summaryrefslogtreecommitdiffstats
path: root/sys-utils/setpriv.c
diff options
context:
space:
mode:
authorPatrick Steinhardt2017-07-17 23:14:09 +0200
committerKarel Zak2017-07-18 13:54:08 +0200
commitfbd15c4d47be22fd88670251b44749287af0f2ff (patch)
tree11ebb38dd0546e136fab1fe45683b59a24f91270 /sys-utils/setpriv.c
parentlibfdisk: fix warning -Wunused-function (diff)
downloadkernel-qcow2-util-linux-fbd15c4d47be22fd88670251b44749287af0f2ff.tar.gz
kernel-qcow2-util-linux-fbd15c4d47be22fd88670251b44749287af0f2ff.tar.xz
kernel-qcow2-util-linux-fbd15c4d47be22fd88670251b44749287af0f2ff.zip
setpriv: support setting unnamed capabilities
When setting capabilities, we accept human readable names like for example `sys_rawio` or `net_admin`. To do so the translation between the capability name and its in-kernel index, we rely on the function `capng_name_to_capability`. When the function does not know the named capability, it will return an error value and we abort setting the capability. This relies upon the ability of libcap to know all capabilities inside of the kernel. But actually, it is possible that new capabilities are introduced inside of the Linux kernel which are not recognized yet by the library. When dumping these unknown capabilities, libcap will simply return a string like "cap_38", that is it will append the capability's in-kernel index to the prefix "cap_". This may lead a user to also think that "cap_38" may be passed to the switches "--inh-caps" or "--ambient-caps", which is unfortunately not the case. We can do better here by instead accepting strings in the form of "cap_N". To do so, we can simply rely on the fact that capability indices are steadily increasing and that the highest index known to the kernel is stored inside of the kernel's procfs, made readily available by our function `real_cap_last_cap()`. So in case libcap does not know a capability name, we can simply parse the string and, if it is in the correct format, check whether the detected index is between 0 and the highest capability index. If so, we can treat it as a valid capability string and apply it. Signed-off-by: Patrick Steinhardt <ps@pks.im>
Diffstat (limited to 'sys-utils/setpriv.c')
-rw-r--r--sys-utils/setpriv.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/sys-utils/setpriv.c b/sys-utils/setpriv.c
index 19753aab8..2402e624f 100644
--- a/sys-utils/setpriv.c
+++ b/sys-utils/setpriv.c
@@ -529,6 +529,9 @@ static void do_caps(enum cap_type type, const char *caps)
int cap = capng_name_to_capability(c + 1);
if (0 <= cap)
cap_update(action, type, cap);
+ else if (sscanf(c + 1, "cap_%d", &cap) == 1
+ && 0 <= cap && cap <= real_cap_last_cap())
+ cap_update(action, type, cap);
else
errx(EXIT_FAILURE,
_("unknown capability \"%s\""), c + 1);