2016-02-16 1:22 GMT+03:00 Philip Guenther <[email protected]>:
> On Sun, 14 Feb 2016, Philip Guenther wrote:
>> On Sun, 14 Feb 2016, Nicolas Bedos wrote:
> ...
>> > >Fix:
>> >     I did some digging and it seems pax gets stuck in a loop after
>> >     calling node_creat (file_subs.c) to create /tmp/foo/bar:
>> ...
>> >     The first argument of chk_path seems to end with '/' because of the
>> >     cpio format. I could not reproduce the problem with the ustar
>> >     format. I did not look any further since I think it is chk_path
>> >     which is at fault here.
>>
>> It doesn't occur when reading ustar format input because a filename with a
>> trailing slash is already specially handled there to provide compat with
>> the old tar format where directories are stored with a trailing slash.
>
> ...and since pax's tar format code only trims a single trailing slash, it
> will loop even in that case if you add more than one trailing slash.
>
> Indeed, if you add more than one trailing slash in general then it'll
> still hang despite your patch: to fix it the code needs to be able to
> detect when its reached an arbitrary number of trailing slashes.
>
> So, I think a diff like this is in order.  This also lets it skip extra
> slashes in the middle of the path and avoid the checks that would be
> duplicated.
>
> Look good to everyone?
>
>
> --- file_subs.c 19 Mar 2015 05:14:24 -0000      1.47
> +++ file_subs.c 15 Feb 2016 09:35:57 -0000
> @@ -597,6 +597,7 @@ int
>  chk_path(char *name, uid_t st_uid, gid_t st_gid)
>  {
>         char *spt = name;
> +       char *next;
>         struct stat sb;
>         int retval = -1;
>
> @@ -613,6 +614,17 @@ chk_path(char *name, uid_t st_uid, gid_t

Hello, Philip.

I think we should change "if" to "while" in this function, too...
After that, okay zhuk@.

--
WBR,
  Vadim Zhukov


Index: file_subs.c
===================================================================
RCS file: /cvs/src/bin/pax/file_subs.c,v
retrieving revision 1.47
diff -u -p -r1.47 file_subs.c
--- file_subs.c 19 Mar 2015 05:14:24 -0000      1.47
+++ file_subs.c 15 Feb 2016 23:24:40 -0000
@@ -597,13 +597,14 @@ int
 chk_path(char *name, uid_t st_uid, gid_t st_gid)
 {
        char *spt = name;
+       char *next;
        struct stat sb;
        int retval = -1;
 
        /*
         * watch out for paths with nodes stored directly in / (e.g. /bozo)
         */
-       if (*spt == '/')
+       while (*spt == '/')
                ++spt;
 
        for (;;) {
@@ -613,6 +614,17 @@ chk_path(char *name, uid_t st_uid, gid_t
                spt = strchr(spt, '/');
                if (spt == NULL)
                        break;
+
+               /*
+                * skip over duplicate slashes; stop if there're only
+                * trailing slashes left
+                */
+               next = spt + 1;
+               while (*next == '/')
+                       next++;
+               if (*next == '\0')
+                       break;
+
                *spt = '\0';
 
                /*
@@ -625,7 +637,8 @@ chk_path(char *name, uid_t st_uid, gid_t
                 * required (do an access()).
                 */
                if (lstat(name, &sb) == 0) {
-                       *(spt++) = '/';
+                       *spt = '/';
+                       spt = next;
                        continue;
                }
 
@@ -659,7 +672,8 @@ chk_path(char *name, uid_t st_uid, gid_t
                        set_pmode(name, ((sb.st_mode & FILEBITS) | S_IRWXU));
                        add_dir(name, &sb, 1);
                }
-               *(spt++) = '/';
+               *spt = '/';
+               spt = next;
                continue;
        }
        return(retval);

Reply via email to