34

I'm in /sbin and I see that shutdown has permissions rwxr-xr-x. Doesn't this mean that anyone can execute it?

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
Korgan Rivera
  • 2,543
  • 6
  • 28
  • 39
  • 1
    what is the command that you ran and what is the error that you get ? – slayedbylucifer Dec 04 '13 at 10:55
  • I think he's talking about the `shutdown` command. – Vinz Dec 04 '13 at 11:02
  • I ran ./shutdown +30. I get "shutdown: need to be root". However, if the permissions say that anyone can execute, why do I need to be root? – Korgan Rivera Dec 04 '13 at 11:02
  • I'm guessing, that anyone can shutdown the machine. Just like on a GUI, anyone can shut it down too. But if you are saying that you need to be root, then I don't know. Good question though. – Kevdog777 Dec 04 '13 at 11:02
  • 4
    @Kevdog777 : On a GUI PolicyKit manages this. It is a daemon with root privileges which will check if you're allowed to use `shutdown`. – Vinz Dec 04 '13 at 11:09
  • You can't do it because it wouldn't be secure if you could. If all you needed was rx permissions on a binary in order to (successfully) execute it, i.e. in order to shut down a machine, then anyone could shutdown any machine as you can just upload and execute a binary with rx permissions yourself. – frostschutz Dec 05 '13 at 15:06
  • Anyone can execute `/bin/rm -rf`, but you cannot remove `/etc`, or another user's home directory. It goes further: Any local user can write, compile and execute a program that'll use any library or system call on your machine. So the execution bits do nothing in terms of security. Group and user rights are what prevents any user from having unrestricted powers. (The read and write bits are another matter, since they protect authentication secrets). – alexis Dec 07 '13 at 13:05

4 Answers4

76

Anyone can execute shutdown, but triggering a system shutdown requires root privileges. But shutdown is not setuid, and so only root can successfully execute it. The shutdown program is nice enough to check your privileges and let you know if there is a problem, but even if it naively tried a system shutdown, nothing would happen.

GLENDOWER: I can call spirits from the vasty deep.
HOTSPUR: Why, so can I, or so can any man; But will they come when you do call for them?
(from Henry IV)

shutdown is no different from /bin/rm. Everyone can execute it, but a regular user cannot remove /etc, or another user's home directory.

Specifically: Only a process running with root privileges (effective UID 0) can direct the init system to stop system services, terminate all user processes, and issue the system call that actually stops the machine. (If shutdown was setuid, it would run as root no matter who invokes it; but it is not.)

What about calling shutdown from a GUI, e.g. with control-alt-del? It's important to realize that in that case, shutdown is started directly by init and it runs with root privileges. So everyone who walks up to the console could potentially shut it down. If this is not desirable, control-alt-delete will actually run shutdown -a. (See the documentation that @some1 quoted in their answer). That tells shutdown to check whether the currently logged in user is authorized to run it. But this is only relevant because shutdown is running as root in this scenario.

alexis
  • 5,719
  • 3
  • 21
  • 28
  • 2
    Clarification: Anyone can execute the program `shutdown`, but that program **can't** actually trigger a system shutdown unless the current user has root privileges. Right? – LarsH Dec 04 '13 at 19:26
  • 1
    That's pretty much it. Programs run with the privileges of the invoking user, unless they're setuid. Shutting down the system requires root privileges, so you can't write your own program to do it, either (except by exploiting security holes etc.). – alexis Dec 04 '13 at 22:47
  • What does "shutdown is not setuid" mean? – Iain Samuel McLean Elder Dec 07 '13 at 16:45
  • 1
    @Iain, programs are normally run with the permissions of the user who invokes them. This is also the case with `shutdown`. A setuid program is run with the permisions of the user who owns the executable. E.g., `/etc/passwd` runs with root permissions to allow you to modify the password file. See the manpage for `chmod`. – alexis Dec 08 '13 at 18:34
  • That should have been "`/usr/bin/passwd` runs with root permissions"! `/etc/passwd` is not executable (it is the "password file" being modified). – alexis Dec 10 '13 at 23:19
15

The binary shutdown itself checks if your UID is 0.

See the strace output of:

strace /sbin/shutdown -r -h now
...
...
geteuid()                               = 10001
setuid(10001)                           = 0
getuid()                                = 10001
write(2, "shutdown: Need to be root\n", 26shutdown: Need to be root
) = 26
exit_group(1)                           = ?
chaos
  • 47,463
  • 11
  • 118
  • 144
  • 4
    +1 for showing the use of strace ... this is useful. However I don't see how this trace shows that `shutdown` checks that your UID is 0. – LarsH Dec 04 '13 at 19:29
  • 1
    You won't see that in the strace output since it only reports system calls. You can _infer_ that when a getuid is closely followed by writing the error message that the code was similar to `if(getuid() != 0) printf("Need to be root");`. Which in fact the source code shows it to be. – msw Dec 06 '13 at 13:17
5

Yes ! Everybody can run that command. As you said, you're able to run it but you're faced with a "Need to be root" message, not a permission denied. The shutdown command checks your UID to see if you're root, or not.

Vinz
  • 2,120
  • 12
  • 16
-1

It appears that shutdown will check an access list if you flag it with -a:

ACCESS CONTROL
       shutdown can be called from init(8) when the magic keys CTRL-ALT-DEL are pressed, by creating an appropriate entry in /etc/inittab. This means that every‐
       one who has physical access to the console keyboard can shut the system down. To prevent this, shutdown can check to see if an authorized user  is  logged
       in  on  one of the virtual consoles. If shutdown is called with the -a argument (add this to the invocation of shutdown in /etc/inittab), it checks to see
       if the file /etc/shutdown.allow is present.  It then compares the login names in that file with the list of people that are logged in on a virtual console
       (from /var/run/utmp). Only if one of those authorized users or root is logged in, it will proceed. Otherwise it will write the message

       shutdown: no authorized users logged in

       to  the  (physical)  system  console.  The  format  of  /etc/shutdown.allow is one user name per line. Empty lines and comment lines (prefixed by a #) are
       allowed. Currently there is a limit of 32 users in this file.

Since you're currently calling it without the -a flag, it's defaulting to allowing root shutdowns only.

If you want additional users to be able to run the command, configure that file and use the flag.

Why can't I execute shutdown when the permission is rwxr-xr-x?

Permission bits don't necessarily exclude access control based on a user or group.

some1
  • 1,776
  • 4
  • 20
  • 27
  • Calling it with `-a` from the commandline will make no difference: `shutdown -a` must still be executed with root permissions (which `init` supplies on control-alt-del). – alexis Dec 04 '13 at 11:38