Reputation: 11
I am interested in /proc/sys
and trying to understand the access control mechanism of files in this directory.
I am not sure if accessing /proc/sys
is the same as accessing on-disk file systems, like ext4. So I just started with the open
system call and tried to trace critical kernel functions called among the process.
And found that it first called do_sys_open()
, which called do_filp_open()
internally. In do_filp_open()
, some path name resolution is done at first and then it called may_open()
to do some permission checks, and finally vfs_open()
is called to do the specific open function according to the file system.
From reading the source code, I suppose the permission check work is indeed done by generic_permission()
which located in /fs/namei.c. The whole function looks like this:
int generic_permission(struct inode *inode, int mask)
{
int ret;
/*
* Do the basic permission checks.
*/
ret = acl_permission_check(inode, mask);
if (ret != -EACCES)
return ret;
if (S_ISDIR(inode->i_mode)) {
/* DACs are overridable for directories */
if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
return 0;
if (!(mask & MAY_WRITE))
if (capable_wrt_inode_uidgid(inode,
CAP_DAC_READ_SEARCH))
return 0;
return -EACCES;
}
/*
* Read/write DACs are always overridable.
* Executable DACs are overridable when there is
* at least one exec bit set.
*/
if (!(mask & MAY_EXEC) || (inode->i_mode & S_IXUGO))
if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
return 0;
/*
* Searching includes executable on directories, else just read.
*/
mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
if (mask == MAY_READ)
if (capable_wrt_inode_uidgid(inode, CAP_DAC_READ_SEARCH))
return 0;
return -EACCES;
}
So, it seems like UGO check comes at first, if UGO failed kernel will check if you have special Capability. But this process is not consistent with the experiment result I saw when I tried access files under /proc/sys.
Take /proc/sys/kernel/usermodehelper/bset as an example:
$ ll /proc/sys/kernel/usermodehelper/bset
-rw------- 1 root root 0 Nov 6 12:15 /proc/sys/kernel/usermodehelper/bset
This file is owned by root and can’t be read from others. From the logic in generic_permission(), non-root could read this file if he has CAP_DAC_OVERRIDE. So I give /bin/cat
CAP_DAC_OVERRIDE, but got an “Permission denied” and still cannot read the file.
However, I could read /etc/shadow
after grand CAP_DAC_OVERRIDE to cat
, which is also a root file and can't be read by a normal user.
Why did this happen?What is the permission check process like when accessing files under /proc/sys
? Doesn’t it go through generic_permission()
? Is there some other check in kernel when accessing /proc/sys
?
Upvotes: 1
Views: 928