/dev/hidraw: read permissions

devicesudev

What do I need to do to have read permissions on /dev/hidraw*?

I'm seeing stuff about udev rules and saw this on the net, but the world of udev is like a foreign land to me, and if there's some sort of a simpler solution where I just add myself to a group that'd be dandy…

(Ubuntu 13.10 Preview)

Feel free to retag the question – I'm not too keen on what 'hidraw' exactly goes under.

EDIT:

H'okay, so, just some more information to clarify the issue:
I literally stepped through code that called the POSIX open() method, and got the errno for insufficient permissions. Running cat on the file as a normal user results in an insufficient permissions error, while running under su results in a successful (albeit meaningless) cat operation.

EDIT EDIT:

At request, I'm providing the relevant code with POSIX call. It's from the HIDAPI library by Signal11 (function hid_open_path). I trust that this code is correct, as it has apparently been in use for quite some time now. I've added a comment located where the relevant errno reading took place in GDB.

hid_device *dev = NULL;

hid_init();

dev = new_hid_device();

if (kernel_version == 0) {
    struct utsname name;
    int major, minor, release;
    int ret;
    uname(&name);
    ret = sscanf(name.release, "%d.%d.%d", &major, &minor, &release);
    if (ret == 3) {
        kernel_version = major << 16 | minor << 8 | release;
        //printf("Kernel Version: %d\n", kernel_version);
    }
    else {
        printf("Couldn't sscanf() version string %s\n", name.release);
    }
}

/* OPEN HERE */
dev->device_handle = open(path, O_RDWR);

// errno at this location is 13: insufficient permissions

/* If we have a good handle, return it. */
if (dev->device_handle > 0) {

    /* Get the report descriptor */
    int res, desc_size = 0;
    struct hidraw_report_descriptor rpt_desc;

    memset(&rpt_desc, 0x0, sizeof(rpt_desc));

    /* Get Report Descriptor Size */
    res = ioctl(dev->device_handle, HIDIOCGRDESCSIZE, &desc_size);
    if (res < 0)
        perror("HIDIOCGRDESCSIZE");


    /* Get Report Descriptor */
    rpt_desc.size = desc_size;
    res = ioctl(dev->device_handle, HIDIOCGRDESC, &rpt_desc);
    if (res < 0) {
        perror("HIDIOCGRDESC");
    } else {
        /* Determine if this device uses numbered reports. */
        dev->uses_numbered_reports =
            uses_numbered_reports(rpt_desc.value,
                                  rpt_desc.size);
    }

    return dev;
}
else {
    /* Unable to open any devices. */
    free(dev);
    return NULL;
}

Best Answer

I gave up running around trying to figure out some other means of doing it than udev rules, and instead just learned a bit about udev and wrote a flippin' rule. The following line was placed in a .rules file (I named mine 99-hidraw-permissions.rules) located under /etc/udev/rules.d.

KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0664", GROUP="plugdev"

Basically this assigns all devices coming out of the hidraw subsystem in the kernel to the group plugdev and sets the permissions to r/w r/w r (for root [the default owner], plugdev, and everyone else respectively). With myself added to the plugdev group, everything's dandy.

Not quite as brain melting as I'd expected. Udev rules actually seem pretty straightforward... I mean, they look like they can get ridiculous if you're dealing with individual product IDs and whatnot, but they seem pretty damn tame for what they do.

Related Question