| Summary: | cpio doesn't preserve file permissions in some cases | ||
|---|---|---|---|
| Product: | Busybox | Reporter: | Daniel <leva> |
| Component: | Other | Assignee: | unassigned |
| Status: | RESOLVED FIXED | ||
| Severity: | minor | CC: | busybox-cvs |
| Priority: | P5 | ||
| Version: | 1.16.x | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Other | ||
| Host: | Target: | ||
| Build: | |||
When a file has a symlink pointing to it, and one specifies the symlink's path later than the file's on compression, then on extraction, the file's permissions lose the setgid/setuid bits. $ touch file # create a file $ chmod 6755 file # set the suid/sgid bit $ ln -sf file link # make a symlink to the file $ ls -la file link -rwsr-sr-x 1 daniell users 0 Jun 11 13:55:42 2010 file* lrwxrwxrwx 1 daniell users 4 Jun 11 13:55:49 2010 link@ -> file $ find file link |busybox cpio -ovHnewc > pack.cpio # package them $ rm -f file link # remove and ... $ busybox cpio -dimvu < pack.cpio # ... unpack the files $ ls -la file link # see what happened -rwxr-xr-x 1 daniell users 0 Jun 11 13:55:42 2010 file* lrwxrwxrwx 1 daniell users 4 Jun 11 13:55:49 2010 link@ -> file The setuid/setgid bits didn't get restored. It seems like the situation where one changes the mode bits prior to changing the owner/group on a file: $ touch file $ chmod 6755 file ; ls -l file -rwsr-sr-x 1 daniell daniell 0 2010-06-11 14.01.46 file* $ chown ^C $ sudo chown root:daemon file ; ls -l file -rwxr-xr-x 1 root daemon 0 2010-06-11 14.01.46 file* I couldn't find the corresponding cpio(1) code in the busybox source (although I must admit I didn't try very hard), but I also noticed another bug, which is kind of the same in sed(1): It changes the modes before the owners when editing files in place, so the setuid/setgid bits are also gets lost. --- busybox-1.16.1/editors/sed.c.orig 2010-03-28 19:43:35.000000000 +0200 +++ busybox-1.16.1/editors/sed.c 2010-06-11 14:04:42.253430792 +0200 @@ -1342,8 +1342,8 @@ /* Set permissions/owner of output file */ fstat(fileno(file), &statbuf); - fchmod(nonstdoutfd, statbuf.st_mode); fchown(nonstdoutfd, statbuf.st_uid, statbuf.st_gid); + fchmod(nonstdoutfd, statbuf.st_mode); add_input_file(file); process_files(); fclose(G.nonstdout);