Re: Bug#645346: pax: FTBFS on hurd-i386
reopen 645346
thanks
On Mon, 2011-10-24 at 20:21 +0200, Guillem Jover wrote:
> Hi!
>
> On Sat, 2011-10-15 at 15:51:11 +0200, Svante Signell wrote:
> > On Sat, 2011-10-15 at 01:20 +0200, Guillem Jover wrote:
> > > After considering this, I think it would be a better option and way more
> > > portable to use realpath(path, NULL) when _POSIX_VERSION >= 200809L.
> >
> > Attached is an updated patch, taking Guillems comments into
> > consideration. We are looking forward to se it applied in the next
> > Debian release of pax (and in upstream in due time).
Attached is another updated patch for pax, taking Guillems further
comments into consideration, increasing safety and portability.
Sorry to have to reopen this bug report. Apply the new patch whenever is
appropriate for you.
diff -ur pax-20090728/file_subs.c pax-20090728.modified/file_subs.c
--- pax-20090728/file_subs.c 2009-07-28 17:38:28.000000000 +0000
+++ pax-20090728.modified/file_subs.c 2011-10-31 17:39:17.000000000 +0000
@@ -351,7 +351,7 @@
int pass = 0;
mode_t file_mode;
struct stat sb;
- char target[MAXPATHLEN];
+ char *target = NULL;
char *nm = arcn->name;
int len;
@@ -374,8 +374,15 @@
if (strcmp(NM_TAR, argv0) == 0 && Lflag) {
while (lstat(nm, &sb) == 0 &&
S_ISLNK(sb.st_mode)) {
+ target = malloc(sb.st_size + 1);
+ if (target == NULL) {
+ oerrno = ENOMEM;
+ syswarn(1, oerrno,
+ "Insufficient memory");
+ return(-1);
+ }
len = readlink(nm, target,
- sizeof target - 1);
+ sb.st_size + 1);
if (len == -1) {
syswarn(0, errno,
"cannot follow symlink %s in chain for %s",
@@ -383,6 +390,14 @@
res = -1;
goto badlink;
}
+ if (len > sb.st_size) {
+ syswarn(0, errno,
+ "symlink %s increased in size between lstat() and readlink() for %s",
+ nm, arcn->name);
+
+ res = -1;
+ goto badlink;
+ }
target[len] = '\0';
nm = target;
}
@@ -411,6 +426,7 @@
paxwarn(0,
"%s skipped. Sockets cannot be copied or extracted",
nm);
+ free(target);
return(-1);
case PAX_SLK:
res = symlink(arcn->ln_name, nm);
@@ -425,6 +441,7 @@
*/
paxwarn(0, "%s has an unknown file type, skipping",
nm);
+ free(target);
return(-1);
}
@@ -440,14 +457,17 @@
* we failed to make the node
*/
oerrno = errno;
- if ((ign = unlnk_exist(nm, arcn->type)) < 0)
+ if ((ign = unlnk_exist(nm, arcn->type)) < 0) {
+ free(target);
return(-1);
+ }
if (++pass <= 1)
continue;
if (nodirs || chk_path(nm,arcn->sb.st_uid,arcn->sb.st_gid) < 0) {
syswarn(1, oerrno, "Could not create: %s", nm);
+ free(target);
return(-1);
}
}
@@ -465,8 +485,10 @@
/*
* symlinks are done now.
*/
- if (arcn->type == PAX_SLK)
+ if (arcn->type == PAX_SLK) {
+ free(target);
return(0);
+ }
/*
* IMPORTANT SECURITY NOTE:
@@ -517,6 +539,7 @@
if (patime || pmtime)
set_ftime(nm, arcn->sb.st_mtime, arcn->sb.st_atime, 0);
+ free(target);
return(0);
}
diff -ur pax-20090728/tables.c pax-20090728.modified/tables.c
--- pax-20090728/tables.c 2009-07-28 17:38:28.000000000 +0000
+++ pax-20090728.modified/tables.c 2011-10-31 17:17:26.000000000 +0000
@@ -55,6 +55,7 @@
#include "pax.h"
#include "tables.h"
#include "extern.h"
+#include <unistd.h>
/*
* Routines for controlling the contents of all the different databases pax
@@ -1126,13 +1127,21 @@
add_dir(char *name, struct stat *psb, int frc_mode)
{
DIRDATA *dblk;
+#if (_POSIX_VERSION >= 200809L)
+ char *rp = NULL;
+#else
char realname[MAXPATHLEN], *rp;
+#endif
if (dirp == NULL)
return;
if (havechd && *name != '/') {
+#if (_POSIX_VERSION >= 200809L)
+ if ((rp = realpath(name, NULL)) == NULL) {
+#else
if ((rp = realpath(name, realname)) == NULL) {
+#endif
paxwarn(1, "Cannot canonicalize %s", name);
return;
}
@@ -1143,6 +1152,9 @@
if (dblk == NULL) {
paxwarn(1, "Unable to store mode and times for created"
" directory: %s", name);
+#if (_POSIX_VERSION >= 200809L)
+ free(rp);
+#endif
return;
}
dirp = dblk;
@@ -1152,6 +1164,9 @@
if ((dblk->name = strdup(name)) == NULL) {
paxwarn(1, "Unable to store mode and times for created"
" directory: %s", name);
+#if (_POSIX_VERSION >= 200809L)
+ free(rp);
+#endif
return;
}
dblk->mode = psb->st_mode & 0xffff;
@@ -1159,6 +1174,9 @@
dblk->atime = psb->st_atime;
dblk->frc_mode = frc_mode;
++dircnt;
+#if (_POSIX_VERSION >= 200809L)
+ free(rp);
+#endif
}
/*
Reply to: