bug-tar
[Top][All Lists]
Advanced

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

tar attempts to drop privileges for remote command but mishandles groups


From: Ondrej Dubaj
Subject: tar attempts to drop privileges for remote command but mishandles groups
Date: Mon, 18 Jan 2021 12:22:07 +0100

When tar executes remote command for remote archive (by default /usr/bin/ssh), it calls sys_reset_uid_gid in rmt_open__ in forked child right before execl. So it seems like the intent in set-uid/set-gid situations is to run the remote command with the privileges of the invoking user, not with the elevated privileges.

The sys_reset_uid_gid is defined in lib/system.h as

# define sys_reset_uid_gid()                                    \
  do {                                                          \
    if (! (setuid (getuid ()) == 0 && setgid (getgid ()) == 0)) \
      abort ();                                                 \
  } while (0)

This code means that supplementary groups are not cleared and saved set-group-ID is not reset.

Affected version: tar-1.32

Steps to Reproduce: 1. Prepare "remote command" to display privileges of the process on standard error output -- create /usr/local/bin/id with content #!/bin/bash -p /usr/bin/id >&2 2. Make it executable: chmod +x /usr/local/bin/id 3. Create test program suid-tar-with-groups.c to be run as set-uid/set-gid which also sets some supplementary groups: #include <sys/types.h> #include <unistd.h> #include <grp.h> #include <stdlib.h> int main(void) { const gid_t list[] = { 992, 993 }; setgroups(2, list); execl("/usr/bin/tar", "tar", "-c", "--rsh-command=/usr/local/bin/id", "-f", "root@localhost:/tmp/out.tar", "/something/somewhere", (char *) NULL); } 4. Build it as root: gcc -o /usr/local/bin/suid-tar-with-groups suid-tar-with-groups.c 5. Make it set-uid/set-gid as root: chmod ug+s /usr/local/bin/suid-tar-with-groups 6. Have a non-privileged account which has no supplemental groups: run id to check: uid=1000(test) gid=1000(test) groups=1000(test) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 7. From this account, execute: /usr/local/bin/suid-tar-with-groups Actual results: uid=1000(test) gid=1000(test) groups=1000(test),992(chrony),993(unbound) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tar: root@localhost\:/tmp/out.tar: Cannot open: Input/output error tar: Error is not recoverable: exiting now Expected results: uid=1000(test) gid=1000(test) groups=1000(test) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tar: root@localhost\:/tmp/out.tar: Cannot open: Input/output error tar: Error is not recoverable: exiting now Additional info: This demonstrates that when tar drops the privileges back to the invoking real uid and real gid to execute the remote command, the process still has the extra supplementary groups of that set-uid process. Based on https://wiki.sei.cmu.edu/confluence/display/c/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges, calling setgroups() before setuid is needed. I tried with plain setgroups(0, NULL); added at the start of sys_reset_uid_gid that the supplementary groups will be purged. Another issue is the order of the setuid() and setgid() -- since sys_reset_uid_gid does setuid first, by the time it runs setgid, the process no longer has permissions to drop the saved set-group-ID. The reproducer above does not demonstrate this second problem specifically, let's just say the order should be reversed.

Regards,

Ondrej Dubaj

reply via email to

[Prev in Thread] Current Thread [Next in Thread]