Why the access check algorithm from "man acl" does not correspond to the actual differentiation of rights?

2

In man acl says:

2.   else if the effective user ID of the process matches the qualifier of any entry of type ACL_USER, then
              if the matching ACL_USER entry and the ACL_MASK entry contain the requested permissions, access is granted,
              else access is denied.

As I'm understand, if exist entry ACL_USER for user, then access granted or denied corresponding this entry, and algorithm end.

Create a file and assign it access rights::

echo "echo 123" > /file1
chmod 005 file1
setfacl -m u:test1:--- /file1
chown usertest:root /file1

and get

userc@client:~$ getfacl /file1
getfacl: Removing leading '/' from absolute path names
# file: file1
# owner: usertest
# group: root
user::---
user:test1:---
group::---
mask::---
other::r-x

If I understand the algorithm correctly, access for executing and reading is allowed to everyone except usertest and test1, but auth to test1 and execute file:

test1@client:~$ sh /file1
123

i.e. get access rights from others

Why entry ACL_USER for user 'test1' not deny access for test1?

p.s. drive mounted with 'acl'

magrif

Posted 2018-09-10T11:32:39.760

Reputation: 135

Answers

2

In this case, because ACL_MASK contains no bits at all (and therefore the ACL cannot grant any permissions), the Linux kernel skips ACL checking entirely. The operation falls through to just checking the "other" permission bits (which allow the access).

This might be a bug that was introduced in the 2004 "generic ACL support" rewrite (commit 42017c2e in tglx/history, dc4ceab7 in unified). You can see it in the acl_permission_check() function in fs/namei.c (note that the 'mask' variable does not refer to ACL_MASK, but to the desired access bits):

static int acl_permission_check(struct inode *inode, int mask)
{
    unsigned int mode = inode->i_mode;

    if (likely(uid_eq(current_fsuid(), inode->i_uid)))
        ...
    else {
        if (IS_POSIXACL(inode) && (mode & S_IRWXG)) {
            int error = check_acl(inode, mask);
            if (error != -EAGAIN)
                return error;
        }
        ...

As a side note: When you use sh /file1, only the +r permission applies to file1, because you're not asking the kernel to execute the file – you're executing only sh.

user1686

Posted 2018-09-10T11:32:39.760

Reputation: 283 655

Is there a C interface for checking the actual access rights to the FS resource for the user (include the ACL)? – magrif – 2018-09-10T12:48:40.137

1

@magrif: There's the access() syscall to verify whether you have specific effective rights – it considers permissions, ACLs, root privilege, and CAP_DAC_OVERRIDE. (I don't know whether it includes LSMs such as SELinux, however, but it should.)

– user1686 – 2018-09-10T12:50:21.123

exist some like access(user, resurce), i.e. not for calling process? (sudo -u <user> [ -x /path/to/res ] don't want use). – magrif – 2018-09-10T13:02:58.937

1If you're doing it in C and have root, then you might use setfsuid() and initgroups() before checking the permissions, then change back. But remember that file access can depend on various environment factors. Even [ -x path ] actually calls access() behind the scenes. – user1686 – 2018-09-10T13:25:16.880