krbonne
Posts: 3
Joined: Sun Sep 09, 2012 9:21 pm

GPIO without root-priviledges

Sun Sep 09, 2012 10:09 pm

Hi,

To port an application to the Raspberry pi, I would need to access the GPIO ports from a C application.

For input, I would need to read one of the pins about 10 times a second (to have a quick enough input responds and but still be able to process keybounce).

I have found two libraries to access the GPIO pins from C (bcm2835 and wiringPi) but in both cases, the whole application needs to have root priviledges (to access /dev/mem) and this is something I like to avoid for obvious reasons.


Other options I have found sofar to access the GPIO pins without root-access are:
- use the /sys/class/... file-system
But this would mean that I would have the application open/read/close a file for 10 times a second

- split of the GPIO-stuff to a dedicated deamon-process and have that communicate with the main application in some way (e.g. using posix file-locks).
That way, the amount of code running as root (setuid) would be limited and can be contained but would require additional code to deal with all kind of senarios of applications dying, etc.


Does anybody see any other options?


BTW. The main application is threaded (posix threads). I read somewhere it is possible to have a setuid application "drop back" to non-root per thread; but I have never done this.
Is this an option? Who can provide some code for this?


Cheerio!
Kr. Bonne.

Serac
Posts: 124
Joined: Wed Jul 18, 2012 2:49 pm

Re: GPIO without root-priviledges

Mon Sep 10, 2012 2:25 pm

Something along the lines of:
setcap cap_sys_rawio+ep /path/to/app/bin.name
You could also do some setting and dropping of privileges from within your C sources - Would suggest reading the man page for capabilities as a starting point. Ping me a reminder later and I'll dig out some sample code when I get home.

User avatar
raspberrypiguy1
Posts: 379
Joined: Sun Sep 02, 2012 7:01 pm

Re: GPIO without root-priviledges

Mon Sep 10, 2012 2:26 pm

If you just start up the GUI with sudo startx rather than just startx, this gives ever command root priverillages....

The Raspberry Pi Guy :)
Matt, The Raspberry Pi Guy YouTube channel, author of Learn Robotics with Raspberry Pi, available now: http://mybook.to/raspirobots, Computer Science & Electronics Undergraduate at The University of Edinburgh

User avatar
PeterO
Posts: 6095
Joined: Sun Jul 22, 2012 4:14 pm

Re: GPIO without root-priviledges

Mon Sep 10, 2012 2:29 pm

raspberrypiguy1 wrote:If you just start up the GUI with sudo startx rather than just startx, this gives ever command root priverillages....
The Raspberry Pi Guy :)
I hope no one is taking that suggestion seriously !

PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

Serac
Posts: 124
Joined: Wed Jul 18, 2012 2:49 pm

Re: GPIO without root-priviledges

Mon Sep 10, 2012 9:22 pm

Found the sample code - Rather than copy/pasting, a pointer is probably worth more. With libcap-dev installed, look at the man page for cap_set_proc. The flag you want to set is CAP_SYS_RAWIO.

User avatar
jojopi
Posts: 3737
Joined: Tue Oct 11, 2011 8:38 pm

Re: GPIO without root-priviledges

Mon Sep 10, 2012 10:45 pm

krbonne wrote:I have found two libraries to access the GPIO pins from C (bcm2835 and wiringPi) but in both cases, the whole application needs to have root priviledges (to access /dev/mem) and this is something I like to avoid for obvious reasons.
WiringPi open()s and mmap()s /dev/mem in wiringPiSetup() or wiringPiSetupGpio(). After that you should be able to drop setuid privileges:

Code: Select all

  if (setuid(getuid()) < 0) _exit(1);
Serac wrote:Found the sample code - Rather than copy/pasting, a pointer is probably worth more. With libcap-dev installed, look at the man page for cap_set_proc. The flag you want to set is CAP_SYS_RAWIO.
CAP_SYS_RAWIO is necessary to open /dev/mem, but not sufficient. Unless you make the device world-writable, you also need CAP_DAC_OVERRIDE. I am not sure that running in this state is actually any more secure than running as root.

User avatar
gordon@drogon.net
Posts: 2024
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK

Re: GPIO without root-priviledges

Wed Sep 12, 2012 10:02 pm

krbonne wrote:Hi,

To port an application to the Raspberry pi, I would need to access the GPIO ports from a C application.

For input, I would need to read one of the pins about 10 times a second (to have a quick enough input responds and but still be able to process keybounce).

I have found two libraries to access the GPIO pins from C (bcm2835 and wiringPi) but in both cases, the whole application needs to have root priviledges (to access /dev/mem) and this is something I like to avoid for obvious reasons.
You don't (always) need root for witingPi.

What you do is setup the pins using the gpio program, so e.g.

gpio export 17 out
gpio export 18 out
gpio export 19 in

lets you use pins 17 & 18 as outputs, and 19 as an input.

Then you initialise wiringPi with:

x = wiringPiSetupSys () ;

check that x >= 0 for success.

After that, you can use digitalRead () and digitalWrite() as a nomal user.

Works too with posix threads too.

Note, you need to do the exports before the setup. You can system() them in the program, or have a shell script before you launch your program.


-Gordon
--
Gordons projects: https://projects.drogon.net/

BonesPi
Posts: 2
Joined: Tue Dec 17, 2013 7:29 pm

Re: GPIO without root-priviledges

Tue Dec 17, 2013 7:41 pm

Hi all, this is my first post! So happy to be apart of this great Pi community finally.

Gordon, thank you for all your great software and support. You have made working with the GPIO very easy. But I have a quick question for you and the rest of the community.

I'm using PWM on GPIO_18 to fade an LED in and out. And it's my understanding that the linux gpio driver still does not support PWM so I am stuck using direct memory mapping instead of being able to export the pin via /sys/class/gpio driver. Does this mean that I can only access GPIO_18 directly as the root user? I have been trying to figure out if I can access it from a non-root user.

It seems to me that I can run Gordon's gpio utility just fine from a non-root user and access the PWM mode of GPIO_18 without any problems. So I guess my question is, what's my best approach for getting PWM access from within my own code running as a non-root user?

Again, thanks for all your help! I'm having a blast with my Pi :)
-Anthony

User avatar
gordon@drogon.net
Posts: 2024
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK

Re: GPIO without root-priviledges

Tue Dec 17, 2013 10:41 pm

BonesPi wrote:Hi all, this is my first post! So happy to be apart of this great Pi community finally.

Gordon, thank you for all your great software and support. You have made working with the GPIO very easy. But I have a quick question for you and the rest of the community.

I'm using PWM on GPIO_18 to fade an LED in and out. And it's my understanding that the linux gpio driver still does not support PWM so I am stuck using direct memory mapping instead of being able to export the pin via /sys/class/gpio driver. Does this mean that I can only access GPIO_18 directly as the root user? I have been trying to figure out if I can access it from a non-root user.

It seems to me that I can run Gordon's gpio utility just fine from a non-root user and access the PWM mode of GPIO_18 without any problems. So I guess my question is, what's my best approach for getting PWM access from within my own code running as a non-root user?

Again, thanks for all your help! I'm having a blast with my Pi :)
-Anthony
The gpio program runs as a set-uid root program. That's what enabled it to be run as a non-root user.

You can make your own programs setuid -root too - but you start to enter a whole area of potential pain... However, one thing you can do, and I do this in FUZE BASIC is to install and run the program as a suid-root program, call wiringPiSetup () then drop root privs. so that normal file access is then as the calling user (e.g. pi) You can do this easily with the following function:

Code: Select all

static void revokeRoot (void)
{
  if (getuid () + geteuid () == 0)      // Really running as root
    return ;

  if (geteuid () == 0)                  // Running setuid root
     seteuid (getuid ()) ;               // Change effective uid to the uid of the caller
}
Once you do that, you can still call wiringPi functions - just not the setup function.

-Gordon
--
Gordons projects: https://projects.drogon.net/

BonesPi
Posts: 2
Joined: Tue Dec 17, 2013 7:29 pm

Re: GPIO without root-priviledges

Tue Dec 17, 2013 11:46 pm

aaaah, I see. Thank you for the explanation.

Return to “C/C++”