https://bugzilla.suse.com/show_bug.cgi?id=1177499
Bug ID: 1177499 Summary: prctl test fails on Tumbleweed Classification: openSUSE Product: openSUSE Tumbleweed Version: Current Hardware: Other OS: Other Status: NEW Severity: Normal Priority: P5 - None Component: Kernel Assignee: kernel-bugs@opensuse.org Reporter: msuchanek@suse.com QA Contact: qa-bugs@suse.de Found By: --- Blocker: ---
https://build.opensuse.org/package/live_build_log/home:michals/python-python...
@require('get_no_new_privs') def test_no_new_privs(self): """Test the no_new_privs function""" self.assertEqual(prctl.get_no_new_privs(), 0) pid = os.fork() if pid: self.assertEqual(os.waitpid(pid, 0)[1], 0) else: prctl.set_no_new_privs(1) self.assertEqual(prctl.get_no_new_privs(), 1) if os.geteuid() != 0: sp = subprocess.Popen(['ping', '-c1', 'localhost'], stderr=subprocess.PIPE) sp.communicate() self.assertNotEqual(sp.returncode, 0) os._exit(0)
It assumes that by default you cannot ping, and PR_SET_NO_NEW_PRIVS is inherited across fork.
Has there been some change in the capabilities recently?
https://bugzilla.suse.com/show_bug.cgi?id=1177499 https://bugzilla.suse.com/show_bug.cgi?id=1177499#c1
--- Comment #1 from Michal Suchanek msuchanek@suse.com --- Changed the code to this:
@require('get_no_new_privs') def test_no_new_privs(self): """Test the no_new_privs function""" self.assertEqual(prctl.get_no_new_privs(), 0) pid = os.fork() if pid: self.assertEqual(os.waitpid(pid, 0)[1], 0) else: prctl.set_no_new_privs(1) self.assertEqual(prctl.get_no_new_privs(), 1) os._exit(0) if os.geteuid() != 0: pid = os.fork() if pid:
self.assertiNotEqual(os.waitpid(pid, 0)[1], 0)
else: prctl.set_no_new_privs(1) os.execvp('ping',['ping', '-c1', 'localhost']) os._exit(0)
and the indicated assert fails. So either ping no longer needs privileges or the PR_SET_NO_NEW_PRIVS stopped working.
https://bugzilla.suse.com/show_bug.cgi?id=1177499 https://bugzilla.suse.com/show_bug.cgi?id=1177499#c2
--- Comment #2 from Michal Suchanek msuchanek@suse.com --- :~/home:michals/python-python-prctl> cp /usr/bin/ping . :~/home:michals/python-python-prctl> ./ping -c1 localhost PING localhost(localhost (::1)) 56 data bytes 64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.072 ms
--- localhost ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.072/0.072/0.072/0.000 ms
so indeed ping is the wrong test - it no longer needs any special capability.
https://bugzilla.suse.com/show_bug.cgi?id=1177499 https://bugzilla.suse.com/show_bug.cgi?id=1177499#c3
--- Comment #3 from Michal Suchanek msuchanek@suse.com --- ~/home:michals/python-python-prctl> rm ping ~/home:michals/python-python-prctl> cat /usr/bin/ping > ping ./ping -c1 localhost bash: ./ping: Permission denied
So cp copies the capability settings but cat creates a new file which does not have any capability settings and that does not work anymore.
-> looks like PR_SET_NO_NEW_PRIVS is broken on Tumbleweed kernel
https://bugzilla.suse.com/show_bug.cgi?id=1177499 https://bugzilla.suse.com/show_bug.cgi?id=1177499#c4
Anthony Iliopoulos ailiopoulos@suse.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |ailiopoulos@suse.com
--- Comment #4 from Anthony Iliopoulos ailiopoulos@suse.com --- PR_SET_NO_NEW_PRIVS works fine, but ping indeed doesn't need any special capabilities anymore, so the test fails.
This has been actually possible for a long time, since commit c319b4d76b9e ("net: ipv4: add IPPROTO_ICMP socket kind"), but it was restricted by default (see commit msg for details, basically /proc/sys/net/ipv4/ping_group_range needs to allow uid ranges).
This seems to have been changed recently in TW to allow this to all users:
/usr/lib/sysctl.d/50-default.conf:net.ipv4.ping_group_range = 0 2147483647
rpm -qf /usr/lib/sysctl.d/50-default.conf aaa_base-84.87+git20200918.331aa2f-1.1.x86_64
Wed Sep 9 06:51:29 UTC 2020 - Ludwig Nussel lnussel@suse.de * sysctl.d/50-default.conf: allow everybody to create IPPROTO_ICMP sockets (bsc#1174504)
https://bugzilla.suse.com/show_bug.cgi?id=1177499 https://bugzilla.suse.com/show_bug.cgi?id=1177499#c5
--- Comment #5 from Michal Suchanek msuchanek@suse.com --- Replacing the command with dumpcap from wireshark does not work either - the test fails with EPERM
'dumpcap', '-i', 'lo', '-a', 'duration:1'
https://bugzilla.suse.com/show_bug.cgi?id=1177499 https://bugzilla.suse.com/show_bug.cgi?id=1177499#c6
--- Comment #6 from Anthony Iliopoulos ailiopoulos@suse.com --- (In reply to Michal Suchanek from comment #5)
Replacing the command with dumpcap from wireshark does not work either - the test fails with EPERM
'dumpcap', '-i', 'lo', '-a', 'duration:1'
that's because dumpcap is by default installed with 0750/-rwxr-x--- perms, and I presume the test user doesn't belong to the "wireshark" group.
you can try to reproduce the ping issue to confirm that the prctl is functioning as expected:
# restrict unprivileged icmp socket creation echo 1 0 | sudo tee /proc/sys/net/ipv4/ping_group_range
dev@localhost:~> ping -c1 localhost PING localhost(localhost (::1)) 56 data bytes 64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.049 ms
--- localhost ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.049/0.049/0.049/0.000 ms
dev@localhost:~> setpriv --nnp ping -c1 localhost ping: socket: Operation not permitted
Anyway, I'd assume that relying on a package binary that is expected to have filecaps may not be the most reliable method for testing this.
It's probably best to have a test.c that prints its own cap bits (via libcap), that gets compiled and has some cap bits set on it (which is a problem I suppose since it requires root), or just make this binary into an rpm package as a dependency.
https://bugzilla.suse.com/show_bug.cgi?id=1177499 https://bugzilla.suse.com/show_bug.cgi?id=1177499#c7
Miroslav Bene�� mbenes@suse.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |mbenes@suse.com
--- Comment #7 from Miroslav Bene�� mbenes@suse.com --- Michal, has there been any follow-up on this?
https://bugzilla.suse.com/show_bug.cgi?id=1177499 https://bugzilla.suse.com/show_bug.cgi?id=1177499#c8
--- Comment #8 from Michal Suchanek msuchanek@suse.com --- Read the previous comment: everything works as designed but there is no reasonable way to test this in our build environment.
At best we could probably create a test package that contains a binary which is installed with some capabilities and fails when the capabilities are missing.
https://bugzilla.suse.com/show_bug.cgi?id=1177499 https://bugzilla.suse.com/show_bug.cgi?id=1177499#c9
Miroslav Bene�� mbenes@suse.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution|--- |INVALID
--- Comment #9 from Miroslav Bene�� mbenes@suse.com --- (In reply to Michal Suchanek from comment #8)
Read the previous comment: everything works as designed but there is no reasonable way to test this in our build environment.
I did and that is why I asked about...
At best we could probably create a test package that contains a binary which is installed with some capabilities and fails when the capabilities are missing.
...something like this. Or what Anthony proposed.
Anyway, you are right that there is nothing to fix here, so let me close.
kernel-bugs@lists.opensuse.org