diff options
author | kientzle <kientzle@FreeBSD.org> | 2007-08-12 17:35:05 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2007-08-12 17:35:05 +0000 |
commit | 43d47bd7967cb26165dd1d88bdebf43509c28c4c (patch) | |
tree | d5a96c0cddfcd1aa3c76158dd7375f6b3383d739 /lib/libarchive/archive_write_disk.c | |
parent | f7582f9f8ea38f6cc713efc491bf2806b6649800 (diff) | |
download | FreeBSD-src-43d47bd7967cb26165dd1d88bdebf43509c28c4c.zip FreeBSD-src-43d47bd7967cb26165dd1d88bdebf43509c28c4c.tar.gz |
Make suid/sgid restore be "opportunistic" if
owner restore is not requested. If you ask
for permissions to be restored but not owner,
you will now get no error if suid/sgid bits
cannot be set. (It's a security hole to restore
suid/sgid bits if the owner/group aren't restored.)
This fixes an obscure problem where a simple
"tar -xf" with no other options will sometimes
fail gratuitously because of suid/sgid bits.
This is causing occasional problems for people
using bsdtar as a drop-in replacement for
"that other tar program." ;-)
Note: If you do ask for owner restore, then suid/sgid
restore failures still issue an error. This
only suppresses the error in the case where an
suid/sgid bit restore fails because of an owner
mismatch and owner restore was not requested.
Approved by: re (bmah)
MFC after: 7 days
Diffstat (limited to 'lib/libarchive/archive_write_disk.c')
-rw-r--r-- | lib/libarchive/archive_write_disk.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/lib/libarchive/archive_write_disk.c b/lib/libarchive/archive_write_disk.c index 158f757..f5fb3aa 100644 --- a/lib/libarchive/archive_write_disk.c +++ b/lib/libarchive/archive_write_disk.c @@ -1541,15 +1541,28 @@ set_mode(struct archive_write_disk *a, int mode) } if (a->pst->st_gid != a->gid) { mode &= ~ S_ISGID; - archive_set_error(&a->archive, -1, "Can't restore SGID bit"); - r = ARCHIVE_WARN; + if (a->flags & ARCHIVE_EXTRACT_OWNER) { + /* + * This is only an error if you + * requested owner restore. If you + * didn't, we'll try to restore + * sgid/suid, but won't consider it a + * problem if we can't. + */ + archive_set_error(&a->archive, -1, + "Can't restore SGID bit"); + r = ARCHIVE_WARN; + } } /* While we're here, double-check the UID. */ if (a->pst->st_uid != a->uid && (a->todo & TODO_SUID)) { mode &= ~ S_ISUID; - archive_set_error(&a->archive, -1, "Can't restore SUID bit"); - r = ARCHIVE_WARN; + if (a->flags & ARCHIVE_EXTRACT_OWNER) { + archive_set_error(&a->archive, -1, + "Can't restore SUID bit"); + r = ARCHIVE_WARN; + } } a->todo &= ~TODO_SGID_CHECK; a->todo &= ~TODO_SUID_CHECK; @@ -1561,8 +1574,11 @@ set_mode(struct archive_write_disk *a, int mode) */ if (a->user_uid != a->uid) { mode &= ~ S_ISUID; - archive_set_error(&a->archive, -1, "Can't make file SUID"); - r = ARCHIVE_WARN; + if (a->flags & ARCHIVE_EXTRACT_OWNER) { + archive_set_error(&a->archive, -1, + "Can't make file SUID"); + r = ARCHIVE_WARN; + } } a->todo &= ~TODO_SUID_CHECK; } |