Skip to content

Commit c66f39b

Browse files
committed
src/utils: add proc_has_capability_in helper
Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
1 parent ad4ca27 commit c66f39b

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

src/utils.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <stdio.h>
1414
#include <stdlib.h>
1515
#include <string.h>
16+
#include <sys/capability.h>
1617
#include <sys/epoll.h>
1718
#include <sys/stat.h>
1819
#include <sys/types.h>
@@ -691,3 +692,49 @@ int get_task_personality(pid_t pid, __u32 *personality)
691692

692693
return ret;
693694
}
695+
696+
/* inspired by the Linux kernel's selftests/bpf :-) */
697+
bool proc_has_capability(pid_t pid, __u64 caps)
698+
{
699+
struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];
700+
struct __user_cap_header_struct hdr = {
701+
.version = _LINUX_CAPABILITY_VERSION_3,
702+
};
703+
__u32 cap0 = caps;
704+
__u32 cap1 = caps >> 32;
705+
int err;
706+
707+
err = capget(&hdr, data);
708+
if (err)
709+
return false;
710+
711+
return ((data[0].effective & cap0) == cap0 &&
712+
(data[1].effective & cap1) == cap1);
713+
}
714+
715+
#define LXCFS_PROC_USER_NS_LEN \
716+
(STRLITERALLEN("/proc/") + INTTYPE_TO_STRLEN(uint64_t) + \
717+
STRLITERALLEN("/ns/user") + 1)
718+
719+
static ino_t get_userns_ino(pid_t pid)
720+
{
721+
char path[LXCFS_PROC_USER_NS_LEN];
722+
struct stat st;
723+
724+
snprintf(path, sizeof(path), "/proc/%d/ns/user", pid);
725+
if (stat(path, &st))
726+
return 0;
727+
728+
return st.st_ino;
729+
}
730+
731+
bool proc_has_capability_in(pid_t nspid, pid_t pid, __u64 caps)
732+
{
733+
ino_t nspid_userns_ino, pid_userns_ino;
734+
735+
nspid_userns_ino = get_userns_ino(nspid);
736+
pid_userns_ino = get_userns_ino(pid);
737+
738+
return (nspid_userns_ino == pid_userns_ino) &&
739+
proc_has_capability(pid, caps);
740+
}

src/utils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,7 @@ extern char *read_file_at(int dfd, const char *fnam, unsigned int o_flags);
7979
extern int get_task_personality(pid_t pid, __u32 *personality);
8080
extern int get_host_personality(__u32 *personality);
8181

82+
extern bool proc_has_capability(pid_t pid, __u64 caps);
83+
extern bool proc_has_capability_in(pid_t nspid, pid_t pid, __u64 caps);
84+
8285
#endif /* __LXCFS_UTILS_H */

0 commit comments

Comments
 (0)