2

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:

__ATTR(status_vector,0660,status_vector_is_read,status_vector_is_written);

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?

J Amos
  • 23

1 Answers1

3

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) +                                \
     /* USER_READABLE >= GROUP_READABLE >= OTHER_READABLE */            \
     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) +                                   \
     (perms))

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

Andy Dalton
  • 13,993
  • 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 03: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