Skip to content

Commit 1735384

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

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-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>
@@ -713,3 +714,49 @@ bool can_access_personality(void)
713714

714715
return could_access_init_personality != 0;
715716
}
717+
718+
/* inspired by the Linux kernel's selftests/bpf :-) */
719+
bool proc_has_capability(pid_t pid, __u64 caps)
720+
{
721+
struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];
722+
struct __user_cap_header_struct hdr = {
723+
.version = _LINUX_CAPABILITY_VERSION_3,
724+
};
725+
__u32 cap0 = caps;
726+
__u32 cap1 = caps >> 32;
727+
int err;
728+
729+
err = capget(&hdr, data);
730+
if (err)
731+
return false;
732+
733+
return ((data[0].effective & cap0) == cap0 &&
734+
(data[1].effective & cap1) == cap1);
735+
}
736+
737+
#define LXCFS_PROC_USER_NS_LEN \
738+
(STRLITERALLEN("/proc/") + INTTYPE_TO_STRLEN(uint64_t) + \
739+
STRLITERALLEN("/ns/user") + 1)
740+
741+
static ino_t get_userns_ino(pid_t pid)
742+
{
743+
char path[LXCFS_PROC_USER_NS_LEN];
744+
struct stat st;
745+
746+
snprintf(path, sizeof(path), "/proc/%d/ns/user", pid);
747+
if (stat(path, &st))
748+
return 0;
749+
750+
return st.st_ino;
751+
}
752+
753+
bool proc_has_capability_in(pid_t nspid, pid_t pid, cap_value_t cap)
754+
{
755+
ino_t nspid_userns_ino, pid_userns_ino;
756+
757+
nspid_userns_ino = get_userns_ino(nspid);
758+
pid_userns_ino = get_userns_ino(pid);
759+
760+
return (nspid_userns_ino == pid_userns_ino) &&
761+
proc_has_capability(pid, 1ULL << cap);
762+
}

src/utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <signal.h>
99
#include <stdbool.h>
10+
#include <sys/capability.h>
1011
#include <sys/socket.h>
1112
#include <sys/types.h>
1213
#include <sys/un.h>
@@ -82,4 +83,7 @@ extern int get_task_personality(pid_t pid, __u32 *personality);
8283
extern bool can_access_personality(void);
8384
extern int get_host_personality(__u32 *personality);
8485

86+
extern bool proc_has_capability(pid_t pid, __u64 caps);
87+
extern bool proc_has_capability_in(pid_t nspid, pid_t pid, cap_value_t cap);
88+
8589
#endif /* __LXCFS_UTILS_H */

0 commit comments

Comments
 (0)