ocsacesar/rc522

Not working without sudo & failing too silently

Opened this issue · 6 comments

Hello! Thank you for your efforts with the library.
I am trying to run it on a Raspberry Pi 3 (Raspbian GNU/Linux 8 (jessie)), and it is impossible to make it work without sudo. To narrow down the issue for you, here is what I am talking about:

pi@raspberrypi:~/node_modules/rc522 $ node rc522_output.js
bcm2835_init: Unable to open /dev/mem: Permission denied
Segmentation fault

It works with sudo though, and reads the RFID tags properly. It seems that your library still tries to access /dev/mem even when it's not running under root. This fault seems to contradict this excerpt from your documentation:

Prior to the release of Raspbian Jessie in Feb 2016, access to any peripheral device via /dev/mem on the RPi required the process to run as root. Raspbian Jessie permits non-root users to access the GPIO peripheral (only) via /dev/gpiomem, and this library supports that limited mode of operation.

If the library runs with effective UID of 0 (ie root), then bcm2835_init() will attempt to open /dev/mem, and, if successful, it will permit use of all peripherals and library functions.

If the library runs with any other effective UID (ie not root), then bcm2835_init() will attempt to open /dev/gpiomem, and, if successful, will only permit GPIO operations. In particular, bcm2835_spi_begin() and bcm2835_i2c_begin() will return false and all other non-gpio operations may fail silently or crash.

My permissions to the devices are below:

pi@raspberrypi:~/node_modules/rc522 $ ls -lat /dev/mem
crw-r----- 1 root kmem 1, 1 Oct 11 16:20 /dev/mem
pi@raspberrypi:~/node_modules/rc522 $ ls -lat /dev/gpio*
crw-rw---- 1 root gpio 244, 0 Oct 11 16:20 /dev/gpiomem

It is imperative that sudo is not used in our application, because we are calling this library from Node-RED framework, which cannot properly terminate processes launched with sudo. Please, let me know if there is anything immediate that can be done about this, as my school project depends on this library functioning properly.

Another issue with the library is that everything fails silently. For instance, when we launch
pi@raspberrypi:~/node_modules/rc522 $ node main.js
there are no error messages passed to the console from the child processes... The proper handling of error messages would be most helpful.

Thank you.

Also, the user PI belongs to the group gpio:

pi@raspberrypi:~/node_modules/rc522 $ groups pi
pi : pi gpio

@mitchellparsons have you got any idea about this?

I'm sorry, but at the moment I don't have solution to this.

The silent failing should be fixed by pr #5.
The other problem seems to be due to bcm2835_init not using the right file - contrary to what is stated in its documentation (and also here). So this is actually coming from Mike McCauley's C library and not related to this library.

The problem is probably around line 1337 in mikem's bcm28335 driver (which seems to be only available as tar file from his homepage):

    /* Now get ready to map the peripherals block 
     * If we are not root, try for the new /dev/gpiomem interface and accept
     * the fact that we can only access GPIO
     * else try for the /dev/mem interface and get access to everything
     */
    memfd = -1;
    ok = 0;
    if (geteuid() == 0)
    {
      /* Open the master /dev/mem device */
      if ((memfd = open("/dev/mem", O_RDWR | O_SYNC) ) < 0) 
    {
      fprintf(stderr, "bcm2835_init: Unable to open /dev/mem: %s\n",
          strerror(errno)) ;
      goto exit;
    }

Have you checked what geteuid() returns on your system (i.e. runecho $EUID $UID in a shell)?

...from Stackoverflow on how to check if the user is root:

Usually it's a mistake to test if the user is root. POSIX does not even require a root user, but leaves it to the implementation to determine how permissions work. [...]
Instead, you should always attempt the privileged operation you need to perform, and check for EPERM or similar if it fails to notify the user that they have insufficient privileges (and perhaps should retry running as root).

So instead of goto exit; it should go to the alternative branch using /dev/gpiomem and try again. Maybe you can contact Mike McCauley with a patch for your problem. ;)
(and sorry for posting my whole train of thought in separate comments here)