Commit 21d27446 authored by John Johansen's avatar John Johansen Committed by Tim Gardner

UBUNTU: SAUCE: apparmor: rework retrieval of the current label in the profile update case

BugLink: http://bugs.launchpad.net/bugs/1430546

The profile update mechanism can return a stale label when an update to
the task's cred fails.  Fix this so that the current label is always
returned.
Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
Signed-off-by: default avatarTim Gardner <tim.gardner@canonical.com>
parent 67e14e37
...@@ -105,11 +105,12 @@ static int apparmor_ptrace_access_check(struct task_struct *child, ...@@ -105,11 +105,12 @@ static int apparmor_ptrace_access_check(struct task_struct *child,
struct aa_label *tracer, *tracee; struct aa_label *tracer, *tracee;
int error; int error;
tracer = aa_current_label(); tracer = aa_begin_current_label(DO_UPDATE);
tracee = aa_get_task_label(child); tracee = aa_get_task_label(child);
error = aa_may_ptrace(tracer, tracee, error = aa_may_ptrace(tracer, tracee,
mode == PTRACE_MODE_READ ? AA_PTRACE_READ : AA_PTRACE_TRACE); mode == PTRACE_MODE_READ ? AA_PTRACE_READ : AA_PTRACE_TRACE);
aa_put_label(tracee); aa_put_label(tracee);
aa_end_current_label(tracer);
return error; return error;
} }
...@@ -118,10 +119,12 @@ static int apparmor_ptrace_traceme(struct task_struct *parent) ...@@ -118,10 +119,12 @@ static int apparmor_ptrace_traceme(struct task_struct *parent)
struct aa_label *tracer, *tracee; struct aa_label *tracer, *tracee;
int error; int error;
tracee = aa_current_label(); tracee = aa_begin_current_label(DO_UPDATE);
tracer = aa_get_task_label(parent); tracer = aa_get_task_label(parent);
error = aa_may_ptrace(tracer, tracee, AA_PTRACE_TRACE); error = aa_may_ptrace(tracer, tracee, AA_PTRACE_TRACE);
aa_put_label(tracer); aa_put_label(tracer);
aa_end_current_label(tracee);
return error; return error;
} }
...@@ -187,7 +190,7 @@ static int common_perm(int op, struct path *path, u32 mask, ...@@ -187,7 +190,7 @@ static int common_perm(int op, struct path *path, u32 mask,
struct aa_label *label; struct aa_label *label;
int error = 0; int error = 0;
label = aa_begin_current_label(); label = aa_begin_current_label(NO_UPDATE);
if (!unconfined(label)) if (!unconfined(label))
error = aa_path_perm(op, label, path, 0, mask, cond); error = aa_path_perm(op, label, path, 0, mask, cond);
aa_end_current_label(label); aa_end_current_label(label);
...@@ -342,9 +345,11 @@ static int apparmor_path_link(struct dentry *old_dentry, struct path *new_dir, ...@@ -342,9 +345,11 @@ static int apparmor_path_link(struct dentry *old_dentry, struct path *new_dir,
if (!path_mediated_fs(old_dentry)) if (!path_mediated_fs(old_dentry))
return 0; return 0;
label = aa_current_label(); label = aa_begin_current_label(DO_UPDATE);
if (!unconfined(label)) if (!unconfined(label))
error = aa_path_link(label, old_dentry, new_dir, new_dentry); error = aa_path_link(label, old_dentry, new_dir, new_dentry);
aa_end_current_label(label);
return error; return error;
} }
...@@ -357,7 +362,7 @@ static int apparmor_path_rename(struct path *old_dir, struct dentry *old_dentry, ...@@ -357,7 +362,7 @@ static int apparmor_path_rename(struct path *old_dir, struct dentry *old_dentry,
if (!path_mediated_fs(old_dentry)) if (!path_mediated_fs(old_dentry))
return 0; return 0;
label = aa_current_label(); label = aa_begin_current_label(DO_UPDATE);
if (!unconfined(label)) { if (!unconfined(label)) {
struct path old_path = { old_dir->mnt, old_dentry }; struct path old_path = { old_dir->mnt, old_dentry };
struct path new_path = { new_dir->mnt, new_dentry }; struct path new_path = { new_dir->mnt, new_dentry };
...@@ -375,6 +380,8 @@ static int apparmor_path_rename(struct path *old_dir, struct dentry *old_dentry, ...@@ -375,6 +380,8 @@ static int apparmor_path_rename(struct path *old_dir, struct dentry *old_dentry,
AA_MAY_CREATE, &cond); AA_MAY_CREATE, &cond);
} }
aa_end_current_label(label);
return error; return error;
} }
...@@ -439,12 +446,16 @@ static int apparmor_file_open(struct file *file, const struct cred *cred) ...@@ -439,12 +446,16 @@ static int apparmor_file_open(struct file *file, const struct cred *cred)
static int apparmor_file_alloc_security(struct file *file) static int apparmor_file_alloc_security(struct file *file)
{ {
int error = 0;
/* freed by apparmor_file_free_security */ /* freed by apparmor_file_free_security */
file->f_security = aa_alloc_file_cxt(aa_current_label(), GFP_KERNEL); struct aa_label *label = aa_begin_current_label(DO_UPDATE);
file->f_security = aa_alloc_file_cxt(label, GFP_KERNEL);
if (!file_cxt(file)) if (!file_cxt(file))
return -ENOMEM; error = -ENOMEM;
return 0; aa_end_current_label(label);
return error;
} }
static void apparmor_file_free_security(struct file *file) static void apparmor_file_free_security(struct file *file)
...@@ -457,7 +468,7 @@ static int common_file_perm(int op, struct file *file, u32 mask) ...@@ -457,7 +468,7 @@ static int common_file_perm(int op, struct file *file, u32 mask)
struct aa_label *label; struct aa_label *label;
int error = 0; int error = 0;
label = aa_begin_current_label(); label = aa_begin_current_label(NO_UPDATE);
error = aa_file_perm(op, label, file, mask); error = aa_file_perm(op, label, file, mask);
aa_end_current_label(label); aa_end_current_label(label);
...@@ -531,7 +542,7 @@ static int apparmor_sb_mount(const char *dev_name, struct path *path, ...@@ -531,7 +542,7 @@ static int apparmor_sb_mount(const char *dev_name, struct path *path,
flags &= ~AA_MS_IGNORE_MASK; flags &= ~AA_MS_IGNORE_MASK;
label = aa_begin_current_label(); label = aa_begin_current_label(NO_UPDATE);
if (!unconfined(label)) { if (!unconfined(label)) {
if (flags & MS_REMOUNT) if (flags & MS_REMOUNT)
error = aa_remount(label, path, flags, data); error = aa_remount(label, path, flags, data);
...@@ -556,7 +567,7 @@ static int apparmor_sb_umount(struct vfsmount *mnt, int flags) ...@@ -556,7 +567,7 @@ static int apparmor_sb_umount(struct vfsmount *mnt, int flags)
struct aa_label *label; struct aa_label *label;
int error = 0; int error = 0;
label = aa_begin_current_label(); label = aa_begin_current_label(NO_UPDATE);
if (!unconfined(label)) if (!unconfined(label))
error = aa_umount(label, mnt, flags); error = aa_umount(label, mnt, flags);
aa_end_current_label(label); aa_end_current_label(label);
...@@ -569,7 +580,7 @@ static int apparmor_sb_pivotroot(struct path *old_path, struct path *new_path) ...@@ -569,7 +580,7 @@ static int apparmor_sb_pivotroot(struct path *old_path, struct path *new_path)
struct aa_label *label; struct aa_label *label;
int error = 0; int error = 0;
label = aa_begin_current_label(); label = aa_begin_current_label(NO_UPDATE);
if (!unconfined(label)) if (!unconfined(label))
error = aa_pivotroot(label, old_path, new_path); error = aa_pivotroot(label, old_path, new_path);
aa_end_current_label(label); aa_end_current_label(label);
...@@ -668,10 +679,11 @@ static int apparmor_setprocattr(struct task_struct *task, char *name, ...@@ -668,10 +679,11 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
return error; return error;
fail: fail:
aad(&sa)->label = aa_current_label(); aad(&sa)->label = aa_begin_current_label(DO_UPDATE);
aad(&sa)->info = name; aad(&sa)->info = name;
aad(&sa)->error = -EINVAL; aad(&sa)->error = -EINVAL;
aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL); aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
aa_end_current_label(aad(&sa)->label);
return -EINVAL; return -EINVAL;
} }
...@@ -710,7 +722,7 @@ void apparmor_bprm_committed_creds(struct linux_binprm *bprm) ...@@ -710,7 +722,7 @@ void apparmor_bprm_committed_creds(struct linux_binprm *bprm)
static int apparmor_task_setrlimit(struct task_struct *task, static int apparmor_task_setrlimit(struct task_struct *task,
unsigned int resource, struct rlimit *new_rlim) unsigned int resource, struct rlimit *new_rlim)
{ {
struct aa_label *label = aa_begin_current_label(); struct aa_label *label = aa_begin_current_label(NO_UPDATE);
int error = 0; int error = 0;
if (!unconfined(label)) if (!unconfined(label))
...@@ -790,7 +802,7 @@ static int apparmor_unix_stream_connect(struct sock *sk, struct sock *peer_sk, ...@@ -790,7 +802,7 @@ static int apparmor_unix_stream_connect(struct sock *sk, struct sock *peer_sk,
struct path *path; struct path *path;
int error; int error;
label = aa_begin_current_label(); label = aa_begin_current_label(NO_UPDATE);
error = aa_unix_peer_perm(label, OP_CONNECT, error = aa_unix_peer_perm(label, OP_CONNECT,
(AA_MAY_CONNECT | AA_MAY_SEND | AA_MAY_RECEIVE), (AA_MAY_CONNECT | AA_MAY_SEND | AA_MAY_RECEIVE),
sk, peer_sk, NULL); sk, peer_sk, NULL);
...@@ -843,7 +855,7 @@ static int apparmor_unix_stream_connect(struct sock *sk, struct sock *peer_sk, ...@@ -843,7 +855,7 @@ static int apparmor_unix_stream_connect(struct sock *sk, struct sock *peer_sk,
static int apparmor_unix_may_send(struct socket *sock, struct socket *peer) static int apparmor_unix_may_send(struct socket *sock, struct socket *peer)
{ {
struct aa_sk_cxt *peer_cxt = SK_CXT(peer->sk); struct aa_sk_cxt *peer_cxt = SK_CXT(peer->sk);
struct aa_label *label = aa_begin_current_label(); struct aa_label *label = aa_begin_current_label(NO_UPDATE);
int error; int error;
error = xcheck(aa_unix_peer_perm(label, OP_SENDMSG, AA_MAY_SEND, error = xcheck(aa_unix_peer_perm(label, OP_SENDMSG, AA_MAY_SEND,
...@@ -861,12 +873,14 @@ static int apparmor_unix_may_send(struct socket *sock, struct socket *peer) ...@@ -861,12 +873,14 @@ static int apparmor_unix_may_send(struct socket *sock, struct socket *peer)
static int apparmor_socket_create(int family, int type, int protocol, int kern) static int apparmor_socket_create(int family, int type, int protocol, int kern)
{ {
struct aa_label *label; struct aa_label *label;
int error = 0;
label = aa_current_label(); label = aa_begin_current_label(DO_UPDATE);
if (kern || unconfined(label)) if (!(kern || unconfined(label)))
return 0; error = aa_sock_create_perm(label, family, type, protocol);
aa_end_current_label(label);
return aa_sock_create_perm(label, family, type, protocol); return error;
} }
/** /**
...@@ -887,7 +901,7 @@ static int apparmor_socket_post_create(struct socket *sock, int family, ...@@ -887,7 +901,7 @@ static int apparmor_socket_post_create(struct socket *sock, int family,
if (kern) if (kern)
label = aa_get_label(&current_ns()->unconfined->label); label = aa_get_label(&current_ns()->unconfined->label);
else else
label = aa_get_label(aa_current_label()); label = aa_get_current_label();
if (sock->sk) { if (sock->sk) {
struct aa_sk_cxt *cxt = SK_CXT(sock->sk); struct aa_sk_cxt *cxt = SK_CXT(sock->sk);
...@@ -1056,7 +1070,7 @@ static int apparmor_socket_getpeersec_stream(struct socket *sock, ...@@ -1056,7 +1070,7 @@ static int apparmor_socket_getpeersec_stream(struct socket *sock,
{ {
char *name; char *name;
int slen, error = 0; int slen, error = 0;
struct aa_label *label = aa_current_label(); struct aa_label *label = aa_begin_current_label(DO_UPDATE);
struct aa_label *peer = sk_peer_label(sock->sk); struct aa_label *peer = sk_peer_label(sock->sk);
if (IS_ERR(peer)) if (IS_ERR(peer))
...@@ -1079,6 +1093,7 @@ static int apparmor_socket_getpeersec_stream(struct socket *sock, ...@@ -1079,6 +1093,7 @@ static int apparmor_socket_getpeersec_stream(struct socket *sock,
kfree(name); kfree(name);
} }
aa_end_current_label(label);
return error; return error;
} }
...@@ -1128,7 +1143,7 @@ static int apparmor_task_kill(struct task_struct *target, struct siginfo *info, ...@@ -1128,7 +1143,7 @@ static int apparmor_task_kill(struct task_struct *target, struct siginfo *info,
* Dealing with USB IO specific behavior * Dealing with USB IO specific behavior
*/ */
return 0; return 0;
cl = aa_begin_current_label(); cl = aa_begin_current_label(NO_UPDATE);
tl = aa_get_task_label(target); tl = aa_get_task_label(target);
error = aa_may_signal(cl, tl, sig); error = aa_may_signal(cl, tl, sig);
aa_put_label(tl); aa_put_label(tl);
......
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