8

I suppose an executable file with SetUID bit set should be running as its owner but I cannot really reproduce it. I tried the following.

$ cat prepare.sh
cp /bin/bash .
chown root.root bash
chmod 4770 bash # Verified
$ sudo sh prepare.sh
$ ./bash
$ id -u
1000
$ exit
$
$ cat test.c
#include<stdio.h>
#include<unistd.h>
int main(){
 printf("%d,%d\n", getuid(), geteuid());
 return 0;
}
$ gcc -o test test.c
$ chmod 4770 test # Verified
$ sudo chown root.root test
$ ./test
1000,1000
$ # Why???

However

$ su
# ./bash
# id -u
0
# ./test
0,0
# exit
# exit
$

Note: The mount point has no nosuid nor noexec set.
Can anyone explain why it's failing to work on Ubuntu 16.04 LTS?

asked Apr 18, 2017 at 4:58
3
  • 3
    Possible duplicate of Allow setuid on shell scripts Commented Apr 18, 2017 at 6:35
  • 3
    @Kusalananda it is not a script. Commented Apr 18, 2017 at 6:39
  • 4
    The script is a bit confusing, but it's just a red herring. I suppose it's there to save two uses of sudo? There's a bug or a typo in it, though, the chmod is missing a file name. Commented Apr 18, 2017 at 8:17

3 Answers 3

15

For the compiled executable, from man 2 chown:

When the owner or group of an executable file are changed by an
unprivileged user the S_ISUID and S_ISGID mode bits are cleared. POSIX
does not specify whether this also should happen when root does the
chown(); the Linux behavior depends on the kernel version.

Reversing the chown and chmod order works for me:

$ sudo chmod 4770 foo
$ sudo chown root:root foo
$ stat foo
 File: 'foo'
 Size: 8712 Blocks: 24 IO Block: 4096 regular file
Device: 801h/2049d Inode: 967977 Links: 1
Access: (0770/-rwxrwx---) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2017年04月18日 15:15:15.074425000 +0900
Modify: 2017年04月18日 15:15:15.074425000 +0900
Change: 2017年04月18日 15:15:33.683725000 +0900
 Birth: -
$ sudo chmod 4777 foo
$ ./foo
1000,0
answered Apr 18, 2017 at 6:21
0
15

In your first case, it's Bash that doesn't like being run as setuid.

If Bash is started with the effective user (group) id not equal to the real user (group) id,..., and the effective user id is set to the real user id.

See: Bash's manual on startup files, also Setuid bit seems to have no effect on bash .

In the second case, it's the order of chmod and chown that matters, as muru already answered. Changing the owner resets the setuid bit.

answered Apr 18, 2017 at 8:11
4
  • Oh, I didn't notice the OP was using the script setup a setuid bash. Commented Apr 18, 2017 at 8:18
  • Is it possible to run shell scripts with the setuid bit via other shells? Or are shell scripts off the table entirely if I need to use setuid? Commented Apr 9, 2022 at 0:21
  • @maples, having a script setuid is different from having the shell binary itself setuid. The latter is what they were doing here, and that's what Bash is extra picky about, other shells I tried didn't care. But setuid scripts also have issues, see Allow setuid on shell scripts and the links in the answers. The answers there also say that most unixes ignore the setuid bit on scripts to begin with, so it doesn't matter what the shell does at that point. Commented Apr 9, 2022 at 9:40
  • 1
    @maples, anyway, if you need to run a script with elevated privileges, the simple and ok-ish way would be to have your users run it through sudo. It's better than plain setuid, since sudo knows to do at least some cleanup when changing UIDs, which setuid doesn't really do. Of course, a better way would be to have a privileged background process listen to a unix socket and receive requests through it; that would get rid of all issues with stuff getting inherited from a parent process to a child. Commented Apr 9, 2022 at 9:43
6

It could also be that the filesystem containing the test executable was mounted with the nosuid option; I have heard that newer distributions will do this by default for /tmp, and there are good arguments for applying it to /home as well. nosuid causes the kernel to ignore the setuid and setgid bits on all executables within the filesystem. (The unrelated thing that happens when you make a directory setgid is unaffected.)

answered Apr 18, 2017 at 15:13

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.