lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:   Wed, 27 Jul 2022 10:21:07 -0500
From:   "Eric W. Biederman" <ebiederm@...ssion.com>
To:     wangboshi <wangboshi@...wei.com>
Cc:     "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
        "Qinchao(OS Kernel Lab)" <qinchao15@...wei.com>,
        "Likun(OSLab)" <hw.likun@...wei.com>,
        <linux-fsdevel@...r.kernel.org>
Subject: Re: fs: An unexpected ACL pass


Adding fsdevel where some of the people involved in the implementation
might see the question.

wangboshi <wangboshi@...wei.com> writes:

> Hi, everyone.
>
> We want to talk about a detail about ACL. In `acl_permission_check` function, when file modes don't contain any group permissions, the ACL check is bypassed. 
> ```
> static int acl_permission_check(struct user_namespace *mnt_userns,
> 				struct inode *inode, int mask)
> {
> 	unsigned int mode = inode->i_mode;
> 	kuid_t i_uid;
>
> 	/* Are we the owner? If so, ACL's don't matter */
> 	i_uid = i_uid_into_mnt(mnt_userns, inode);
> 	if (likely(uid_eq(current_fsuid(), i_uid))) {
> 		mask &= 7;
> 		mode >>= 6;
> 		return (mask & ~mode) ? -EACCES : 0;
> 	}
>
> 	/* Do we have ACL's? */
> 	if (IS_POSIXACL(inode) && (mode & S_IRWXG)) {
> 		int error = check_acl(mnt_userns, inode, mask);
> 		if (error != -EAGAIN)
> 			return error;
> 	}
>
> 	/* Only RWX matters for group/other mode bits */
> 	mask &= 7;
>
> 	/*
> 	 * Are the group permissions different from
> 	 * the other permissions in the bits we care
> 	 * about? Need to check group ownership if so.
> 	 */
> 	if (mask & (mode ^ (mode >> 3))) {
> 		kgid_t kgid = i_gid_into_mnt(mnt_userns, inode);
> 		if (in_group_p(kgid))
> 			mode >>= 3;
> 	}
>
> 	/* Bits in 'mode' clear that we require? */
> 	return (mask & ~mode) ? -EACCES : 0;
> }
> ```
> It causes that users or groups can get permissions by the other-permission bits even if ACL explicitly restricts that they have no permission.
> For example, we(1000) create a file and set its ACLs which give owner, user(2000), group(3000) and other all permissions with no mask permissions.
> ```
> $ echo data > test
> $ setfacl -m u::rwx,g::rwx,u:2000:rwx,g:3000:rwx,m::-,o:rwx test
> $ getfacl test
> # file: test
> # owner: 1000
> # group: 1000
> user::rwx
> user:2000:rwx                   #effective:---
> group::rwx                      #effective:---
> group:3000:rwx                  #effective:---
> mask::---
> other::rwx
> ```
> Let user(2000) and group(3000) access the file.
> ```
> $ sudo capsh --gid=2000 --uid=2000 -- -c 'cat test'
> data
> $ sudo capsh --gid=3000 --uid=3000 -- -c 'cat test'
> data
> ```
> We can see these successful accesses. It is unexpected. In contrast, according to the ACL access check algorithm described in POSIX 1003.1e draft 17 23.1.5 section, accesses should be denied, because user(2000) and group(3000) are explicitly specified by us and we restrict the permission of the specific users and groups via no mask permissions. And the getfacl tool tells us that all effective permissions of user(1000), group(3000) and owner group contain nothing too.
>
> What's more, if we add x permission to mask permissions, read accesses are denied. It's counterintuitive that we can do something with no permission and are denied with more other permissions.
>
> We want to trace the original of the design. We find similar implementations in earlier version where ext2 ACL was introduced. The design looks like an optimization, but it should base on an assumption that there is no other-permissions if no group-permissions. Is the assumption always valid?

Eric

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ