Bug 2270895 - avc denial create while running stress-ng
Summary: avc denial create while running stress-ng
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: selinux-policy
Version: rawhide
Hardware: Unspecified
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Zdenek Pytela
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2024-03-22 02:23 UTC by Yulia Kopkova
Modified: 2024-09-02 14:28 UTC (History)
9 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2024-09-02 14:28:25 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)
Short program testing that memfd_create() works as expected (866 bytes, text/x-csrc)
2024-05-10 10:18 UTC, Juraj Marcin
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Github fedora-selinux selinux-policy pull 2107 0 None Merged Add support for secretmem anon inode 2024-05-09 19:41:42 UTC

Description Yulia Kopkova 2024-03-22 02:23:16 UTC
I'm getting avc denial create message while running stress-ng
stress-ng --resources 16 --timeout 5 --log-file resources.log

Looks like stress-ng attempts to create anonymous inodes:
#if defined(O_TMPFILE)
		resources[i].fd_tmp = open("/tmp", O_TMPFILE | O_RDWR,
				      S_IRUSR | S_IWUSR);
		if (!stress_continue_flag())
			break;
		if (resources[i].fd_tmp != -1) {
			(void)shim_fallocate(resources[i].fd_tmp, 0, 0, (off_t)page_size);

SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   permissive
Mode from config file:          permissive
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy version:      33
selinux-policy-40.15-1.fc41.noarch
----
time->Thu Mar 21 14:13:36 2024
type=AVC msg=audit(1711044816.431:694): avc:  denied  { create } for  pid=90746 comm="stress-ng" anonclass=[secretmem] scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:unconfined_t:s0 tclass=anon_inode permissive=1

Not sure if this is not allowed by the policy design.

Reproducible: Always

Comment 1 Milos Malik 2024-03-27 06:57:12 UTC
The following SELinux denial appears many times in enforcing mode:
----
type=PROCTITLE msg=audit(03/27/2024 02:54:00.035:4382) : proctitle=stress-ng-resources [run] 
type=SYSCALL msg=audit(03/27/2024 02:54:00.035:4382) : arch=x86_64 syscall=memfd_secret success=no exit=EACCES(Permission denied) a0=0x0 a1=0x0 a2=0x0 a3=0x0 items=0 ppid=2072 pid=5294 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=4 comm=stress-ng-resou exe=/usr/bin/stress-ng subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null) 
type=AVC msg=audit(03/27/2024 02:54:00.035:4382) : avc:  denied  { create } for  pid=5294 comm=stress-ng-resou anonclass=[secretmem] scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:unconfined_t:s0 tclass=anon_inode permissive=0 
----

The following SELinux denial appears in permissive mode:
----
type=PROCTITLE msg=audit(03/27/2024 02:55:33.937:4389) : proctitle=stress-ng-resources [run] 
type=SYSCALL msg=audit(03/27/2024 02:55:33.937:4389) : arch=x86_64 syscall=memfd_secret success=yes exit=10 a0=0x0 a1=0x0 a2=0x7fa616382897 a3=0x9 items=0 ppid=7242 pid=7253 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=4 comm=stress-ng-resou exe=/usr/bin/stress-ng subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null) 
type=AVC msg=audit(03/27/2024 02:55:33.937:4389) : avc:  denied  { create } for  pid=7253 comm=stress-ng-resou anonclass=[secretmem] scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:unconfined_t:s0 tclass=anon_inode permissive=1 
----

# rpm -qa selinux\* stress\* | sort
selinux-policy-40.15-1.fc41.noarch
selinux-policy-targeted-40.15-1.fc41.noarch
stress-ng-0.17.03-2.fc40.x86_64
#

Comment 2 Milos Malik 2024-03-27 12:27:48 UTC
Test coverage for this bug exists in a form of PR:
 * https://src.fedoraproject.org/tests/selinux/pull-request/484

The PR waits for a review.

Comment 3 Zdenek Pytela 2024-04-26 09:02:18 UTC
Juraj,

stress is known for doing nasty things. Do you think this permission should be allowed?

Comment 4 Juraj Marcin 2024-04-30 11:50:55 UTC
(In reply to Zdenek Pytela from comment #3)
> Juraj,
> 
> stress is known for doing nasty things. Do you think this permission should
> be allowed?

This AVC is triggered by calling memfd_secret() syscall here[1]. This syscall creates an anonymous RAM-based file that nobody else should have access to, except the process holding the file descriptor.

I think this should be allowed (at least for the unconfined domain under which stress is running). In fact, it was previously allowed for any domain due to a workaround for anon inode support, but when the proper support was implemented in this commit[2], support for secretmem anon_inode type was not added.

I can try to implement a fix with new type for secretmem anon_inode similarly how userfaultfd is handled.


[1]: https://github.com/ColinIanKing/stress-ng/blob/V0.17.03/core-shim.c#L2370
[2]: https://github.com/fedora-selinux/selinux-policy/commit/65b9e0bdceb7e6adbe308f9a591b103cba6986ef

Comment 5 Juraj Marcin 2024-05-03 07:55:44 UTC
PR: https://github.com/fedora-selinux/selinux-policy/pull/2107
Copr build: https://copr.fedorainfracloud.org/coprs/jmarcin/selinux-policy-testing/build/7399165/

Steps to install:
dnf copr enable jmarcin/selinux-policy-testing
dnf install selinux-policy-40.17-1.fc41.20240502.bz2270895_secretmem1


I have added a new type for the secretmem anon inode, so this type of inode always has secretmem_t type. Additionally I allowed unconfined_domain_type to create it.

There are no AVCs when I tested with stress-ng or with my own short program using the memfd_secret() syscall and the returned descriptor.

Comment 6 Juraj Marcin 2024-05-10 10:18:58 UTC
Created attachment 2032491 [details]
Short program testing that memfd_create() works as expected

Comment 7 Zdenek Pytela 2024-05-10 13:45:05 UTC
Should it be allowed to some of confined users, too?

----
type=PROCTITLE msg=audit(10.5.2024 15:38:40.051:739) : proctitle=./secretmem_test
type=SYSCALL msg=audit(10.5.2024 15:38:40.051:739) : arch=x86_64 syscall=memfd_secret success=yes exit=3 a0=0x0 a1=0x7ffc530584d8 a2=0x403e00 a3=0x0 items=0 ppid=6202 pid=79065 aui
d=username uid=username gid=username euid=username suid=username fsuid=username egid=username sgid=username fsgid=username tty=pts3 ses=3 comm=secretmem_test exe=secretmem_test subj=staff_u:staff_r:staff_t:s0-s0:c0.c1023 key=(null) 
type=AVC msg=audit(10.5.2024 15:38:40.051:739) : avc:  denied  { create } for  pid=79065 comm=secretmem_test anonclass=[secretmem] scontext=staff_u:staff_r:staff_t:s0-s0:c0.c1023 tcontext=staff_u:object_r:staff_t:s0 tclass=anon_inode permissive=1

Comment 8 Juraj Marcin 2024-05-27 09:15:01 UTC
(In reply to Zdenek Pytela from comment #7)
> Should it be allowed to some of confined users, too?
> 
> ----
> type=PROCTITLE msg=audit(10.5.2024 15:38:40.051:739) :
> proctitle=./secretmem_test
> type=SYSCALL msg=audit(10.5.2024 15:38:40.051:739) : arch=x86_64
> syscall=memfd_secret success=yes exit=3 a0=0x0 a1=0x7ffc530584d8 a2=0x403e00
> a3=0x0 items=0 ppid=6202 pid=79065 aui
> d=username uid=username gid=username euid=username suid=username
> fsuid=username egid=username sgid=username fsgid=username tty=pts3 ses=3
> comm=secretmem_test exe=secretmem_test
> subj=staff_u:staff_r:staff_t:s0-s0:c0.c1023 key=(null) 
> type=AVC msg=audit(10.5.2024 15:38:40.051:739) : avc:  denied  { create }
> for  pid=79065 comm=secretmem_test anonclass=[secretmem]
> scontext=staff_u:staff_r:staff_t:s0-s0:c0.c1023
> tcontext=staff_u:object_r:staff_t:s0 tclass=anon_inode permissive=1

It makes sense to allow also for some confined users, as it is just memory allocation with some extra security. However, it would probably be better to start with sysadm and then add other confined users if needed. Pages allocated with this method can never be swapped out of the physical memory, and the system hibernation is blocked as long as any file descriptor created with this method exists.

Comment 9 Zdenek Pytela 2024-05-27 14:43:26 UTC
Seems I did not think through it enough: user domains are also a part of the domain attribute, so the transition actually is defined also for all users, but usage (create) for the transitioned type is not. That was the original intention?
So you suggest now only kernel_secretmem_use(sysadm_t) or kernel_secretmem_use(confined_admindomain)?

Comment 10 Juraj Marcin 2024-05-27 14:55:09 UTC
(In reply to Zdenek Pytela from comment #9)
> Seems I did not think through it enough: user domains are also a part of the
> domain attribute, so the transition actually is defined also for all users,
> but usage (create) for the transitioned type is not. That was the original
> intention?

Yes, it is same as for userfaultfd and io_uring anon inodes. The transition is necessary, so the created object always has the correct type regardless of the creator (even if usage is not allowed).

> So you suggest now only kernel_secretmem_use(sysadm_t) or
> kernel_secretmem_use(confined_admindomain)?

Yes, I think it would be a safer option now, given it could obstruct some normal behavior (hibernation) and only allow once some application required by non-admin domain needs it. Or you think non-admin confined domains should be able to run stress (I am not currently aware of any other application using it)? Maybe also Ondrej could provide some insight.


Note You need to log in before you can comment on or make changes to this bug.