Losing permissions by adding capability?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
6
down vote

favorite
2












I observed the following phenomenon that I can not explain. After adding the CAP_SYS_ADMIN capability, unshare is no longer able to write to /proc/self/setgroups.



In fact, writing to this file requires the capability, but that is achieved by changing the user namespace. So why does adding the capability to the parent process prevents writing to this file?



me@myhost:~$ unshare -r
root@myhost:~# exit
logout

me@myhost:~$ sudo setcap cap_sys_admin=ep /usr/bin/unshare
me@myhost:~$ unshare -r
unshare: cannot open /proc/self/setgroups: Permission denied

me@myhost:~$ sudo setcap cap_sys_admin= /usr/bin/unshare
me@myhost:~$ unshare -r
root@myhost:~#


By the way: I am running Ubuntu 16.04.4 LTS with kernel version 4.4 and the version of util-linux (including unshare) is 2.27.1.







share|improve this question





















  • Related questions are unix.stackexchange.com/questions/133922 , unix.stackexchange.com/questions/364568 , and unix.stackexchange.com/questions/75045 .
    – JdeBP
    Aug 1 at 15:52
















up vote
6
down vote

favorite
2












I observed the following phenomenon that I can not explain. After adding the CAP_SYS_ADMIN capability, unshare is no longer able to write to /proc/self/setgroups.



In fact, writing to this file requires the capability, but that is achieved by changing the user namespace. So why does adding the capability to the parent process prevents writing to this file?



me@myhost:~$ unshare -r
root@myhost:~# exit
logout

me@myhost:~$ sudo setcap cap_sys_admin=ep /usr/bin/unshare
me@myhost:~$ unshare -r
unshare: cannot open /proc/self/setgroups: Permission denied

me@myhost:~$ sudo setcap cap_sys_admin= /usr/bin/unshare
me@myhost:~$ unshare -r
root@myhost:~#


By the way: I am running Ubuntu 16.04.4 LTS with kernel version 4.4 and the version of util-linux (including unshare) is 2.27.1.







share|improve this question





















  • Related questions are unix.stackexchange.com/questions/133922 , unix.stackexchange.com/questions/364568 , and unix.stackexchange.com/questions/75045 .
    – JdeBP
    Aug 1 at 15:52












up vote
6
down vote

favorite
2









up vote
6
down vote

favorite
2






2





I observed the following phenomenon that I can not explain. After adding the CAP_SYS_ADMIN capability, unshare is no longer able to write to /proc/self/setgroups.



In fact, writing to this file requires the capability, but that is achieved by changing the user namespace. So why does adding the capability to the parent process prevents writing to this file?



me@myhost:~$ unshare -r
root@myhost:~# exit
logout

me@myhost:~$ sudo setcap cap_sys_admin=ep /usr/bin/unshare
me@myhost:~$ unshare -r
unshare: cannot open /proc/self/setgroups: Permission denied

me@myhost:~$ sudo setcap cap_sys_admin= /usr/bin/unshare
me@myhost:~$ unshare -r
root@myhost:~#


By the way: I am running Ubuntu 16.04.4 LTS with kernel version 4.4 and the version of util-linux (including unshare) is 2.27.1.







share|improve this question













I observed the following phenomenon that I can not explain. After adding the CAP_SYS_ADMIN capability, unshare is no longer able to write to /proc/self/setgroups.



In fact, writing to this file requires the capability, but that is achieved by changing the user namespace. So why does adding the capability to the parent process prevents writing to this file?



me@myhost:~$ unshare -r
root@myhost:~# exit
logout

me@myhost:~$ sudo setcap cap_sys_admin=ep /usr/bin/unshare
me@myhost:~$ unshare -r
unshare: cannot open /proc/self/setgroups: Permission denied

me@myhost:~$ sudo setcap cap_sys_admin= /usr/bin/unshare
me@myhost:~$ unshare -r
root@myhost:~#


By the way: I am running Ubuntu 16.04.4 LTS with kernel version 4.4 and the version of util-linux (including unshare) is 2.27.1.









share|improve this question












share|improve this question




share|improve this question








edited Jul 27 at 8:35
























asked Jul 19 at 20:36









koalo

1107




1107











  • Related questions are unix.stackexchange.com/questions/133922 , unix.stackexchange.com/questions/364568 , and unix.stackexchange.com/questions/75045 .
    – JdeBP
    Aug 1 at 15:52
















  • Related questions are unix.stackexchange.com/questions/133922 , unix.stackexchange.com/questions/364568 , and unix.stackexchange.com/questions/75045 .
    – JdeBP
    Aug 1 at 15:52















Related questions are unix.stackexchange.com/questions/133922 , unix.stackexchange.com/questions/364568 , and unix.stackexchange.com/questions/75045 .
– JdeBP
Aug 1 at 15:52




Related questions are unix.stackexchange.com/questions/133922 , unix.stackexchange.com/questions/364568 , and unix.stackexchange.com/questions/75045 .
– JdeBP
Aug 1 at 15:52










1 Answer
1






active

oldest

votes

















up vote
8
down vote



accepted
+50










What's happening here is that your "unshare" process does not have access to write to the setgroups (and uid_maps, gid_maps) files on the external user namespace.



In that namespace, the pseudo-files in /proc/<PID> will be root-owned, and as if your effective uid is still that of your own user, you will not have access to write to those files.



You can visualize that easily by running a process in background (such as sleep) and inspecting the permissions of the setgroups file while it's running (uid_maps and gid_maps behave exactly the same.)



First, with a binary that doesn't have additional capabilities:



$ cp /usr/bin/sleep .
$ ./sleep 10 &
[1] 11209
$ ls -l /proc/11209/setgroups
-rw-r--r--. 1 myuser myuser 0 Jul 31 12:33 /proc/11209/setgroups
[1]+ Done ./sleep 10
$


Then, let's add some file capabilities to it and see the ownership change:



$ sudo setcap cap_net_bind_service=ep sleep
$ ./sleep 10 &
[1] 11220
$ ls -l /proc/11220/setgroups
-rw-r--r--. 1 root root 0 Jul 31 12:34 /proc/11220/setgroups
[1]+ Done ./sleep 10
$


The ownership of the files in /proc/<PID> is controlled by the "dumpable" flag inside the Linux kernel, which is used to prevent leaking information from a privileged process to an unprivileged user.



And considering you're running unshare with additional capabilities but still with a non-root effective uid, write access to these pseudo-files which are owned by root is prevented through the normal access controls of the operating system.




You can inspect the value of the "dumpable" flag by using the PR_GET_DUMPABLE command of the prctl(2) syscall.



In the description for PR_SET_DUMPABLE you'll also find:




Normally, this flag is set to 1. However, it is reset to the current value contained in the file /proc/sys/fs/suid_dumpable (which by default has the value 0), in the following circumstances:



[...]



  • The process executes (execve(2)) a program that has file capabilities (see capabilities(7)), but only if the permitted capabilities gained exceed those already permitted for the process.



Which is exactly your case, with an unshare binary that has file capabilities.



Interestingly, using a root owned setuid binary for unshare doesn't run into this exact issue. Yes, it will clear the "dumpable" flags and the files in /proc/<PID> will be owned by root. But considering your effective uid is also root when running a setuid binary, the access will be allowed.



In that case, you end up running into a different problem, which has to do with unshare's logic not being able to handle that particular setup (probably something to do with the effective uid and the actual uid not matching):



$ cp /usr/bin/unshare .
$ sudo setcap -r unshare
$ sudo chown root:root unshare
$ sudo chmod 4711 unshare
$ ./unshare -r
-bash: cannot set uid to 65534: effective uid 0: Invalid argument
-bash-4.4$


Also notice that the clearing of the "dumpable" flag was triggered by running a binary with file capabilities set. If you get additional capabilities in a different way, you might not run into this trouble. For instance, using "ambient" capabilities is a good way to get additional capabilities outside the namespace, while still not running into trouble when unsharing into a new user namespace.



(Unfortunately, there is not a lot of tooling around ambient capabilities yet. libcap only ships support in latest git, past version 2.25, which is the one currently shipped in most distros. capsh is fairly low-level, so it's not that easy to get it right either. See here for details on using latest capsh to add ambient capabilities. I also tried systemd-run but couldn't really manage to get ambient capabilities set up there either. Anyways, something for you to look into, if you do need capabilities, non-root user & user namespaces together!)






share|improve this answer

















  • 1




    thanks for mentioning Ambient capabilities, for example that's interesting to avoid limitations described there to bind to a privileged port.
    – A.B
    Aug 2 at 18:08










Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f457299%2flosing-permissions-by-adding-capability%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
8
down vote



accepted
+50










What's happening here is that your "unshare" process does not have access to write to the setgroups (and uid_maps, gid_maps) files on the external user namespace.



In that namespace, the pseudo-files in /proc/<PID> will be root-owned, and as if your effective uid is still that of your own user, you will not have access to write to those files.



You can visualize that easily by running a process in background (such as sleep) and inspecting the permissions of the setgroups file while it's running (uid_maps and gid_maps behave exactly the same.)



First, with a binary that doesn't have additional capabilities:



$ cp /usr/bin/sleep .
$ ./sleep 10 &
[1] 11209
$ ls -l /proc/11209/setgroups
-rw-r--r--. 1 myuser myuser 0 Jul 31 12:33 /proc/11209/setgroups
[1]+ Done ./sleep 10
$


Then, let's add some file capabilities to it and see the ownership change:



$ sudo setcap cap_net_bind_service=ep sleep
$ ./sleep 10 &
[1] 11220
$ ls -l /proc/11220/setgroups
-rw-r--r--. 1 root root 0 Jul 31 12:34 /proc/11220/setgroups
[1]+ Done ./sleep 10
$


The ownership of the files in /proc/<PID> is controlled by the "dumpable" flag inside the Linux kernel, which is used to prevent leaking information from a privileged process to an unprivileged user.



And considering you're running unshare with additional capabilities but still with a non-root effective uid, write access to these pseudo-files which are owned by root is prevented through the normal access controls of the operating system.




You can inspect the value of the "dumpable" flag by using the PR_GET_DUMPABLE command of the prctl(2) syscall.



In the description for PR_SET_DUMPABLE you'll also find:




Normally, this flag is set to 1. However, it is reset to the current value contained in the file /proc/sys/fs/suid_dumpable (which by default has the value 0), in the following circumstances:



[...]



  • The process executes (execve(2)) a program that has file capabilities (see capabilities(7)), but only if the permitted capabilities gained exceed those already permitted for the process.



Which is exactly your case, with an unshare binary that has file capabilities.



Interestingly, using a root owned setuid binary for unshare doesn't run into this exact issue. Yes, it will clear the "dumpable" flags and the files in /proc/<PID> will be owned by root. But considering your effective uid is also root when running a setuid binary, the access will be allowed.



In that case, you end up running into a different problem, which has to do with unshare's logic not being able to handle that particular setup (probably something to do with the effective uid and the actual uid not matching):



$ cp /usr/bin/unshare .
$ sudo setcap -r unshare
$ sudo chown root:root unshare
$ sudo chmod 4711 unshare
$ ./unshare -r
-bash: cannot set uid to 65534: effective uid 0: Invalid argument
-bash-4.4$


Also notice that the clearing of the "dumpable" flag was triggered by running a binary with file capabilities set. If you get additional capabilities in a different way, you might not run into this trouble. For instance, using "ambient" capabilities is a good way to get additional capabilities outside the namespace, while still not running into trouble when unsharing into a new user namespace.



(Unfortunately, there is not a lot of tooling around ambient capabilities yet. libcap only ships support in latest git, past version 2.25, which is the one currently shipped in most distros. capsh is fairly low-level, so it's not that easy to get it right either. See here for details on using latest capsh to add ambient capabilities. I also tried systemd-run but couldn't really manage to get ambient capabilities set up there either. Anyways, something for you to look into, if you do need capabilities, non-root user & user namespaces together!)






share|improve this answer

















  • 1




    thanks for mentioning Ambient capabilities, for example that's interesting to avoid limitations described there to bind to a privileged port.
    – A.B
    Aug 2 at 18:08














up vote
8
down vote



accepted
+50










What's happening here is that your "unshare" process does not have access to write to the setgroups (and uid_maps, gid_maps) files on the external user namespace.



In that namespace, the pseudo-files in /proc/<PID> will be root-owned, and as if your effective uid is still that of your own user, you will not have access to write to those files.



You can visualize that easily by running a process in background (such as sleep) and inspecting the permissions of the setgroups file while it's running (uid_maps and gid_maps behave exactly the same.)



First, with a binary that doesn't have additional capabilities:



$ cp /usr/bin/sleep .
$ ./sleep 10 &
[1] 11209
$ ls -l /proc/11209/setgroups
-rw-r--r--. 1 myuser myuser 0 Jul 31 12:33 /proc/11209/setgroups
[1]+ Done ./sleep 10
$


Then, let's add some file capabilities to it and see the ownership change:



$ sudo setcap cap_net_bind_service=ep sleep
$ ./sleep 10 &
[1] 11220
$ ls -l /proc/11220/setgroups
-rw-r--r--. 1 root root 0 Jul 31 12:34 /proc/11220/setgroups
[1]+ Done ./sleep 10
$


The ownership of the files in /proc/<PID> is controlled by the "dumpable" flag inside the Linux kernel, which is used to prevent leaking information from a privileged process to an unprivileged user.



And considering you're running unshare with additional capabilities but still with a non-root effective uid, write access to these pseudo-files which are owned by root is prevented through the normal access controls of the operating system.




You can inspect the value of the "dumpable" flag by using the PR_GET_DUMPABLE command of the prctl(2) syscall.



In the description for PR_SET_DUMPABLE you'll also find:




Normally, this flag is set to 1. However, it is reset to the current value contained in the file /proc/sys/fs/suid_dumpable (which by default has the value 0), in the following circumstances:



[...]



  • The process executes (execve(2)) a program that has file capabilities (see capabilities(7)), but only if the permitted capabilities gained exceed those already permitted for the process.



Which is exactly your case, with an unshare binary that has file capabilities.



Interestingly, using a root owned setuid binary for unshare doesn't run into this exact issue. Yes, it will clear the "dumpable" flags and the files in /proc/<PID> will be owned by root. But considering your effective uid is also root when running a setuid binary, the access will be allowed.



In that case, you end up running into a different problem, which has to do with unshare's logic not being able to handle that particular setup (probably something to do with the effective uid and the actual uid not matching):



$ cp /usr/bin/unshare .
$ sudo setcap -r unshare
$ sudo chown root:root unshare
$ sudo chmod 4711 unshare
$ ./unshare -r
-bash: cannot set uid to 65534: effective uid 0: Invalid argument
-bash-4.4$


Also notice that the clearing of the "dumpable" flag was triggered by running a binary with file capabilities set. If you get additional capabilities in a different way, you might not run into this trouble. For instance, using "ambient" capabilities is a good way to get additional capabilities outside the namespace, while still not running into trouble when unsharing into a new user namespace.



(Unfortunately, there is not a lot of tooling around ambient capabilities yet. libcap only ships support in latest git, past version 2.25, which is the one currently shipped in most distros. capsh is fairly low-level, so it's not that easy to get it right either. See here for details on using latest capsh to add ambient capabilities. I also tried systemd-run but couldn't really manage to get ambient capabilities set up there either. Anyways, something for you to look into, if you do need capabilities, non-root user & user namespaces together!)






share|improve this answer

















  • 1




    thanks for mentioning Ambient capabilities, for example that's interesting to avoid limitations described there to bind to a privileged port.
    – A.B
    Aug 2 at 18:08












up vote
8
down vote



accepted
+50







up vote
8
down vote



accepted
+50




+50




What's happening here is that your "unshare" process does not have access to write to the setgroups (and uid_maps, gid_maps) files on the external user namespace.



In that namespace, the pseudo-files in /proc/<PID> will be root-owned, and as if your effective uid is still that of your own user, you will not have access to write to those files.



You can visualize that easily by running a process in background (such as sleep) and inspecting the permissions of the setgroups file while it's running (uid_maps and gid_maps behave exactly the same.)



First, with a binary that doesn't have additional capabilities:



$ cp /usr/bin/sleep .
$ ./sleep 10 &
[1] 11209
$ ls -l /proc/11209/setgroups
-rw-r--r--. 1 myuser myuser 0 Jul 31 12:33 /proc/11209/setgroups
[1]+ Done ./sleep 10
$


Then, let's add some file capabilities to it and see the ownership change:



$ sudo setcap cap_net_bind_service=ep sleep
$ ./sleep 10 &
[1] 11220
$ ls -l /proc/11220/setgroups
-rw-r--r--. 1 root root 0 Jul 31 12:34 /proc/11220/setgroups
[1]+ Done ./sleep 10
$


The ownership of the files in /proc/<PID> is controlled by the "dumpable" flag inside the Linux kernel, which is used to prevent leaking information from a privileged process to an unprivileged user.



And considering you're running unshare with additional capabilities but still with a non-root effective uid, write access to these pseudo-files which are owned by root is prevented through the normal access controls of the operating system.




You can inspect the value of the "dumpable" flag by using the PR_GET_DUMPABLE command of the prctl(2) syscall.



In the description for PR_SET_DUMPABLE you'll also find:




Normally, this flag is set to 1. However, it is reset to the current value contained in the file /proc/sys/fs/suid_dumpable (which by default has the value 0), in the following circumstances:



[...]



  • The process executes (execve(2)) a program that has file capabilities (see capabilities(7)), but only if the permitted capabilities gained exceed those already permitted for the process.



Which is exactly your case, with an unshare binary that has file capabilities.



Interestingly, using a root owned setuid binary for unshare doesn't run into this exact issue. Yes, it will clear the "dumpable" flags and the files in /proc/<PID> will be owned by root. But considering your effective uid is also root when running a setuid binary, the access will be allowed.



In that case, you end up running into a different problem, which has to do with unshare's logic not being able to handle that particular setup (probably something to do with the effective uid and the actual uid not matching):



$ cp /usr/bin/unshare .
$ sudo setcap -r unshare
$ sudo chown root:root unshare
$ sudo chmod 4711 unshare
$ ./unshare -r
-bash: cannot set uid to 65534: effective uid 0: Invalid argument
-bash-4.4$


Also notice that the clearing of the "dumpable" flag was triggered by running a binary with file capabilities set. If you get additional capabilities in a different way, you might not run into this trouble. For instance, using "ambient" capabilities is a good way to get additional capabilities outside the namespace, while still not running into trouble when unsharing into a new user namespace.



(Unfortunately, there is not a lot of tooling around ambient capabilities yet. libcap only ships support in latest git, past version 2.25, which is the one currently shipped in most distros. capsh is fairly low-level, so it's not that easy to get it right either. See here for details on using latest capsh to add ambient capabilities. I also tried systemd-run but couldn't really manage to get ambient capabilities set up there either. Anyways, something for you to look into, if you do need capabilities, non-root user & user namespaces together!)






share|improve this answer













What's happening here is that your "unshare" process does not have access to write to the setgroups (and uid_maps, gid_maps) files on the external user namespace.



In that namespace, the pseudo-files in /proc/<PID> will be root-owned, and as if your effective uid is still that of your own user, you will not have access to write to those files.



You can visualize that easily by running a process in background (such as sleep) and inspecting the permissions of the setgroups file while it's running (uid_maps and gid_maps behave exactly the same.)



First, with a binary that doesn't have additional capabilities:



$ cp /usr/bin/sleep .
$ ./sleep 10 &
[1] 11209
$ ls -l /proc/11209/setgroups
-rw-r--r--. 1 myuser myuser 0 Jul 31 12:33 /proc/11209/setgroups
[1]+ Done ./sleep 10
$


Then, let's add some file capabilities to it and see the ownership change:



$ sudo setcap cap_net_bind_service=ep sleep
$ ./sleep 10 &
[1] 11220
$ ls -l /proc/11220/setgroups
-rw-r--r--. 1 root root 0 Jul 31 12:34 /proc/11220/setgroups
[1]+ Done ./sleep 10
$


The ownership of the files in /proc/<PID> is controlled by the "dumpable" flag inside the Linux kernel, which is used to prevent leaking information from a privileged process to an unprivileged user.



And considering you're running unshare with additional capabilities but still with a non-root effective uid, write access to these pseudo-files which are owned by root is prevented through the normal access controls of the operating system.




You can inspect the value of the "dumpable" flag by using the PR_GET_DUMPABLE command of the prctl(2) syscall.



In the description for PR_SET_DUMPABLE you'll also find:




Normally, this flag is set to 1. However, it is reset to the current value contained in the file /proc/sys/fs/suid_dumpable (which by default has the value 0), in the following circumstances:



[...]



  • The process executes (execve(2)) a program that has file capabilities (see capabilities(7)), but only if the permitted capabilities gained exceed those already permitted for the process.



Which is exactly your case, with an unshare binary that has file capabilities.



Interestingly, using a root owned setuid binary for unshare doesn't run into this exact issue. Yes, it will clear the "dumpable" flags and the files in /proc/<PID> will be owned by root. But considering your effective uid is also root when running a setuid binary, the access will be allowed.



In that case, you end up running into a different problem, which has to do with unshare's logic not being able to handle that particular setup (probably something to do with the effective uid and the actual uid not matching):



$ cp /usr/bin/unshare .
$ sudo setcap -r unshare
$ sudo chown root:root unshare
$ sudo chmod 4711 unshare
$ ./unshare -r
-bash: cannot set uid to 65534: effective uid 0: Invalid argument
-bash-4.4$


Also notice that the clearing of the "dumpable" flag was triggered by running a binary with file capabilities set. If you get additional capabilities in a different way, you might not run into this trouble. For instance, using "ambient" capabilities is a good way to get additional capabilities outside the namespace, while still not running into trouble when unsharing into a new user namespace.



(Unfortunately, there is not a lot of tooling around ambient capabilities yet. libcap only ships support in latest git, past version 2.25, which is the one currently shipped in most distros. capsh is fairly low-level, so it's not that easy to get it right either. See here for details on using latest capsh to add ambient capabilities. I also tried systemd-run but couldn't really manage to get ambient capabilities set up there either. Anyways, something for you to look into, if you do need capabilities, non-root user & user namespaces together!)







share|improve this answer













share|improve this answer



share|improve this answer











answered Jul 31 at 20:03









Filipe Brandenburger

2,919417




2,919417







  • 1




    thanks for mentioning Ambient capabilities, for example that's interesting to avoid limitations described there to bind to a privileged port.
    – A.B
    Aug 2 at 18:08












  • 1




    thanks for mentioning Ambient capabilities, for example that's interesting to avoid limitations described there to bind to a privileged port.
    – A.B
    Aug 2 at 18:08







1




1




thanks for mentioning Ambient capabilities, for example that's interesting to avoid limitations described there to bind to a privileged port.
– A.B
Aug 2 at 18:08




thanks for mentioning Ambient capabilities, for example that's interesting to avoid limitations described there to bind to a privileged port.
– A.B
Aug 2 at 18:08












 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f457299%2flosing-permissions-by-adding-capability%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

How to check contact read email or not when send email to Individual?

Bahrain

Postfix configuration issue with fips on centos 7; mailgun relay