I want to write a driver to pass some info to a device, and to do so I've made a sysfs entry. It works fine, but the problem is that I don't have the permissions to write to it unless I am logged in as admin. I'd like it to have open read and write permissions.

The way I was advised to write the driver, I used the following macro to set up the sysfs attribute:


The problem is obvious, I've used 660 as the permission instead of 666.

However, when I try putting the permission as 666, or using the defined S_IWUGO | S_IRUGO, I get an error. I am able to set open read permissions, but not write. Apparently this person had the same problem, but I don't see any answer given on that thread.

I could always just set the permissions using chmod, but that seems clunky and annoying of a solution, Id rather learn how to actually write a driver properly. Why am I not allowed to set S_IWUGO?


The __ATTR macro expands to the following [1]:

#define __ATTR(_name, _mode, _show, _store) {   \
    .attr = {.name = __stringify(_name),        \
    .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },  \
    .show   = _show,                            \
    .store  = _store,                           \

Note the use of the macro VERIFY_OCTAL_PERMISSIONS. That macro expands to the following [2]:

#define VERIFY_OCTAL_PERMISSIONS(perms)                                 \
    (BUILD_BUG_ON_ZERO((perms) < 0) +                                   \
     BUILD_BUG_ON_ZERO((perms) > 0777) +                                \
     BUILD_BUG_ON_ZERO((((perms) >> 6) & 4) < (((perms) >> 3) & 4)) +   \
     BUILD_BUG_ON_ZERO((((perms) >> 3) & 4) < ((perms) & 4)) +          \
     /* USER_WRITABLE >= GROUP_WRITABLE */                              \
     BUILD_BUG_ON_ZERO((((perms) >> 6) & 2) < (((perms) >> 3) & 2)) +   \
     /* OTHER_WRITABLE?  Generally considered a bad idea. */            \
     BUILD_BUG_ON_ZERO((perms) & 2) +                                   \

What version of BUILD_BUG_ON_ZERO you get depends on a macro that I didn't track down, but you should note the comment in the above macro: "OTHER_WRITABLE? Generally considered a bad idea".

Although I didn't trace the call path, my guess is that the code filters/ignores o+w.

All that said, why would you want a non-privileged user to be able to interact directly with a piece of hardware?

[1] http://elixir.free-electrons.com/linux/v4.14/source/include/linux/sysfs.h#L101

[2] http://elixir.free-electrons.com/linux/v4.14/source/include/linux/kernel.h#L940

  • That does seem to be present in my kernel sources, so I imagine that is the, or at least a, problem. So this seems to just be there...for no reason? Anyway the processor I am using is actually an SoC, and I want components in the FPGA fabric to be available to the userspace. – J Amos Nov 14 '17 at 3:29
  • I've the same problem, but found on another thread a potential solution to just redefine VERIFY_OCTAL_PERMISSIONS to ignore the last BUILD_BUG error. Problem is, even if you get past this error message, somewhere in the build process there's something else that ALSO prevents it, so you'll get a compiled kernel module, but when you insert it, it still wont assign write privilege. If anyone knows how to get around that, please respond. – Zephyr Nov 14 '17 at 14:06
  • Or, consider that the people who wrote this code knew what they were doing when they blocked o+w and reconsider your design. In the very worst case, you could introduce a simple suid root program that non-privileged users could use to write the file. – Andy Dalton Nov 14 '17 at 14:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.