diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index fe68bd3..8aabd21 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -787,6 +787,22 @@ static int unix_fs_perm(int op, struct aa_label *label, struct sock *sk, return 0; } +static int unix_peer_perm(struct aa_label *label, int op, u32 request, + struct sock *sk, struct sock *peer_sk) +{ + struct unix_sock *peeru = unix_sk(peer_sk); + struct unix_sock *u = unix_sk(sk); + + AA_BUG(!label); + AA_BUG(!sk); + AA_BUG(!peer_sk); + + if (UNIX_FS(peeru)) + return unix_fs_perm(op, request, label, peeru, 0); + else if (UNIX_FS(u)) + return unix_fs_perm(op, request, label, u, 0); +} + /** * apparmor_unix_stream_connect - check perms before making unix domain conn * @@ -802,8 +818,8 @@ static int apparmor_unix_stream_connect(struct sock *sock, struct sock *other, int error; label = __aa_get_current_label(); - error = unix_fs_perm(OP_CONNECT, label, other, - MAY_READ | MAY_WRITE); + error = aa_unix_peer_perm(label, OP_CONNECT, (MAY_READ | MAY_WRITE), + sk, peer_sk); __aa_put_current_label(label); if (error) @@ -835,9 +851,10 @@ static int apparmor_unix_may_send(struct socket *sock, struct socket *other) struct aa_label *label = __aa_get_current_label(); int error; - error = xcheck(unix_fs_perm(OP_SENDMSG, label, other->sk, MAY_WRITE), - unix_fs_perm(OP_SENDMSG, other_cxt->label, sock->sk, - MAY_READ)); + error = xcheck(aa_unix_peer_perm(label, OP_SENDMSG, AA_MAY_SEND, + sock->sk, peer->sk), + aa_unix_peer_perm(peer_cxt->label, OP_SENDMSG, + AA_MAY_RECEIVE, peer->sk, sock->sk)); __aa_put_current_label(label); return error;