[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: