5

I am developing C function to shutdown my Embedded Linux system (Ubuntu) using the following way.

#include <stdlib.h>

int main() 
{
    system("shutdown -P now");
    return 0;
}

Is this approach is secure?
If not is there any better and secure way I can perform same task?

Swordfish
  • 12,971
  • 3
  • 21
  • 43
raj123
  • 564
  • 2
  • 10
  • 27
  • `system()` spawns a child process which is used to execute the command. I'd call [reboot()](http://man7.org/linux/man-pages/man2/reboot.2.html) directly. As for security please have a look at the comments to [Why should the system() function be avoided in C and C++?](https://stackoverflow.com/questions/19913446/why-should-the-system-function-be-avoided-in-c-and-c) – Swordfish Nov 21 '18 at 05:43
  • thanks got it we have to avoid system call.So how can I perform same functionality without system call?@Swordfish – raj123 Nov 21 '18 at 06:00
  • I also read about [reboot](http://man7.org/linux/man-pages/man2/reboot.2.html) but couldn't getting it how can I use it to shutdown my system.@Swordfish – raj123 Nov 21 '18 at 06:02
  • https://stackoverflow.com/a/31652816/3975177 – Swordfish Nov 21 '18 at 06:10
  • It says system("/bin/sh shutdown -P now") also safe to use Is it?@Swordfish – raj123 Nov 21 '18 at 06:18
  • https://stackoverflow.com/questions/43197676/is-system-call-in-c-program-safe – Swordfish Nov 21 '18 at 06:42
  • From the cited manpage: "Only the superuser may call reboot()." If you're not running your program as `root`, you may have to set the appropriate [capability](http://man7.org/linux/man-pages/man7/capabilities.7.html) to it, or find another way. – Murphy Nov 23 '18 at 11:33

1 Answers1

2

man reboot(2)

#include <unistd.h>
#include <sys/reboot.h>

int main () {
    sync();    // If reboot() not preceded by a sync(), data will be lost.
    setuid(0); // set uid to root, the running uid must already have the
               // appropriate permissions to do this.
    reboot(RB_AUTOBOOT); // note, this reboots the system, it's not as
    return(0);           // graceful as asking the init system to reboot.
}

Pre-systemd, you could also sometimes get away with:

int main() {
    sync();
    kill(1, SIGTERM);
    return 0;
}

This method was more prevalent on embedded systems where the program is run under a single shell, but killing initd was effective as well. Note that on newer GNU/Linux's that use systemd/upstart, SIGTERM is ignored by systemd.

Cinder Biscuits
  • 4,880
  • 31
  • 51