RPi Gateaway: Dropping root privilege

  • I'd prefer not running as root a process that parse radio messages and do a lot of stuff on it.

    The mysGateway on Raspberry Pi needs root privileges for GPIO and SPI. Using a GPIO group (rasbian package raspberrypi-sys-mods) is not enough, SPI si not working.

    I suggest SUID binary and drop root privileges after mmaping /dev/mem, but I don't know the better place to do this. I suggest here in bcm2835.c, but I don't know if it really clean and tit doesn't mess something else.

    chmod u+s /usr/local/bin/mysGateway

    diff --git a/drivers/RPi/bcm2835.c b/drivers/RPi/bcm2835.c
    index 26aa8d6..7b262b5 100644
    --- a/drivers/RPi/bcm2835.c
    +++ b/drivers/RPi/bcm2835.c
    @@ -1358,6 +1358,10 @@ int bcm2835_init(void)
           /* Base of the peripherals block is mapped to VM */
           bcm2835_peripherals = mapmem("gpio", bcm2835_peripherals_size, memfd, (uint32_t)bcm2835_peripherals_base);
    +      /* Drop root privileges if SUID */
    +      setuid(getuid());
           if (bcm2835_peripherals == MAP_FAILED) goto exit;
           /* Now compute the base addresses of various peripherals, 

    When doing this a bug appears in GPIO for IRQ, the delay between export and opening is not long enough. The folder folder is already created, but group permissions are not yet propagated (raspbian udev rule 99-com.rules use a chown). Running mysGateway failed half the time. I encountered errors for values under 30ms on RPi 3.

    diff --git a/drivers/RPi/rpi_util.cpp b/drivers/RPi/rpi_util.cpp
    index 7ee1a92..96ff78f 100644
    --- a/drivers/RPi/rpi_util.cpp
    +++ b/drivers/RPi/rpi_util.cpp
    @@ -236,7 +236,8 @@ void rpi_util::attachInterrupt(uint8_t physPin, void (*func)(), uint8_t mode) {
            // Wait a bit the system to create /sys/class/gpio/gpio<GPIO number>
    -       delay(1L);
    +       // Udev chown on raspbian takes time. Measured up to 30ms on RPi 3, leave good a margin
    +       delay(100L);
            snprintf(fName, sizeof(fName), "/sys/class/gpio/gpio%d/direction", gpioPin) ;
            if ((fd = fopen (fName, "w")) == NULL) {