Why does the SUID bit have no effect when applied to directories in Linux? I clearly see that I can set it with 'chmod u+s'. But why does it not have "any" effect. What is the reason for implementing a way to SET it but not implementing any effect?
Linux – SUID has no effect on directories with Linux
chmoddirectorylinuxsetuid
Related Solutions
Quoting access()
manpage:
The check is done using the calling process's real UID and GID, rather than the effective IDs as is done when actually attempting an operation (e.g., open(2)) on the file. This allows set-user-ID programs to easily determine the invoking user's authority.
Set-user-ID bit makes the process's effective UID equal to the file owner, but the real user ID remains unchanged (i.e. remains what it was before exec()
).
You can use setreuid()
to modify both effective UID and real UID of the process or you can use open()
to determine privileges. I recommend the second solution especially since you already call open()
anyway. You can check whether errno
is equal to EPERM
to find out whether insufficient permissions was the reason open()
failed.
The call to open()
fails in your code, because you use the return value from open()
as the if condition. I guess the call actually succeeds and returns you a valid, non-zero (zero being already taken by stdin) file descriptor making the control go into the error-handling branch. The error-handling branch of the if displays EPERM
error message since this is the last error which occurred due to access()
call. The condition to enter the error handling branch should check whether open()
returned -1.
As you correctly state a SUID bit, sets the effective user-id of the new process to the owner of the program file being run. There's no concept of raising or lowering privileges. Often the user to which one "suids" is root, but it can just as legitimately be any other, and doesn't really change the concept of SUID, when you choose another, apart from some users have access to certain resources. However the root user is a little bit special, and the man page for setuid, explains the subtle differences. I don't think there is a special name for changing to a non-root user, and I have never associated suid meaning going up in privilege, just changing user.
Since you are developing the master yourself which runs as root it can setuid to any user after forking but before exec-ing the new process, I dont see that suid bit has to be used on executable at all, and incidently if you don't, then if any-old user ran the player, since executable is not suid, they wouldn't be able to run it correctly since setuid will fail if they were not root. For me this seems like better security, than using suid bits on executable files.
--- edit 1
So your manager (running as real and effective uid=0) starts player and you code/control player (not manager). If you do nothing special, then player will run with real+effective uid=0 and you want to prevent this.
You could just switch uid in player, no SUID bits on player, no need.
Best Answer
The main reason to have a way to set it is simple: simplicity. It's simpler to treat the setuid bit on directories uniformly with other bits, than it would be to make an exception and reject attempts to set it.
Another reason is that you can mount a filesystem under Linux, set the setuid bit on a directory, and then mount this filesystem under another operating system that does treat the setuid bit in a meaningful way.
As for why the setuid bit has no effect on directories on Linux, that's because no one has found a compelling meaning for it. It can't work in the same way as the setgid bit because Linux doesn't allow a user to give away a file to another user.