#1073591 apt-get install failed with error "Could not create temporary file for ..._Packages - mkstemp (36: File name too long)"

Package:
apt
Source:
apt
Description:
commandline package manager
Submitter:
Changqing Li
Date:
2024-06-19 01:21:05 UTC
Severity:
normal
#1073591#5
Date:
2024-06-18 03:21:06 UTC
From:
To:
Package: apt

Version: 2.6.1

When I run "apt-get install with a long path",  the following error is
reported:
"Could not create temporary file for ...long_path..._Packages - mkstemp
(36: File name too long)"

How about fix with the following patch?

 From 918295aa1320718d342116f76c98d2289d377800 Mon Sep 17 00:00:00 2001
From: Changqing Li <changqing.li@windriver.com>
Date: Tue, 18 Jun 2024 10:32:55 +0800
Subject: [PATCH] strutl.cc: the filename can't be longer than 255

The URItoFileName translates the path into the filename, but the
filename can't be longer than 255 according to
/usr/include/linux/limits.h.

Truncate it when it is longer than 240 (leave some spaces for
".Packages" and "._Release" suffix)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Changqing Li <changqing.li@windriver.com>
---
  apt-pkg/contrib/strutl.cc | 7 ++++++-
  1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc
index 67100f1..5076b35 100644
--- a/apt-pkg/contrib/strutl.cc
+++ b/apt-pkg/contrib/strutl.cc
@@ -565,7 +565,12 @@ string URItoFileName(const string &URI)
     // "\x00-\x20{}|\\\\^\\[\\]<>\"\x7F-\xFF";
     string NewURI = QuoteString(U,"\\|{}[]<>\"^~_=!@#$%^&*");
     replace(NewURI.begin(),NewURI.end(),'/','_');
-   return NewURI;
+
+   // Truncate from the head when it is longer than 240
+   if(NewURI.length() > 240)
+       return NewURI.substr(NewURI.length() - 240, NewURI.length() - 1);
+   else
+       return NewURI;
  }
                                      /*}}}*/
  // Base64Encode - Base64 Encoding routine for short strings  /*{{{*/

#1073591#10
Date:
2024-06-18 10:50:47 UTC
From:
To:
Shouldn't that already be a problem with 'update'? Or are you talking
about 'apt install /very/very/long/path/…' (or a --with-source variant)?
[…]
deb http://example.org/very/very/long/path foo main
deb http://example.org/very/very/long/path bar main
that would roughly translate to e.g.:
example.org_very_very_long_path_dists_foo_main_binary-amd64_Packages
example.org_very_very_long_path_dists_foo_main_binary-i386_Packages
example.org_very_very_long_path_dists_bar_main_binary-amd64_Packages
example.org_very_very_long_path_dists_bar_main_binary-i386_Packages

So, you can't just arbitrarily cut from the end as that potentially maps
multiple URIs to the same filename (and while I am not sure if that
method is UTF-8 safe, truncating is definitively not).

The suffix part in your description is also misleading. The "suffixes"
you mention tend to be already part of the URI (and hence the filename),
so you would cut them. "Suffixes" that might be attached tend to be on
the short side like if a file is compressed (although nobody said that
a compression algorithm needs to use e.g. 'xz', it could also be
'xtremely_zmall'. The longer ones like .diff/Index (or the individual
patches) tend to use this method (and would again be subject to
truncating) if I remember right (haven't checked).


Julian entertained the idea of storing files by hash in lists/ – that
would at least limit the problem to files we don't have hashes for,
as in the (In|)Release(.gpg|) file(s) – and of course every repo we
don't have hashes for.

For these we could go with a (directory)index file that tells us about
the mapping. Such an index might even be better than our current
guessing what files could exist and checking for their existence in many
compression formats, but that would probably amount to a micro-micro
optimisation…

Anyway, drawback is of course that changing filenames means everything
that access the files directly is broken. We told everyone who wanted to
listen that they can use 'apt-get indextargets' to access filenames, but
I doubt everyone wanted to and some might even have "good" reason like
not doing shell (heck, I do sometimes. Our tests do. …)

On a sidenote, NAME_MAX seems as constant as PATH_MAX, as in on some
filesystems it is larger (or potentially smaller), but [surprisingly]
more in effect than PATH_MAX. In any case, no magic numbers please.


Oh, and congratulations! I suppose that problem exists since the
beginning (1997) and I haven't seen it being mentioned while I am around
(~15 years), so that makes this some very old and esoteric problem.


Best regards

David Kalnischkies

#1073591#15
Date:
2024-06-19 00:51:34 UTC
From:
To:
You are right. Sorry, I wrote the wrong cmd.  it is "apt-get update" 
failed.  Is it possible for me to change the subject?

Let me describe more detail:

I am working on yocto project,  and apt-get update is executed during
create rootfs.

and the source is like this:

deb [trusted=yes]
file:/buildarea/cli/yocto/builds/yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto/tmp/work/qemux86_64-poky-linux/core-image-minimal/1.0/oe-rootfs-repo/qemux86_64/
./
deb [trusted=yes]
file:/buildarea/cli/yocto/builds/yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto/tmp/work/qemux86_64-poky-linux/core-image-minimal/1.0/oe-rootfs-repo/core2-64/
./
deb [trusted=yes]
file:/buildarea/cli/yocto/builds/yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto/tmp/work/qemux86_64-poky-linux/core-image-minimal/1.0/oe-rootfs-repo/all/
./


And before apt-get update,  "apt-ftparchive packages . > Packages, 
apt-ftparchive release . >> Release" is executed to generate index file
under above source path.

Then apt-get update failed with error like:

E: Failed to fetch
store:/buildarea/cli/yocto/builds/yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto/tmp/work/qemux86_64-poky-linux/core-image-minimal/1.0/oe-rootfs-repo/all/./Packages
Could not create temporary file for
/buildarea/cli/yocto/builds/yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto_yocto/tmp/work/qemux86_64-poky-linux/core-image-minimal/1.0/apt/lists/partial/_buildarea_cli_yocto_builds_yocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto%5fyocto_tmp_work_qemux86%5f64-poky-linux_core-image-minimal_1.0_oe-rootfs-repo_all_._Packages
- mkstemp (36: File name too long)


The suggest patch may not proper, I just want to say that the original
idea is cut the first few characters for the temp file.

Eg:

example.org_very_very_long_path_dists_foo_main_binary-amd64_Packages   ->ry_very_long_path_dists_foo_main_binary-amd64_Packages


Thanks
Changqing