SUID bit on binary file still yielding “Permission denied” error

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
5
down vote

favorite
1












alice and bob both belong to the staff group.



I've got the following folder:



drwxrwxr-x 2 alice staff 4096 Oct 30 14:45 share



with the following files inside the folder:



-rwsr-xr-x 1 alice alice 8768 Oct 30 14:45 display-foo
-rw------- 1 alice alice 24 Oct 30 14:45 foo.txt


display-foo is a binary file that essentially displays the contents of foo.txt using the cat command.



When alice runs ./display-foo, the binary file executes successfully and the contents of foo.txt are displayed. However, when bob runs ./display-foo, the binary file executes successfully but the contents of the foo.txt are not displayed, yielding the error /bin/cat: /home/alice/share/foo.txt: Permission denied.




From my understanding, setting the setuid bit allows the binary executable to be executed with the privileges of the file's owner (in this case, alice). Why, then, was bob not allowed to view the contents of foo.txt?




ADDENDUM: I have recompiled my binary file with the geteuid() function so that it prints out the effective user ID (EUID). Indeed, when bob executes the binary file, the EUID is that of alice. Yet, permission is denied. Here's a snippet of the source code:



printf("%d", geteuid());
system("/bin/cat /home/alice/share/foo.txt");






share|improve this question






















  • @SatōKatsura Yup, it is a binary file (compiled using gcc from a .c program).
    – JTJM
    Oct 30 '17 at 7:35






  • 4




    Commands run with system() don't inherit the privileged UID. Try fopen() etc. instead.
    – Satō Katsura
    Oct 30 '17 at 7:38










  • Thank you @SatōKatsura , it works like a charm. I'm guessing this is some sort of security feature by Ubuntu.
    – JTJM
    Oct 30 '17 at 8:12






  • 1




    Nope, it's standard UNIX semantics.
    – Satō Katsura
    Oct 30 '17 at 8:13










  • I can't reproduce this (running Debian 9, GCC 6.3.0). The setuid bit seems to be doing its job, even with the system call. Any thoughts?
    – igal
    Nov 4 '17 at 16:45














up vote
5
down vote

favorite
1












alice and bob both belong to the staff group.



I've got the following folder:



drwxrwxr-x 2 alice staff 4096 Oct 30 14:45 share



with the following files inside the folder:



-rwsr-xr-x 1 alice alice 8768 Oct 30 14:45 display-foo
-rw------- 1 alice alice 24 Oct 30 14:45 foo.txt


display-foo is a binary file that essentially displays the contents of foo.txt using the cat command.



When alice runs ./display-foo, the binary file executes successfully and the contents of foo.txt are displayed. However, when bob runs ./display-foo, the binary file executes successfully but the contents of the foo.txt are not displayed, yielding the error /bin/cat: /home/alice/share/foo.txt: Permission denied.




From my understanding, setting the setuid bit allows the binary executable to be executed with the privileges of the file's owner (in this case, alice). Why, then, was bob not allowed to view the contents of foo.txt?




ADDENDUM: I have recompiled my binary file with the geteuid() function so that it prints out the effective user ID (EUID). Indeed, when bob executes the binary file, the EUID is that of alice. Yet, permission is denied. Here's a snippet of the source code:



printf("%d", geteuid());
system("/bin/cat /home/alice/share/foo.txt");






share|improve this question






















  • @SatōKatsura Yup, it is a binary file (compiled using gcc from a .c program).
    – JTJM
    Oct 30 '17 at 7:35






  • 4




    Commands run with system() don't inherit the privileged UID. Try fopen() etc. instead.
    – Satō Katsura
    Oct 30 '17 at 7:38










  • Thank you @SatōKatsura , it works like a charm. I'm guessing this is some sort of security feature by Ubuntu.
    – JTJM
    Oct 30 '17 at 8:12






  • 1




    Nope, it's standard UNIX semantics.
    – Satō Katsura
    Oct 30 '17 at 8:13










  • I can't reproduce this (running Debian 9, GCC 6.3.0). The setuid bit seems to be doing its job, even with the system call. Any thoughts?
    – igal
    Nov 4 '17 at 16:45












up vote
5
down vote

favorite
1









up vote
5
down vote

favorite
1






1





alice and bob both belong to the staff group.



I've got the following folder:



drwxrwxr-x 2 alice staff 4096 Oct 30 14:45 share



with the following files inside the folder:



-rwsr-xr-x 1 alice alice 8768 Oct 30 14:45 display-foo
-rw------- 1 alice alice 24 Oct 30 14:45 foo.txt


display-foo is a binary file that essentially displays the contents of foo.txt using the cat command.



When alice runs ./display-foo, the binary file executes successfully and the contents of foo.txt are displayed. However, when bob runs ./display-foo, the binary file executes successfully but the contents of the foo.txt are not displayed, yielding the error /bin/cat: /home/alice/share/foo.txt: Permission denied.




From my understanding, setting the setuid bit allows the binary executable to be executed with the privileges of the file's owner (in this case, alice). Why, then, was bob not allowed to view the contents of foo.txt?




ADDENDUM: I have recompiled my binary file with the geteuid() function so that it prints out the effective user ID (EUID). Indeed, when bob executes the binary file, the EUID is that of alice. Yet, permission is denied. Here's a snippet of the source code:



printf("%d", geteuid());
system("/bin/cat /home/alice/share/foo.txt");






share|improve this question














alice and bob both belong to the staff group.



I've got the following folder:



drwxrwxr-x 2 alice staff 4096 Oct 30 14:45 share



with the following files inside the folder:



-rwsr-xr-x 1 alice alice 8768 Oct 30 14:45 display-foo
-rw------- 1 alice alice 24 Oct 30 14:45 foo.txt


display-foo is a binary file that essentially displays the contents of foo.txt using the cat command.



When alice runs ./display-foo, the binary file executes successfully and the contents of foo.txt are displayed. However, when bob runs ./display-foo, the binary file executes successfully but the contents of the foo.txt are not displayed, yielding the error /bin/cat: /home/alice/share/foo.txt: Permission denied.




From my understanding, setting the setuid bit allows the binary executable to be executed with the privileges of the file's owner (in this case, alice). Why, then, was bob not allowed to view the contents of foo.txt?




ADDENDUM: I have recompiled my binary file with the geteuid() function so that it prints out the effective user ID (EUID). Indeed, when bob executes the binary file, the EUID is that of alice. Yet, permission is denied. Here's a snippet of the source code:



printf("%d", geteuid());
system("/bin/cat /home/alice/share/foo.txt");








share|improve this question













share|improve this question




share|improve this question








edited Oct 30 '17 at 7:33

























asked Oct 30 '17 at 7:06









JTJM

263




263











  • @SatōKatsura Yup, it is a binary file (compiled using gcc from a .c program).
    – JTJM
    Oct 30 '17 at 7:35






  • 4




    Commands run with system() don't inherit the privileged UID. Try fopen() etc. instead.
    – Satō Katsura
    Oct 30 '17 at 7:38










  • Thank you @SatōKatsura , it works like a charm. I'm guessing this is some sort of security feature by Ubuntu.
    – JTJM
    Oct 30 '17 at 8:12






  • 1




    Nope, it's standard UNIX semantics.
    – Satō Katsura
    Oct 30 '17 at 8:13










  • I can't reproduce this (running Debian 9, GCC 6.3.0). The setuid bit seems to be doing its job, even with the system call. Any thoughts?
    – igal
    Nov 4 '17 at 16:45
















  • @SatōKatsura Yup, it is a binary file (compiled using gcc from a .c program).
    – JTJM
    Oct 30 '17 at 7:35






  • 4




    Commands run with system() don't inherit the privileged UID. Try fopen() etc. instead.
    – Satō Katsura
    Oct 30 '17 at 7:38










  • Thank you @SatōKatsura , it works like a charm. I'm guessing this is some sort of security feature by Ubuntu.
    – JTJM
    Oct 30 '17 at 8:12






  • 1




    Nope, it's standard UNIX semantics.
    – Satō Katsura
    Oct 30 '17 at 8:13










  • I can't reproduce this (running Debian 9, GCC 6.3.0). The setuid bit seems to be doing its job, even with the system call. Any thoughts?
    – igal
    Nov 4 '17 at 16:45















@SatōKatsura Yup, it is a binary file (compiled using gcc from a .c program).
– JTJM
Oct 30 '17 at 7:35




@SatōKatsura Yup, it is a binary file (compiled using gcc from a .c program).
– JTJM
Oct 30 '17 at 7:35




4




4




Commands run with system() don't inherit the privileged UID. Try fopen() etc. instead.
– Satō Katsura
Oct 30 '17 at 7:38




Commands run with system() don't inherit the privileged UID. Try fopen() etc. instead.
– Satō Katsura
Oct 30 '17 at 7:38












Thank you @SatōKatsura , it works like a charm. I'm guessing this is some sort of security feature by Ubuntu.
– JTJM
Oct 30 '17 at 8:12




Thank you @SatōKatsura , it works like a charm. I'm guessing this is some sort of security feature by Ubuntu.
– JTJM
Oct 30 '17 at 8:12




1




1




Nope, it's standard UNIX semantics.
– Satō Katsura
Oct 30 '17 at 8:13




Nope, it's standard UNIX semantics.
– Satō Katsura
Oct 30 '17 at 8:13












I can't reproduce this (running Debian 9, GCC 6.3.0). The setuid bit seems to be doing its job, even with the system call. Any thoughts?
– igal
Nov 4 '17 at 16:45




I can't reproduce this (running Debian 9, GCC 6.3.0). The setuid bit seems to be doing its job, even with the system call. Any thoughts?
– igal
Nov 4 '17 at 16:45










2 Answers
2






active

oldest

votes

















up vote
1
down vote













I read through the manual page for the system function and came across the following passage which offers an explanation:




Do not use system() from a program with set-user-ID or set-group-ID
privileges, because strange values for some environment variables
might be used to subvert system integrity. Use the exec(3) family of
functions instead, but not execlp(3) or execvp(3). system() will
not, in fact, work properly from programs with set-user-ID or set-
group-ID privileges on systems on which /bin/sh is bash version 2,
since bash 2 drops privileges on startup. (Debian uses a modified
bash which does not do this when invoked as sh.)



Here are some other StackExchange posts that I read through on my way to that passage:



  • SETUID Permission Denied

  • Why do I need setuid(0) within a setuid-root C program that calls an administrative program with system()?

  • Debugging a setuid program / “Permission denied” with setuid

  • Unix suid bit problem

  • how to set the setuid bit in a program of a non-root user?

  • linux setuid does not work

For posterity, and because the given example might be useful for diagnosing this or similar issues in other contexts, I've kept my original below.




Is it possible that you're running into a bug? I was unable to reproduce your problem in a Docker container running Debian 9 with gcc 6.3. Here is how I went about trying to recreate the scenario described in your post.



First create the "alice" and "bob" users and them to the "staff" group:



useradd -m -G staff alice
useradd -m -G staff bob


Next create the file and set its ownership and permissions:



# Create a subdirectory to hold the text file
sudo -u alice mkdir -p /home/alice/share/

# Create the text file
sudo -u alice bash -c 'echo "This is foo.txt" > /home/alice/share/foo.txt'

# Set restrictive permissions on the text file
chmod u=rw,g=,o= /home/alice/share/foo.txt


Let's check the results:



$ ls -l /home/alice/share/foo.txt
-rw------- 1 alice alice 16 Nov 4 15:33 /home/alice/share/foo.txt


Now let's create a version of display-foo which uses the system function:



$ cat <<HEREDOC > /usr/local/src/display-foo.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

int main(int argc, char **argv)

struct passwd *r_pwd = getpwuid(getuid());
printf("Real user: %sn", r_pwd->pw_name);

struct passwd *e_pwd = getpwuid(geteuid());
printf("Effective user: %sn", e_pwd->pw_name);

system("/bin/cat /home/alice/share/foo.txt");

HEREDOC

$ gcc /usr/local/src/display-foo.c -o /usr/local/bin/display-foo


And let's set ownership and permissions on display-foo, including setting the setuid bit:



chown alice:alice /usr/local/bin/display-foo
chmod u=rwx,g=rx,o=rx /usr/local/bin/display-foo
chmod u+s /usr/local/bin/display-foo


Let's also check the result:



$ ls -l /usr/local/bin/display-foo
-rwsr-xr-x 1 alice alice 8640 Nov 4 15:40 /usr/local/bin/display-foo


Now we run the program both as alice and as bob:



$ sudo -u alice display-foo

Real user: alice
Effective user: alice
This is foo.txt

$ sudo -u bob display-foo

Real user: bob
Effective user: alice
This is foo.txt


As you can see, it looks like everything is working as expected.






share|improve this answer


















  • 1




    I've replicated every single step listed above. Same result. Running the binary as alice prints (Real user: alice, Effective user: alice, This is foo.txt). Running the binary as bob prints (Real user: bob, Effective user: alice, /bin/cat: /home/alice/share/foo.txt: Permission denied). In other words, bob had the permission to run the binary, but somehow was unable to execute the system() instruction, as mentioned by Sato. Very very peculiar.
    – JTJM
    Nov 6 '17 at 5:43











  • @JTJM I think I figured it out. See the update to my solution.
    – igal
    Nov 6 '17 at 12:21

















up vote
0
down vote













The foo.txt file is in a share directory in Alice home directory,so Bob can not access the files in Alice home directory because of permissions.
you can create a shared directory in home, and givin both permissions to access this directory.



or, you can create a shared directory with groupowner of staff and set SGID bit with this command:



chmod 2777 sharedDir


when the SGID bit is set on a directory, new files or sub-directories created in the original directory will inherit the group ownership of the directory rather than be based on the user's current default group.



so when Alice create a file here, group ownership of the file will be STAFF and all of the member of this gorup can access these files base on staff group permission.






share|improve this answer






















  • Correct in that bob can't read foo.txt. But ./display-foo is setuid alice, which means it runs with alice's permissions and access rights, and the OP is asking why this program still can't read foo.txt.
    – roaima
    Aug 22 at 14:26











  • @roaima my post has been updated
    – anis
    Aug 26 at 13:31










Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f401351%2fsuid-bit-on-binary-file-still-yielding-permission-denied-error%23new-answer', 'question_page');

);

Post as a guest






























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote













I read through the manual page for the system function and came across the following passage which offers an explanation:




Do not use system() from a program with set-user-ID or set-group-ID
privileges, because strange values for some environment variables
might be used to subvert system integrity. Use the exec(3) family of
functions instead, but not execlp(3) or execvp(3). system() will
not, in fact, work properly from programs with set-user-ID or set-
group-ID privileges on systems on which /bin/sh is bash version 2,
since bash 2 drops privileges on startup. (Debian uses a modified
bash which does not do this when invoked as sh.)



Here are some other StackExchange posts that I read through on my way to that passage:



  • SETUID Permission Denied

  • Why do I need setuid(0) within a setuid-root C program that calls an administrative program with system()?

  • Debugging a setuid program / “Permission denied” with setuid

  • Unix suid bit problem

  • how to set the setuid bit in a program of a non-root user?

  • linux setuid does not work

For posterity, and because the given example might be useful for diagnosing this or similar issues in other contexts, I've kept my original below.




Is it possible that you're running into a bug? I was unable to reproduce your problem in a Docker container running Debian 9 with gcc 6.3. Here is how I went about trying to recreate the scenario described in your post.



First create the "alice" and "bob" users and them to the "staff" group:



useradd -m -G staff alice
useradd -m -G staff bob


Next create the file and set its ownership and permissions:



# Create a subdirectory to hold the text file
sudo -u alice mkdir -p /home/alice/share/

# Create the text file
sudo -u alice bash -c 'echo "This is foo.txt" > /home/alice/share/foo.txt'

# Set restrictive permissions on the text file
chmod u=rw,g=,o= /home/alice/share/foo.txt


Let's check the results:



$ ls -l /home/alice/share/foo.txt
-rw------- 1 alice alice 16 Nov 4 15:33 /home/alice/share/foo.txt


Now let's create a version of display-foo which uses the system function:



$ cat <<HEREDOC > /usr/local/src/display-foo.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

int main(int argc, char **argv)

struct passwd *r_pwd = getpwuid(getuid());
printf("Real user: %sn", r_pwd->pw_name);

struct passwd *e_pwd = getpwuid(geteuid());
printf("Effective user: %sn", e_pwd->pw_name);

system("/bin/cat /home/alice/share/foo.txt");

HEREDOC

$ gcc /usr/local/src/display-foo.c -o /usr/local/bin/display-foo


And let's set ownership and permissions on display-foo, including setting the setuid bit:



chown alice:alice /usr/local/bin/display-foo
chmod u=rwx,g=rx,o=rx /usr/local/bin/display-foo
chmod u+s /usr/local/bin/display-foo


Let's also check the result:



$ ls -l /usr/local/bin/display-foo
-rwsr-xr-x 1 alice alice 8640 Nov 4 15:40 /usr/local/bin/display-foo


Now we run the program both as alice and as bob:



$ sudo -u alice display-foo

Real user: alice
Effective user: alice
This is foo.txt

$ sudo -u bob display-foo

Real user: bob
Effective user: alice
This is foo.txt


As you can see, it looks like everything is working as expected.






share|improve this answer


















  • 1




    I've replicated every single step listed above. Same result. Running the binary as alice prints (Real user: alice, Effective user: alice, This is foo.txt). Running the binary as bob prints (Real user: bob, Effective user: alice, /bin/cat: /home/alice/share/foo.txt: Permission denied). In other words, bob had the permission to run the binary, but somehow was unable to execute the system() instruction, as mentioned by Sato. Very very peculiar.
    – JTJM
    Nov 6 '17 at 5:43











  • @JTJM I think I figured it out. See the update to my solution.
    – igal
    Nov 6 '17 at 12:21














up vote
1
down vote













I read through the manual page for the system function and came across the following passage which offers an explanation:




Do not use system() from a program with set-user-ID or set-group-ID
privileges, because strange values for some environment variables
might be used to subvert system integrity. Use the exec(3) family of
functions instead, but not execlp(3) or execvp(3). system() will
not, in fact, work properly from programs with set-user-ID or set-
group-ID privileges on systems on which /bin/sh is bash version 2,
since bash 2 drops privileges on startup. (Debian uses a modified
bash which does not do this when invoked as sh.)



Here are some other StackExchange posts that I read through on my way to that passage:



  • SETUID Permission Denied

  • Why do I need setuid(0) within a setuid-root C program that calls an administrative program with system()?

  • Debugging a setuid program / “Permission denied” with setuid

  • Unix suid bit problem

  • how to set the setuid bit in a program of a non-root user?

  • linux setuid does not work

For posterity, and because the given example might be useful for diagnosing this or similar issues in other contexts, I've kept my original below.




Is it possible that you're running into a bug? I was unable to reproduce your problem in a Docker container running Debian 9 with gcc 6.3. Here is how I went about trying to recreate the scenario described in your post.



First create the "alice" and "bob" users and them to the "staff" group:



useradd -m -G staff alice
useradd -m -G staff bob


Next create the file and set its ownership and permissions:



# Create a subdirectory to hold the text file
sudo -u alice mkdir -p /home/alice/share/

# Create the text file
sudo -u alice bash -c 'echo "This is foo.txt" > /home/alice/share/foo.txt'

# Set restrictive permissions on the text file
chmod u=rw,g=,o= /home/alice/share/foo.txt


Let's check the results:



$ ls -l /home/alice/share/foo.txt
-rw------- 1 alice alice 16 Nov 4 15:33 /home/alice/share/foo.txt


Now let's create a version of display-foo which uses the system function:



$ cat <<HEREDOC > /usr/local/src/display-foo.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

int main(int argc, char **argv)

struct passwd *r_pwd = getpwuid(getuid());
printf("Real user: %sn", r_pwd->pw_name);

struct passwd *e_pwd = getpwuid(geteuid());
printf("Effective user: %sn", e_pwd->pw_name);

system("/bin/cat /home/alice/share/foo.txt");

HEREDOC

$ gcc /usr/local/src/display-foo.c -o /usr/local/bin/display-foo


And let's set ownership and permissions on display-foo, including setting the setuid bit:



chown alice:alice /usr/local/bin/display-foo
chmod u=rwx,g=rx,o=rx /usr/local/bin/display-foo
chmod u+s /usr/local/bin/display-foo


Let's also check the result:



$ ls -l /usr/local/bin/display-foo
-rwsr-xr-x 1 alice alice 8640 Nov 4 15:40 /usr/local/bin/display-foo


Now we run the program both as alice and as bob:



$ sudo -u alice display-foo

Real user: alice
Effective user: alice
This is foo.txt

$ sudo -u bob display-foo

Real user: bob
Effective user: alice
This is foo.txt


As you can see, it looks like everything is working as expected.






share|improve this answer


















  • 1




    I've replicated every single step listed above. Same result. Running the binary as alice prints (Real user: alice, Effective user: alice, This is foo.txt). Running the binary as bob prints (Real user: bob, Effective user: alice, /bin/cat: /home/alice/share/foo.txt: Permission denied). In other words, bob had the permission to run the binary, but somehow was unable to execute the system() instruction, as mentioned by Sato. Very very peculiar.
    – JTJM
    Nov 6 '17 at 5:43











  • @JTJM I think I figured it out. See the update to my solution.
    – igal
    Nov 6 '17 at 12:21












up vote
1
down vote










up vote
1
down vote









I read through the manual page for the system function and came across the following passage which offers an explanation:




Do not use system() from a program with set-user-ID or set-group-ID
privileges, because strange values for some environment variables
might be used to subvert system integrity. Use the exec(3) family of
functions instead, but not execlp(3) or execvp(3). system() will
not, in fact, work properly from programs with set-user-ID or set-
group-ID privileges on systems on which /bin/sh is bash version 2,
since bash 2 drops privileges on startup. (Debian uses a modified
bash which does not do this when invoked as sh.)



Here are some other StackExchange posts that I read through on my way to that passage:



  • SETUID Permission Denied

  • Why do I need setuid(0) within a setuid-root C program that calls an administrative program with system()?

  • Debugging a setuid program / “Permission denied” with setuid

  • Unix suid bit problem

  • how to set the setuid bit in a program of a non-root user?

  • linux setuid does not work

For posterity, and because the given example might be useful for diagnosing this or similar issues in other contexts, I've kept my original below.




Is it possible that you're running into a bug? I was unable to reproduce your problem in a Docker container running Debian 9 with gcc 6.3. Here is how I went about trying to recreate the scenario described in your post.



First create the "alice" and "bob" users and them to the "staff" group:



useradd -m -G staff alice
useradd -m -G staff bob


Next create the file and set its ownership and permissions:



# Create a subdirectory to hold the text file
sudo -u alice mkdir -p /home/alice/share/

# Create the text file
sudo -u alice bash -c 'echo "This is foo.txt" > /home/alice/share/foo.txt'

# Set restrictive permissions on the text file
chmod u=rw,g=,o= /home/alice/share/foo.txt


Let's check the results:



$ ls -l /home/alice/share/foo.txt
-rw------- 1 alice alice 16 Nov 4 15:33 /home/alice/share/foo.txt


Now let's create a version of display-foo which uses the system function:



$ cat <<HEREDOC > /usr/local/src/display-foo.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

int main(int argc, char **argv)

struct passwd *r_pwd = getpwuid(getuid());
printf("Real user: %sn", r_pwd->pw_name);

struct passwd *e_pwd = getpwuid(geteuid());
printf("Effective user: %sn", e_pwd->pw_name);

system("/bin/cat /home/alice/share/foo.txt");

HEREDOC

$ gcc /usr/local/src/display-foo.c -o /usr/local/bin/display-foo


And let's set ownership and permissions on display-foo, including setting the setuid bit:



chown alice:alice /usr/local/bin/display-foo
chmod u=rwx,g=rx,o=rx /usr/local/bin/display-foo
chmod u+s /usr/local/bin/display-foo


Let's also check the result:



$ ls -l /usr/local/bin/display-foo
-rwsr-xr-x 1 alice alice 8640 Nov 4 15:40 /usr/local/bin/display-foo


Now we run the program both as alice and as bob:



$ sudo -u alice display-foo

Real user: alice
Effective user: alice
This is foo.txt

$ sudo -u bob display-foo

Real user: bob
Effective user: alice
This is foo.txt


As you can see, it looks like everything is working as expected.






share|improve this answer














I read through the manual page for the system function and came across the following passage which offers an explanation:




Do not use system() from a program with set-user-ID or set-group-ID
privileges, because strange values for some environment variables
might be used to subvert system integrity. Use the exec(3) family of
functions instead, but not execlp(3) or execvp(3). system() will
not, in fact, work properly from programs with set-user-ID or set-
group-ID privileges on systems on which /bin/sh is bash version 2,
since bash 2 drops privileges on startup. (Debian uses a modified
bash which does not do this when invoked as sh.)



Here are some other StackExchange posts that I read through on my way to that passage:



  • SETUID Permission Denied

  • Why do I need setuid(0) within a setuid-root C program that calls an administrative program with system()?

  • Debugging a setuid program / “Permission denied” with setuid

  • Unix suid bit problem

  • how to set the setuid bit in a program of a non-root user?

  • linux setuid does not work

For posterity, and because the given example might be useful for diagnosing this or similar issues in other contexts, I've kept my original below.




Is it possible that you're running into a bug? I was unable to reproduce your problem in a Docker container running Debian 9 with gcc 6.3. Here is how I went about trying to recreate the scenario described in your post.



First create the "alice" and "bob" users and them to the "staff" group:



useradd -m -G staff alice
useradd -m -G staff bob


Next create the file and set its ownership and permissions:



# Create a subdirectory to hold the text file
sudo -u alice mkdir -p /home/alice/share/

# Create the text file
sudo -u alice bash -c 'echo "This is foo.txt" > /home/alice/share/foo.txt'

# Set restrictive permissions on the text file
chmod u=rw,g=,o= /home/alice/share/foo.txt


Let's check the results:



$ ls -l /home/alice/share/foo.txt
-rw------- 1 alice alice 16 Nov 4 15:33 /home/alice/share/foo.txt


Now let's create a version of display-foo which uses the system function:



$ cat <<HEREDOC > /usr/local/src/display-foo.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

int main(int argc, char **argv)

struct passwd *r_pwd = getpwuid(getuid());
printf("Real user: %sn", r_pwd->pw_name);

struct passwd *e_pwd = getpwuid(geteuid());
printf("Effective user: %sn", e_pwd->pw_name);

system("/bin/cat /home/alice/share/foo.txt");

HEREDOC

$ gcc /usr/local/src/display-foo.c -o /usr/local/bin/display-foo


And let's set ownership and permissions on display-foo, including setting the setuid bit:



chown alice:alice /usr/local/bin/display-foo
chmod u=rwx,g=rx,o=rx /usr/local/bin/display-foo
chmod u+s /usr/local/bin/display-foo


Let's also check the result:



$ ls -l /usr/local/bin/display-foo
-rwsr-xr-x 1 alice alice 8640 Nov 4 15:40 /usr/local/bin/display-foo


Now we run the program both as alice and as bob:



$ sudo -u alice display-foo

Real user: alice
Effective user: alice
This is foo.txt

$ sudo -u bob display-foo

Real user: bob
Effective user: alice
This is foo.txt


As you can see, it looks like everything is working as expected.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 6 '17 at 12:20

























answered Nov 5 '17 at 22:09









igal

4,830930




4,830930







  • 1




    I've replicated every single step listed above. Same result. Running the binary as alice prints (Real user: alice, Effective user: alice, This is foo.txt). Running the binary as bob prints (Real user: bob, Effective user: alice, /bin/cat: /home/alice/share/foo.txt: Permission denied). In other words, bob had the permission to run the binary, but somehow was unable to execute the system() instruction, as mentioned by Sato. Very very peculiar.
    – JTJM
    Nov 6 '17 at 5:43











  • @JTJM I think I figured it out. See the update to my solution.
    – igal
    Nov 6 '17 at 12:21












  • 1




    I've replicated every single step listed above. Same result. Running the binary as alice prints (Real user: alice, Effective user: alice, This is foo.txt). Running the binary as bob prints (Real user: bob, Effective user: alice, /bin/cat: /home/alice/share/foo.txt: Permission denied). In other words, bob had the permission to run the binary, but somehow was unable to execute the system() instruction, as mentioned by Sato. Very very peculiar.
    – JTJM
    Nov 6 '17 at 5:43











  • @JTJM I think I figured it out. See the update to my solution.
    – igal
    Nov 6 '17 at 12:21







1




1




I've replicated every single step listed above. Same result. Running the binary as alice prints (Real user: alice, Effective user: alice, This is foo.txt). Running the binary as bob prints (Real user: bob, Effective user: alice, /bin/cat: /home/alice/share/foo.txt: Permission denied). In other words, bob had the permission to run the binary, but somehow was unable to execute the system() instruction, as mentioned by Sato. Very very peculiar.
– JTJM
Nov 6 '17 at 5:43





I've replicated every single step listed above. Same result. Running the binary as alice prints (Real user: alice, Effective user: alice, This is foo.txt). Running the binary as bob prints (Real user: bob, Effective user: alice, /bin/cat: /home/alice/share/foo.txt: Permission denied). In other words, bob had the permission to run the binary, but somehow was unable to execute the system() instruction, as mentioned by Sato. Very very peculiar.
– JTJM
Nov 6 '17 at 5:43













@JTJM I think I figured it out. See the update to my solution.
– igal
Nov 6 '17 at 12:21




@JTJM I think I figured it out. See the update to my solution.
– igal
Nov 6 '17 at 12:21












up vote
0
down vote













The foo.txt file is in a share directory in Alice home directory,so Bob can not access the files in Alice home directory because of permissions.
you can create a shared directory in home, and givin both permissions to access this directory.



or, you can create a shared directory with groupowner of staff and set SGID bit with this command:



chmod 2777 sharedDir


when the SGID bit is set on a directory, new files or sub-directories created in the original directory will inherit the group ownership of the directory rather than be based on the user's current default group.



so when Alice create a file here, group ownership of the file will be STAFF and all of the member of this gorup can access these files base on staff group permission.






share|improve this answer






















  • Correct in that bob can't read foo.txt. But ./display-foo is setuid alice, which means it runs with alice's permissions and access rights, and the OP is asking why this program still can't read foo.txt.
    – roaima
    Aug 22 at 14:26











  • @roaima my post has been updated
    – anis
    Aug 26 at 13:31














up vote
0
down vote













The foo.txt file is in a share directory in Alice home directory,so Bob can not access the files in Alice home directory because of permissions.
you can create a shared directory in home, and givin both permissions to access this directory.



or, you can create a shared directory with groupowner of staff and set SGID bit with this command:



chmod 2777 sharedDir


when the SGID bit is set on a directory, new files or sub-directories created in the original directory will inherit the group ownership of the directory rather than be based on the user's current default group.



so when Alice create a file here, group ownership of the file will be STAFF and all of the member of this gorup can access these files base on staff group permission.






share|improve this answer






















  • Correct in that bob can't read foo.txt. But ./display-foo is setuid alice, which means it runs with alice's permissions and access rights, and the OP is asking why this program still can't read foo.txt.
    – roaima
    Aug 22 at 14:26











  • @roaima my post has been updated
    – anis
    Aug 26 at 13:31












up vote
0
down vote










up vote
0
down vote









The foo.txt file is in a share directory in Alice home directory,so Bob can not access the files in Alice home directory because of permissions.
you can create a shared directory in home, and givin both permissions to access this directory.



or, you can create a shared directory with groupowner of staff and set SGID bit with this command:



chmod 2777 sharedDir


when the SGID bit is set on a directory, new files or sub-directories created in the original directory will inherit the group ownership of the directory rather than be based on the user's current default group.



so when Alice create a file here, group ownership of the file will be STAFF and all of the member of this gorup can access these files base on staff group permission.






share|improve this answer














The foo.txt file is in a share directory in Alice home directory,so Bob can not access the files in Alice home directory because of permissions.
you can create a shared directory in home, and givin both permissions to access this directory.



or, you can create a shared directory with groupowner of staff and set SGID bit with this command:



chmod 2777 sharedDir


when the SGID bit is set on a directory, new files or sub-directories created in the original directory will inherit the group ownership of the directory rather than be based on the user's current default group.



so when Alice create a file here, group ownership of the file will be STAFF and all of the member of this gorup can access these files base on staff group permission.







share|improve this answer














share|improve this answer



share|improve this answer








edited Aug 26 at 12:15

























answered Aug 22 at 13:41









anis

92




92











  • Correct in that bob can't read foo.txt. But ./display-foo is setuid alice, which means it runs with alice's permissions and access rights, and the OP is asking why this program still can't read foo.txt.
    – roaima
    Aug 22 at 14:26











  • @roaima my post has been updated
    – anis
    Aug 26 at 13:31
















  • Correct in that bob can't read foo.txt. But ./display-foo is setuid alice, which means it runs with alice's permissions and access rights, and the OP is asking why this program still can't read foo.txt.
    – roaima
    Aug 22 at 14:26











  • @roaima my post has been updated
    – anis
    Aug 26 at 13:31















Correct in that bob can't read foo.txt. But ./display-foo is setuid alice, which means it runs with alice's permissions and access rights, and the OP is asking why this program still can't read foo.txt.
– roaima
Aug 22 at 14:26





Correct in that bob can't read foo.txt. But ./display-foo is setuid alice, which means it runs with alice's permissions and access rights, and the OP is asking why this program still can't read foo.txt.
– roaima
Aug 22 at 14:26













@roaima my post has been updated
– anis
Aug 26 at 13:31




@roaima my post has been updated
– anis
Aug 26 at 13:31

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f401351%2fsuid-bit-on-binary-file-still-yielding-permission-denied-error%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Peggy Mitchell

The Forum (Inglewood, California)

Palaiologos