Skip to content

proc: checks system security policy before trying to get personalities #637

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions src/proc_fuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,11 @@ __lxcfs_fuse_ops int proc_getattr(const char *path, struct stat *sb)
strcmp(path, "/proc/swaps") == 0 ||
strcmp(path, "/proc/loadavg") == 0 ||
strcmp(path, "/proc/slabinfo") == 0) {
if (liblxcfs_functional())
if (liblxcfs_functional()) {
if (!is_ptrace_allowed())
return log_error(-EACCES, RESTRICTED_YAMA_PTRACE_POLICY);
sb->st_size = get_procfile_size_with_personality(path);
}
else
sb->st_size = get_procfile_size(path);
sb->st_mode = S_IFREG | 00444;
Expand Down Expand Up @@ -206,8 +209,11 @@ __lxcfs_fuse_ops int proc_open(const char *path, struct fuse_file_info *fi)

info->type = type;

if (liblxcfs_functional())
if (liblxcfs_functional()) {
if (!is_ptrace_allowed())
return log_error(-EACCES, RESTRICTED_YAMA_PTRACE_POLICY);
info->buflen = get_procfile_size_with_personality(path) + BUF_RESERVE_SIZE;
}
else
info->buflen = get_procfile_size(path) + BUF_RESERVE_SIZE;

Expand Down Expand Up @@ -1646,8 +1652,11 @@ __lxcfs_fuse_ops int proc_read(const char *path, char *buf, size_t size,
return read_file_fuse_with_offset(LXC_TYPE_PROC_MEMINFO_PATH,
buf, size, offset, f);
case LXC_TYPE_PROC_CPUINFO:
if (liblxcfs_functional())
if (liblxcfs_functional()) {
if (!is_ptrace_allowed())
return log_error(-EACCES, RESTRICTED_YAMA_PTRACE_POLICY);
return proc_read_with_personality(&proc_cpuinfo_read, buf, size, offset, fi);
}

return read_file_fuse_with_offset(LXC_TYPE_PROC_CPUINFO_PATH,
buf, size, offset, f);
Expand Down
41 changes: 41 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -691,3 +691,44 @@ int get_task_personality(pid_t pid, __u32 *personality)

return ret;
}

/*
This function checks whether system security policy (i.e. Yama LSM) allows ptrace usages.
This is required as accessing task personalities (see `get_task_personality` above) may be restricted by a ptrace
access mode check (see PROC(5)).
*/
bool is_ptrace_allowed(void)
{
static int yama_ptrace_scope = -1;

__u32 buf_u32;
__do_close int fd = -EBADF;
int ret = -1;
char buf[INTTYPE_TO_STRLEN(uint32_t)];

/* Yama ptrace scope is not yet known (cache is empty) */
if (yama_ptrace_scope == -1) {
/* assume default policy if we can't retrieve info below */
yama_ptrace_scope = YAMA_SCOPE_RELATIONAL;

fd = open(SYS_FS_KERNEL_YAMA_PTRACE_SCOPE, O_RDONLY | O_CLOEXEC);
if (fd >= 0) {
ret = read_nointr(fd, buf, sizeof(buf) - 1);
if (ret >= 0) {
buf[ret] = '\0';
if (safe_uint32(buf, &buf_u32, 16) < 0)
return log_error(true, "Failed to convert Yama ptrace scope %s\n", buf);

yama_ptrace_scope = buf_u32;
} else {
lxcfs_error("Failed to read Yama ptrace scope: %s.\n", strerror(errno));
}
} else if (errno == -ENOENT) {
/* in this very case, Yama may not be enabled at all */
yama_ptrace_scope = YAMA_SCOPE_DISABLED;
}
}

/* consider ptrace is allowed when Yama scope is lower than "no-attach" mode */
return (yama_ptrace_scope < YAMA_SCOPE_NO_ATTACH);
}
7 changes: 7 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
#define SEND_CREDS_NOTSK 1
#define SEND_CREDS_FAIL 2

#define SYS_FS_KERNEL_YAMA_PTRACE_SCOPE "/sys/kernel/yama/ptrace_scope"
#define YAMA_SCOPE_DISABLED 0
#define YAMA_SCOPE_RELATIONAL 1
#define YAMA_SCOPE_NO_ATTACH 3
#define RESTRICTED_YAMA_PTRACE_POLICY "Due to restricted Yama ptrace policy, reading proc files from containers is not permitted"

struct file_info;

__attribute__((__format__(__printf__, 4, 5))) extern char *must_strcat(char **src, size_t *sz, size_t *asz, const char *format, ...);
Expand Down Expand Up @@ -77,6 +83,7 @@ static inline bool file_exists(const char *f)
extern char *read_file_at(int dfd, const char *fnam, unsigned int o_flags);

extern int get_task_personality(pid_t pid, __u32 *personality);
extern bool is_ptrace_allowed(void);
extern int get_host_personality(__u32 *personality);

#endif /* __LXCFS_UTILS_H */