13 Replies Latest reply on Mar 18, 2015 3:25 AM by bagpussy

    Anyone know how to access RasPi GPIO without sudo?

    John Beetem

      I've finally gotten around to playing with RasPi GPIOs, using Gert van Loo and Dom's C code at the RasPi Wiki.  It works fine, except that you have to run the executable as root or use sudo to access /dev/mem.

       

      Does anyone here know how to access /dev/mem as a normal user?

        • Re: Anyone know how to access RasPi GPIO without sudo?
          chiem

          Not sure what you have against running as root--either via su, sudo $SHELL, or setuid--but you could try:

           

          $ sudo chown pi /dev/mem

            • Re: Anyone know how to access RasPi GPIO without sudo?
              John Beetem

              Keith Chiem wrote:

               

              Not sure what you have against running as root--either via su, sudo $SHELL, or setuid--but you could try:

               

              $ sudo chown pi /dev/mem

              I like to run as a normal user most of the time so that I don't accidentally destroy system files.  I'll try your suggestion with /dev/mem, and if it doesn't work I'll take a closer look at permissions for /dev/mem.

               

              One think that's a bit different in my case is that I'm editing and running programs within the XXICC programming environment (xxicc.org).  I'm not generating a stand-alone GPIO program which I can then run using sudo.  I currently have to run XXICC using sudo, so I'm not protected form destroying system files.

              • Re: Anyone know how to access RasPi GPIO without sudo?
                jopaji

                Keith Chiem wrote:

                 

                $ sudo chown pi /dev/mem

                That will not work.  As well as any access controls imposed by the filesystem, you also need to have capability CAP_SYS_RAWIO to open the /dev/mem device.  So you do need to be setuid root (or setcap).

                 

                Note that you do not need any special permissions for any of the later steps, however.  So you can start as root, open /dev/mem, drop privileges with set(res)uid, mmap just the registers you need, close the device to make it impossible to map any more, and then continue with the rest of your code safely.

                1 of 1 people found this helpful
                  • Re: Anyone know how to access RasPi GPIO without sudo?
                    John Beetem

                    Roger Wolff wrote:

                     

                    Now back to your problem...
                    If you make a little program that allows you to manipulate just the GPIO outputs, that won't allow you to cause all the other mischief you'd be able to make with "/dev/mem" access, then you can install that program with superuser permissions (setuid) and then you can use that program as a normal user.

                     

                    I have written such a program. IIRC, it is contained in this package:

                    http://www.bitwizard.nl/software/gpio_spi_i2c_20120419.tgz

                     

                    The program can be made setuid by doing:

                      sudo chown root <program name>

                      sudo chmod 4755 <program name>

                     

                    jopaji wrote:

                     

                    Keith Chiem wrote:

                     

                    $ sudo chown pi /dev/mem

                    That will not work.  As well as any access controls imposed by the filesystem, you also need to have capability CAP_SYS_RAWIO to open the /dev/mem device.  So you do need to be setuid root (or setcap).

                     

                    Note that you do not need any special permissions for any of the later steps, however.  So you can start as root, open /dev/mem, drop privileges with set(res)uid, mmap just the registers you need, close the device to make it impossible to map any more, and then continue with the rest of your code safely.

                    Well, I finally got around to testing these suggestions.  I got CAP_SYS_RAWIO to work (mostly), but decided that it was too dangerous.  So I went with a combination of Roger's suggestion to use chown and chmod so that my programs starts as root, and jopaji's suggestion to call setuid(getuid()) to drop superuser access after using mmap() so as to become a normal user.

                     

                    This scheme is also described by nroff-man at the Raspberry Pi Forum: http://www.raspberrypi.org/forums/viewtopic.php?f=29&t=22515

                     

                    I also learned that you should close /dev/mem once you have done the mmap() so that you don't have a dangerous file descriptor lying around.  Here's my final code, which sets global pointer RasPiGPIO to the virtual address of the GPIO registers or NULL on failure:

                     

                    // Attempt to map RasPi GPIO registers to a virtual address.

                    // Set RasPiGPIO to that address, or NULL if unable to map (print warning).

                    static void AccessRasPiGPIO(void)

                    {

                        int fd = open("/dev/mem", O_RDWR);

                        if (fd < 0)

                        {

                            fprintf(stderr, "Cannot access Raspberry Pi GPIOs: you probably need sudo.\n");

                            return;

                        };

                        // 0x20200000 is the Debian base for mapping RasPi GPIOs using /dev/mem.

                        RasPiGPIO = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x20200000);

                        if (RasPiGPIO == MAP_FAILED)

                        {

                            fprintf(stderr, "Cannot access Raspberry Pi GPIOs: mmap() failed.\n");

                            RasPiGPIO = NULL;

                        } else printf("XXICC can access Raspberry Pi GPIOs.\n");

                        close(fd);    // No longer need /dev/map once we have the virtual address.

                    }

                     

                    After I call this function, I set the user ID back to the original user with the code: setuid(getuid());

                    Thank you to everyone for their suggestions!

                  • Re: Anyone know how to access RasPi GPIO without sudo?
                    bagpussy

                    If you are the only one with access it is no real problem. I don't particularly wish to give sudo access to the kids.

                  • Re: Anyone know how to access RasPi GPIO without sudo?
                    Arjan

                    Either you have to run your application as root, or use a device driver than trying to use /dev/mem

                      • Re: Anyone know how to access RasPi GPIO without sudo?
                        Roger Wolff

                        Unix has a "security model". As a normal users you can do stuff, but you should not be able to access other people's files on the same computer. And as a user you should not be able to cause the computer to stop working.

                         

                        This means that as a rule, you should not be able to directly access hardware, like the physical memory of the computer. So that's why /dev/mem is protected so that normal users cannot access it.

                         

                        Now "/dev/mem" allows you much, much more "mischief" than just changing a GPIO. So that's why /dev/mem must be protected against normal users.

                         

                        If "allowable" things need to happen, the normal way to achieve this is to make a setuid program. The program GETS the priviledges needed once it is executed, the program then checks permissions (if neccessary) and then allows you to do the little thing you wanted.

                         

                        As an example, the system cannot and should not allow you to insert a random packet onto the network. However the operating system does not provide a way to send "ICMP ECHO REQUEST" packets. There is a program that does that: "ping"! So the ping program gets privileges, uses that to send a carefully prepared ICMP ECHO REQUEST packet, and display the results. Although it uses the system mechanism for "sending arbitrary packets", it should restrict you to only send the innocent ICMP ECHO REQUEST packets. The ping program doesn't have any further permission checking (that I know of).

                         

                        Now back to your problem...
                        If you make a little program that allows you to manipulate just the GPIO outputs, that won't allow you to cause all the other mischief you'd be able to make with "/dev/mem" access, then you can install that program with superuser permissions (setuid) and then you can use that program as a normal user.

                         

                        I have written such a program. IIRC, it is contained in this package:

                        http://www.bitwizard.nl/software/gpio_spi_i2c_20120419.tgz

                         

                        The program can be made setuid by doing:

                          sudo chown root <program name>

                          sudo chmod 4755 <program name>

                         

                        The program I wrote has NOT been checked for security in this scenario.

                         

                        The responsibility of "keeping the system safe" is moved from the kernel to the program with the elevated permissions. So if the "ping" program contained a bug that, say, would allow hackers to specify arbitrary network packets, then the protection of the system that normal users cannot send arbitrary network packets breaks down.

                      • Re: Anyone know how to access RasPi GPIO without sudo?

                        Does anyone here know how to access /dev/mem as a normal user?

                        Don't do that.  There's a device driver for the gpios that can be made to expose them under /sys/class/gpio. Access is comparitively slow, but at least it's safer than messing with /dev/mem

                         

                        You can find documentation for 'gpiolib' towards the end of Documentation/gpio.txt in any recent linux kernel source tree. There you'll find out how to export particular gpios to userspace. 

                        Note that you likely still need to chown some files under /sys/class/gpio to allow user access after exporting them as root. Roger is quite right on the security model - consider that gpio's will often be connected to something that sensitive and you should understand why you normally need root to access them.

                         

                        Here's a trivial example in bash

                         

                        echo 55 > /sys/class/gpio/export

                        echo out > /sys/class/gpio/gpio55/direction

                        echo 1 > /sys/class/gpio/gpio55/value

                         

                        however note that 55 isn't a valid value unless you've added a gpio expander like the mcp23008 I'm using, and recompiled the kernel appropriately.

                        1 of 1 people found this helpful
                          • Re: Anyone know how to access RasPi GPIO without sudo?
                            John Beetem

                            selsinork wrote:

                             

                            Does anyone here know how to access /dev/mem as a normal user?

                            Don't do that.  There's a device driver for the gpios that can be made to expose them under /sys/class/gpio. Access is comparitively slow, but at least it's safer than messing with /dev/mem

                            Thank you for the suggestions, but I don't want slow.  This is more out of principle (what others call "pig-headedness") than any real need for my LEDs to blink one million times faster than my eye can resolve.  I figure, hey, it's my computer and what's the point of having memory-mapped I/O if I can't access it as memory?  If you're going to go through several layers of condoms to protect your GPIOs, you might as well be using a mainframe and where's the fun in that?

                             

                            OTOH, I do accidentally delete files from time to time and I'd hate to accidentally delete a system file or directory while being root, so I don't like to stay root for more milliseconds than necessary.  OTOH, I find I've almost never screwed up a system by accessing the wrong memory address, probably because I'm more careful doing the latter.  Back when I was programming PDP-11s, I caused any number of bus errors but never accidentally wrote bad words into the hard drive control registers.

                             

                            So here's something else I tried: I changed the permissions on /dev/mem to the dreaded 666 to allow anyone to access it.  That didn't work.  I also tried changing permissions on /dev/mem to 660 and added myself to the "kmem" group.  That didn't work either.  I'm a little nervous about changing the ownership of /dev/mem to myself since I'd worry that root might want to be the owner somewhere else.

                              • Re: Anyone know how to access RasPi GPIO without sudo?

                                Thank you for the suggestions, but I don't want slow.  This is more out of principle (what others call "pig-headedness") than any real need for my LEDs to blink one million times faster than my eye can resolve.  I figure, hey, it's my computer and what's the point of having memory-mapped I/O if I can't access it as memory?  If you're going to go through several layers of condoms to protect your GPIOs, you might as well be using a mainframe and where's the fun in that?

                                At this point I'll respectfully suggest you're looking at it the wrong way. You have two conflicting requirements, you should pick one and be done with it. Either run as root and accept that you can delete files either by using 'rm -rf /' or by scribbling the wrong stuff into /dev/mem, or run as a normal user and accept those limitations.

                                 

                                You should also realise that the same gpio driver that you don't want to use 'owns' the memory locations you want to manually write to and as such you can't prevent the kernel from changing those locations behind your back. (you could try compiling out the gpio driver, but as the sdcard driver depends on it you'll have other problems).

                                This is part of the compromise you sign up to by running linux as your OS. You are of course free to do other things by not running linux, going for a bare metal approach and treating the Pi like an arduino.

                                 

                                I also agree with the sentiment that it's your computer and you should be able to do what you like. For that reason, especially on something like the Pi, I suggest simply running as root and forgetting about the 'problem' altogether     I have effectively just one user on my Pi - root (there are a few more, but no others can login and they're only there to keep stuff that expects them happy)

                            • Re: Anyone know how to access RasPi GPIO without sudo?
                              mobilewill

                              Here is how I did it.

                               

                              http://www.mobilewill.us/2012/07/raspberry-pi-and-gpio-permissions.html

                               

                               

                              I gave access to a user to run only a script as root by editing the sudoers file. This keeps the security but allows you to access the GPIO.

                              • Re: Anyone know how to access RasPi GPIO without sudo?
                                bencom

                                Greeting John

                                 

                                I use wiringPi and have written a small daemon framework that I will finish once I sort out hardware/logic requirements.

                                This sort of set up allows user space programs to talk to the daemon although I am not doing this at present.

                                My application needs a push button and a tamper switch plus relay outputs (4 at first).

                                Camera plus streaming audio. Motion & avconv. Signally to end points. Control of relays from EP.

                                Logic to deal with a gate opener and general security at a distant gate (150m for my proof of concept).

                                Push button at camera. Plays sound, cyborg voice, turns on relay (light at cam), signals end point RPi.

                                End point at home TV. View, send audio to, and push button or web interface to open gate.

                                The perfect application for the RPi and allows further system integration with other systems.

                                 

                                Eventually I want to hook MC9S08 and STM32V modules to the RPi all of which I have and am reasonably competent with.

                                As for Linux. I am an early implimenter starting in the days when it took days to get the bits to get a 386 going.

                                By no means a ubber geek I am entirely self taught and work on a need to know basis.

                                 

                                Always looking for people wishing to join in and can provide a private vehicle for a small development group on my hobby web site zlham.geek.nz.

                                Sorry I do not accept freemail addresses unless I know who wants an account in which case it is best to email me before applying.

                                 

                                If the OP is interested in code I can put it up on my ftp site with the caviate that it is not fit for public release as such and will be taken down again in a week or so.

                                 

                                Regards

                                Peter

                                • Re: Anyone know how to access RasPi GPIO without sudo?
                                  nsaspook

                                  I think the proper way is to use a somewhat standard DAQ system like Comedi for most applications that don't need realtime response. I'm working on a GPIO/Gertboard kernel module the uses the Comedi library for DIO, analog and PWM. I hope to have it in the 3.7ish kernel release but it works with the current RPi debian 3.2 release with some easy changes.

                                   

                                  The code is still pretty alpha but the basic DIO code framwork is done.

                                   

                                  daq-gert https://github.com/nsaspook/daq_gert.git

                                   

                                  http://www.comedi.org/

                                  • Re: Anyone know how to access RasPi GPIO without sudo?
                                    nsaspook

                                    Here is a HOWTO to test the daq_gert module. It's still in development but most of the DIO function code is in place with fake analog devices as placeholders for now.

                                     

                                    https://github.com/nsaspook/daq_gert/blob/master/RPi_Comedi_HOWTO.txt