Skip to content
Merged
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 (!can_access_personality())
return log_error(-EACCES, RESTRICTED_PERSONALITY_ACCESS_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 (!can_access_personality())
return log_error(-EACCES, RESTRICTED_PERSONALITY_ACCESS_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 (!can_access_personality())
return log_error(-EACCES, RESTRICTED_PERSONALITY_ACCESS_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
24 changes: 23 additions & 1 deletion src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -685,9 +685,31 @@ int get_task_personality(pid_t pid, __u32 *personality)
ret = read_nointr(fd, buf, sizeof(buf) - 1);
if (ret >= 0) {
buf[ret] = '\0';
if (safe_uint32(buf, personality, 16) < 0)
if (personality != NULL && safe_uint32(buf, personality, 16) < 0)
return log_error(-1, "Failed to convert personality %s", buf);
}

return ret;
}

/*
This function checks whether system security policy (i.e. Yama LSM) allows personality access, by trying on
init own one.
This is required as it may be restricted by a ptrace access mode check (see PROC(5)), and
`get_task_personality` function relies on this.
*/
bool can_access_personality(void)
{
static int could_access_init_personality = -1;

/* init personality has never been accessed (cache is empty) */
if (could_access_init_personality == -1) {
if (get_task_personality(1, NULL) < 0) {
could_access_init_personality = 0;
} else {
could_access_init_personality = 1;
}
}

return could_access_init_personality != 0;
}
3 changes: 3 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#define SEND_CREDS_NOTSK 1
#define SEND_CREDS_FAIL 2

#define RESTRICTED_PERSONALITY_ACCESS_POLICY "Due to restricted personality access 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 +79,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 can_access_personality(void);
extern int get_host_personality(__u32 *personality);

#endif /* __LXCFS_UTILS_H */