diff options
-rw-r--r-- | setfacl/setfacl.c | 8 | ||||
-rw-r--r-- | test/root/restore.test | 23 |
2 files changed, 30 insertions, 1 deletions
diff --git a/setfacl/setfacl.c b/setfacl/setfacl.c index 091b9cc..56b0aa4 100644 --- a/setfacl/setfacl.c +++ b/setfacl/setfacl.c @@ -128,6 +128,7 @@ restore( struct do_set_args args; int line = 0, backup_line; int error, status = 0; + int chmod_required = 0; memset(&st, 0, sizeof(st)); @@ -206,10 +207,15 @@ restore( strerror(errno)); status = 1; } + + /* chown() clears setuid/setgid so force a chmod if + * S_ISUID/S_ISGID was expected */ + if ((st.st_mode & flags) & (S_ISUID | S_ISGID)) + chmod_required = 1; } mask = S_ISUID | S_ISGID | S_ISVTX; - if ((st.st_mode & mask) != (flags & mask)) { + if (chmod_required || ((st.st_mode & mask) != (flags & mask))) { if (!args.mode) args.mode = st.st_mode; args.mode &= (S_IRWXU | S_IRWXG | S_IRWXO); diff --git a/test/root/restore.test b/test/root/restore.test new file mode 100644 index 0000000..6003cd4 --- /dev/null +++ b/test/root/restore.test @@ -0,0 +1,23 @@ +Ensure setuid bit is restored when the owner changes + https://bugzilla.redhat.com/show_bug.cgi?id=467936#c7 + + $ touch passwd + $ chmod 755 passwd + $ chmod u+s passwd + $ getfacl passwd > passwd.acl + $ cat passwd.acl + > # file: passwd + > # owner: root + > # group: root + > # flags: s-- + > user::rwx + > group::r-x + > other::r-x + > + $ chown bin passwd + $ chmod u+s passwd + $ setfacl --restore passwd.acl + $ ls -dl passwd | awk '{print $1 " " $3 " " $4}' + > -rwsr-xr-x root root + + $ rm passwd passwd.acl |