9

I know that enabling setuid on scripts has security issues and so is inactive by default, but expect that it works for executables. I created and executable which shows uid as an output following instructions described in this post: Allow setuid on shell scripts

But it returns same uid (1000) both before and after runningsudo chmod +s ./setuid-test. I think this means that setuid does not have any effects on my executable, why and how to solve?

The source code:

#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv) {
    printf("%d", geteuid());
    return 0;
}

Built and run with

$ gcc -o setuid-test setuid-test.c
$ ./setuid-test
1000
$ sudo chown nobody ./setuid-test; sudo chmod +s ./setuid-test
$ ./setuid-test
1000

When running ls -la, this is what I get:

me@me:~$ ls -la setuid-test
-rwsrwsr-x 1 nobody me 8572 Aug 19 16:39 setuid-test
  • 2
    Is the executable owned by a user other than the one you're running it as? (setuid doesn't mean change to root; it means change to the user that owns the executable.) – cjm Aug 19 '14 at 15:04
  • PHPLearner I think you need to involve a group/user in order to change the SUID of a file – ryekayo Aug 19 '14 at 15:05
  • @cjm me@me:~$ ls -la setuid-test ----returns---- -rwsrwsr-x 1 nobody me 8572 Aug 19 16:39 setuid-test – PHP Learner Aug 19 '14 at 15:09
  • 7
    Your program works as expected on my Ubuntu 14.04 system if it's in my home directory, but not when it's in /tmp, because the parameters used to mount /tmp forbid setuid programs. Where is your program located? – Mark Plotnick Aug 19 '14 at 15:11
  • @MarkPlotnick the file (setuid-test) is located in a sub-folder in home directory. – PHP Learner Aug 20 '14 at 02:38
  • 2
    Type df . in the directory to find the mount point, then mount | grep nameofmountpoint. Is there a nosuid flag listed there? – Mark Plotnick Aug 20 '14 at 10:21
  • @MarkPlotnick mount | grep /home/me returns
    /home/me/.Private on /home/me type ecryptfs (ecryptfs_check_dev_ruid,ecryptfs_cipher=xxx,ecryptfs_key_bytes=16,ecryptfs_unlink_sigs,ecryptfs_sig=0123456789abcdef,ecryptfs_fnek_sig=fedcba9876543210)
    – PHP Learner Aug 20 '14 at 17:41

2 Answers2

10

Most filesystems designed for Unix/Linux can be mounted with a nosuid attribute, which will prevent setuid or setgid binaries located on those filesystems from altering the effective uid or gid of a process. It's often used when mounting "untrusted" filesystems, those that are under the control of a non-administrator.

In your case, the filesystem you're using is type ecryptfs, which according to askubuntu: Error when running binary with root setuid under encrypted home directory enforces nosuid (and nodev) automatically, starting with the versions from a few years ago.

Here is a description of the reason for the change, from https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2012-3409 :

Vincent Danen 2012-07-20 11:25:56 EDT
It was reported that the private ecryptfs mount helper (/sbin/mount.ecryptfs_private), which is setuid-root, could allow an unprivileged local user to mount user-controlled ecryptfs shares on the local system. Because the ecryptfs helper does not mount filesystems with the "nosuid" and "nodev" flags, it would be possible for a user to mount a filesystem containing setuid-root binaries and/or device files that could lead to the escalation of their privileges. This could be done via a USB device, if the user had physical access to the system.
...
Forcing MS_NOSUID and MS_NODEV mount flags was added to version 99 .

Mark Plotnick
  • 25,413
  • 3
  • 64
  • 82
  • If the system allowed a user to mount a file-system that allows setuid, then it would be trivial to become root. 1) create an executable 2) elsewhere chown root, chmod +s 3) mount it 4) run executable – ctrl-alt-delor Jul 15 '16 at 08:23
2

SetUID bit on executable allows to run executable at file owner (not superuser). To be able to run executable as root, execute:

sudo chown 0:0 ./setuid-test
phemmer
  • 71,831
hon
  • 179
  • Sure, but that's not the issue. It's possible to have a program that's setuid to a user other than root. In the scenario in the question, setuid-test should display nobody's UID. – Gilles 'SO- stop being evil' Aug 19 '14 at 22:57
  • @Gilles You are right. I expect that setuid-test displays nobody, not root – PHP Learner Aug 20 '14 at 02:40
  • "SetUID bit on executable allows to run executable at file owner" and my file owner is nobody, thus I expect 65534 in return, but I see 1000 whoever be the owner! – PHP Learner Aug 20 '14 at 02:52
  • 2
    Check the mount options of the filesystem on which your test program runs. If it is mounted with nosuid, then your program can't possibly work. – countermode Aug 20 '14 at 07:46
  • 1
    @countermode @MarkPlotnick mount | grep /home/me returns
    /home/me/.Private on /home/me type ecryptfs (ecryptfs_check_dev_ruid,ecryptfs_cipher=xxx,ecryptfs_key_bytes=16,ecryptfs_unlink_sigs,ecryptfs_sig=0123456789abcdef,ecryptfs_fnek_sig=fedcba9876543210)
    – PHP Learner Aug 20 '14 at 17:43