Unverified Commit f43ed6a0 by Christian Brauner Committed by GitHub

Merge pull request #3686 from cyphar/apparmor-attr-subdir

apparmor: prefer /proc/.../attr/apparmor/current over legacy interface
parents 35a68d6d 47f4914d
...@@ -395,52 +395,56 @@ static int apparmor_enabled(struct lsm_ops *ops) ...@@ -395,52 +395,56 @@ static int apparmor_enabled(struct lsm_ops *ops)
return 0; return 0;
} }
static int __apparmor_process_label_open(struct lsm_ops *ops, pid_t pid, int o_flags, bool on_exec)
{
int ret = -1;
int labelfd;
char path[LXC_LSMATTRLEN];
if (on_exec)
TRACE("On-exec not supported with AppArmor");
/* first try the apparmor subdir */
ret = snprintf(path, LXC_LSMATTRLEN, "/proc/%d/attr/apparmor/current", pid);
if (ret < 0 || ret >= LXC_LSMATTRLEN)
return -1;
labelfd = open(path, o_flags);
if (labelfd >= 0)
return labelfd;
else if (errno != ENOENT)
goto error;
/* fallback to legacy global attr directory */
ret = snprintf(path, LXC_LSMATTRLEN, "/proc/%d/attr/current", pid);
if (ret < 0 || ret >= LXC_LSMATTRLEN)
return -1;
labelfd = open(path, o_flags);
if (labelfd >= 0)
return labelfd;
error:
return log_error_errno(-errno, errno, "Unable to open AppArmor LSM label file descriptor");
}
static char *apparmor_process_label_get(struct lsm_ops *ops, pid_t pid) static char *apparmor_process_label_get(struct lsm_ops *ops, pid_t pid)
{ {
char path[100], *space; int label_fd;
int ret; __do_free char *label = NULL;
char *buf = NULL, *newbuf; size_t len;
int sz = 0;
FILE *f;
ret = snprintf(path, 100, "/proc/%d/attr/current", pid); label_fd = __apparmor_process_label_open(ops, pid, O_RDONLY, false);
if (ret < 0 || ret >= 100) { if (label_fd < 0)
ERROR("path name too long");
return NULL;
}
again:
f = fopen_cloexec(path, "r");
if (!f) {
SYSERROR("opening %s", path);
free(buf);
return NULL;
}
sz += 1024;
newbuf = realloc(buf, sz);
if (!newbuf) {
free(buf);
ERROR("out of memory");
fclose(f);
return NULL;
}
buf = newbuf;
memset(buf, 0, sz);
ret = fread(buf, 1, sz - 1, f);
fclose(f);
if (ret < 0) {
ERROR("reading %s", path);
free(buf);
return NULL; return NULL;
}
if (ret >= sz) fd_to_buf(label_fd, &label, &len);
goto again;
space = strchr(buf, '\n'); len = strcspn(label, "\n \t");
if (space) if (len)
*space = '\0'; label[len] = '\0';
space = strchr(buf, ' ');
if (space) return move_ptr(label);
*space = '\0';
return buf;
} }
static char *apparmor_process_label_get_at(struct lsm_ops *ops, int fd_pid) static char *apparmor_process_label_get_at(struct lsm_ops *ops, int fd_pid)
...@@ -448,6 +452,9 @@ static char *apparmor_process_label_get_at(struct lsm_ops *ops, int fd_pid) ...@@ -448,6 +452,9 @@ static char *apparmor_process_label_get_at(struct lsm_ops *ops, int fd_pid)
__do_free char *label = NULL; __do_free char *label = NULL;
size_t len; size_t len;
/* first try the apparmor subdir, then fall back to legacy interface */
label = read_file_at(fd_pid, "attr/apparmor/current", PROTECT_OPEN, PROTECT_LOOKUP_BENEATH);
if (!label && errno == ENOENT)
label = read_file_at(fd_pid, "attr/current", PROTECT_OPEN, PROTECT_LOOKUP_BENEATH); label = read_file_at(fd_pid, "attr/current", PROTECT_OPEN, PROTECT_LOOKUP_BENEATH);
if (!label) if (!label)
return log_error_errno(NULL, errno, "Failed to get AppArmor context"); return log_error_errno(NULL, errno, "Failed to get AppArmor context");
...@@ -455,7 +462,6 @@ static char *apparmor_process_label_get_at(struct lsm_ops *ops, int fd_pid) ...@@ -455,7 +462,6 @@ static char *apparmor_process_label_get_at(struct lsm_ops *ops, int fd_pid)
len = strcspn(label, "\n \t"); len = strcspn(label, "\n \t");
if (len) if (len)
label[len] = '\0'; label[len] = '\0';
return move_ptr(label); return move_ptr(label);
} }
...@@ -1141,22 +1147,7 @@ static int apparmor_keyring_label_set(struct lsm_ops *ops, const char *label) ...@@ -1141,22 +1147,7 @@ static int apparmor_keyring_label_set(struct lsm_ops *ops, const char *label)
static int apparmor_process_label_fd_get(struct lsm_ops *ops, pid_t pid, bool on_exec) static int apparmor_process_label_fd_get(struct lsm_ops *ops, pid_t pid, bool on_exec)
{ {
int ret = -1; return __apparmor_process_label_open(ops, pid, O_RDWR, on_exec);
int labelfd;
char path[LXC_LSMATTRLEN];
if (on_exec)
TRACE("On-exec not supported with AppArmor");
ret = snprintf(path, LXC_LSMATTRLEN, "/proc/%d/attr/current", pid);
if (ret < 0 || ret >= LXC_LSMATTRLEN)
return -1;
labelfd = open(path, O_RDWR);
if (labelfd < 0)
return log_error_errno(-errno, errno, "Unable to open AppArmor LSM label file descriptor");
return labelfd;
} }
static int apparmor_process_label_set_at(struct lsm_ops *ops, int label_fd, const char *label, bool on_exec) static int apparmor_process_label_set_at(struct lsm_ops *ops, int label_fd, const char *label, bool on_exec)
......
...@@ -333,11 +333,13 @@ ...@@ -333,11 +333,13 @@
* + * +
* /attr/ = 6 * /attr/ = 6
* + * +
* /apparmor/ = 10
* +
* /current = 8 * /current = 8
* + * +
* \0 = 1 * \0 = 1
*/ */
#define LXC_LSMATTRLEN (6 + INTTYPE_TO_STRLEN(pid_t) + 6 + 8 + 1) #define LXC_LSMATTRLEN (6 + INTTYPE_TO_STRLEN(pid_t) + 6 + 10 + 8 + 1)
/* MAX_NS_PROC_NAME = MAX_NS_PROC_NAME /* MAX_NS_PROC_NAME = MAX_NS_PROC_NAME
* + * +
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment