Losing permissions by adding capability?
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
6
down vote
favorite
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.
namespace unshare
add a comment |Â
up vote
6
down vote
favorite
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.
namespace unshare
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
add a comment |Â
up vote
6
down vote
favorite
up vote
6
down vote
favorite
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.
namespace unshare
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.
namespace unshare
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
add a comment |Â
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
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
8
down vote
accepted
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 (seecapabilities(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!)
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
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
8
down vote
accepted
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 (seecapabilities(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!)
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
add a comment |Â
up vote
8
down vote
accepted
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 (seecapabilities(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!)
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
add a comment |Â
up vote
8
down vote
accepted
up vote
8
down vote
accepted
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 (seecapabilities(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!)
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 (seecapabilities(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!)
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
add a comment |Â
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
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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