From 50b0df16469684b6f9931c51caeb66ab35f1432f Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 17 Nov 2017 14:03:24 +0100 Subject: [PATCH] util: add list of capabilities the capsh approach doesn't work on RHEL as the version of libcap is not updated and doesn't know all the possible capabilities available on the system. This is the output I get with getpcaps on RHELAH 7.4.2: Capabilities for `1': = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,35,36+ep Fallback to the capsh method if there will be more capabilities that we know of, and hopefully libcap does. Signed-off-by: Giuseppe Scrivano Closes: #1130 Approved by: rhatdan --- Atomic/util.py | 55 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/Atomic/util.py b/Atomic/util.py index cad37681..4ac63cb0 100644 --- a/Atomic/util.py +++ b/Atomic/util.py @@ -1136,6 +1136,45 @@ def remove_skopeo_prefixes(image): image = image.replace(remove, '') return image +KNOWN_CAPS = ['CAP_CHOWN', + 'CAP_DAC_OVERRIDE', + 'CAP_DAC_READ_SEARCH', + 'CAP_FOWNER', + 'CAP_FSETID', + 'CAP_KILL', + 'CAP_SETGID', + 'CAP_SETUID', + 'CAP_SETPCAP', + 'CAP_LINUX_IMMUTABLE', + 'CAP_NET_BIND_SERVICE', + 'CAP_NET_BROADCAST', + 'CAP_NET_ADMIN', + 'CAP_NET_RAW', + 'CAP_IPC_LOCK', + 'CAP_IPC_OWNER', + 'CAP_SYS_MODULE', + 'CAP_SYS_RAWIO', + 'CAP_SYS_CHROOT', + 'CAP_SYS_PTRACE', + 'CAP_SYS_PACCT', + 'CAP_SYS_ADMIN', + 'CAP_SYS_BOOT', + 'CAP_SYS_NICE', + 'CAP_SYS_RESOURCE', + 'CAP_SYS_TIME', + 'CAP_SYS_TTY_CONFIG', + 'CAP_MKNOD', + 'CAP_LEASE', + 'CAP_AUDIT_WRITE', + 'CAP_AUDIT_CONTROL', + 'CAP_SETFCAP', + 'CAP_MAC_OVERRIDE', + 'CAP_MAC_ADMIN', + 'CAP_SYSLOG', + 'CAP_WAKE_ALARM', + 'CAP_BLOCK_SUSPEND', + 'CAP_AUDIT_READ'] + def get_all_known_process_capabilities(): """ Get all the known process capabilities @@ -1147,14 +1186,16 @@ def get_all_known_process_capabilities(): with open("/proc/sys/kernel/cap_last_cap", 'r') as f: last_cap = int(f.read()) - mask = hex((1 << (last_cap + 1)) - 1) - - out = subprocess.check_output([CAPSH_PATH, '--decode={}'.format(mask)], stderr=DEVNULL) + if last_cap < len(KNOWN_CAPS): + caps = KNOWN_CAPS[:last_cap+1] + else: + mask = hex((1 << (last_cap + 1)) - 1) + out = subprocess.check_output([CAPSH_PATH, '--decode={}'.format(mask)], stderr=DEVNULL) - # The output looks like 0x0000003fffffffff=cap_chown,cap_dac_override,... - # so take only the part after the '=' - caps = str(out.decode().split("=")[1].strip()) + # The output looks like 0x0000003fffffffff=cap_chown,cap_dac_override,... + # so take only the part after the '=' + caps = str(out.decode().split("=")[1].strip()).split(',') - caps_list = [i.upper() for i in caps.split(',')] + caps_list = [i.upper() for i in caps] return [i for i in caps_list if not i[0].isdigit()]