UBUNTU: SAUCE: apparmor4.0.0 [47/90]: af_unix mediation
BugLink: http://bugs.launchpad.net/bugs/2028253 af_socket mediation did not make it into 4.17 so add remaining out of tree patch Signed-off-by: John Johansen <john.johansen@canonical.com> (cherry picked from https://gitlab.com/jjohansen/apparmor-kernel) Signed-off-by: Andrea Righi <andrea.righi@canonical.com> (cherry picked from commit 651f0b2cc1d78cb7afbc0fcadc166ed0bcc78dd3 https://git.launchpad.net/~apparmor-dev/ubuntu-kernel-next) Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
This commit is contained in:
committed by
Paolo Pisati
parent
1467c91ebd
commit
938de00f4f
@@ -0,0 +1,122 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* AppArmor security module
|
||||
*
|
||||
* This file contains AppArmor af_unix fine grained mediation
|
||||
*
|
||||
* Copyright 2014 Canonical Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation, version 2 of the
|
||||
* License.
|
||||
*/
|
||||
#ifndef __AA_AF_UNIX_H
|
||||
|
||||
#include <net/af_unix.h>
|
||||
|
||||
#include "label.h"
|
||||
//#include "include/net.h"
|
||||
|
||||
#define unix_addr_len(L) ((L) - sizeof(sa_family_t))
|
||||
#define unix_abstract_name_len(L) (unix_addr_len(L) - 1)
|
||||
#define unix_abstract_len(U) (unix_abstract_name_len((U)->addr->len))
|
||||
#define addr_unix_abstract_name(B) ((B)[0] == 0)
|
||||
#define addr_unix_anonymous(U) (addr_unix_len(U) <= 0)
|
||||
#define addr_unix_abstract(U) (!addr_unix_anonymous(U) && addr_unix_abstract_name((U)->addr))
|
||||
//#define unix_addr_fs(U) (!unix_addr_anonymous(U) && !unix_addr_abstract_name((U)->addr))
|
||||
|
||||
#define unix_addr(A) ((struct sockaddr_un *)(A))
|
||||
#define unix_addr_anon(A, L) ((A) && unix_addr_len(L) <= 0)
|
||||
#define unix_addr_fs(A, L) (!unix_addr_anon(A, L) && \
|
||||
!addr_unix_abstract_name(unix_addr(A)->sun_path))
|
||||
|
||||
#define UNIX_ANONYMOUS(U) (!unix_sk(U)->addr)
|
||||
/* from net/unix/af_unix.c */
|
||||
#define UNIX_ABSTRACT(U) (!UNIX_ANONYMOUS(U) && \
|
||||
unix_sk(U)->addr->hash < UNIX_HASH_SIZE)
|
||||
#define UNIX_FS(U) (!UNIX_ANONYMOUS(U) && unix_sk(U)->addr->name->sun_path[0])
|
||||
#define unix_peer(sk) (unix_sk(sk)->peer)
|
||||
#define unix_connected(S) ((S)->state == SS_CONNECTED)
|
||||
|
||||
static inline void print_unix_addr(struct sockaddr_un *A, int L)
|
||||
{
|
||||
char *buf = (A) ? (char *) &(A)->sun_path : NULL;
|
||||
int len = unix_addr_len(L);
|
||||
|
||||
if (!buf || len <= 0)
|
||||
pr_warn(" <anonymous>");
|
||||
else if (buf[0])
|
||||
pr_warn(" %s", buf);
|
||||
else
|
||||
/* abstract name len includes leading \0 */
|
||||
pr_warn(" %d @%.*s", len - 1, len - 1, buf+1);
|
||||
};
|
||||
|
||||
#define print_unix_sk(SK) \
|
||||
do { \
|
||||
struct unix_sock *u = unix_sk(SK); \
|
||||
\
|
||||
pr_warn("%s: f %d, t %d, p %d", #SK, \
|
||||
(SK)->sk_family, (SK)->sk_type, (SK)->sk_protocol); \
|
||||
if (u->addr) \
|
||||
print_unix_addr(u->addr->name, u->addr->len); \
|
||||
else \
|
||||
print_unix_addr(NULL, sizeof(sa_family_t)); \
|
||||
} while (0)
|
||||
|
||||
#define print_sk(SK) \
|
||||
do { \
|
||||
if (!(SK)) { \
|
||||
pr_warn("%s: %s is null\n", __func__, #SK); \
|
||||
} else if ((SK)->sk_family == PF_UNIX) { \
|
||||
print_unix_sk(SK); \
|
||||
pr_warn("\n"); \
|
||||
} else { \
|
||||
pr_warn("%s: %s: family %d\n", __func__, #SK, \
|
||||
(SK)->sk_family); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define print_sock_addr(U) \
|
||||
do { \
|
||||
pr_warn("%s:\n", __func__); \
|
||||
pr_warn" sock %s:", sock_ctx && sock_ctx->label ? \
|
||||
aa_label_printk(sock_ctx->label, GFP_ATOMIC); : \
|
||||
"<null>"); print_sk(sock); \
|
||||
pr_warn(" other %s:", other_ctx && other_ctx->label ? \
|
||||
aa_label_printk(other_ctx->label, GFP_ATOMIC); : \
|
||||
"<null>"); print_sk(other); \
|
||||
pr_warn(" new %s", new_ctx && new_ctx->label ? \
|
||||
aa_label_printk(new_ctx->label, GFP_ATOMIC); : \
|
||||
"<null>"); print_sk(newsk); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
|
||||
int aa_unix_peer_perm(const struct cred *subj_cred,
|
||||
struct aa_label *label, const char *op, u32 request,
|
||||
struct sock *sk, struct sock *peer_sk,
|
||||
struct aa_label *peer_label);
|
||||
int aa_unix_label_sk_perm(const struct cred *subj_cred,
|
||||
struct aa_label *label, const char *op, u32 request,
|
||||
struct sock *sk);
|
||||
int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock);
|
||||
int aa_unix_create_perm(struct aa_label *label, int family, int type,
|
||||
int protocol);
|
||||
int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address,
|
||||
int addrlen);
|
||||
int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
|
||||
int addrlen);
|
||||
int aa_unix_listen_perm(struct socket *sock, int backlog);
|
||||
int aa_unix_accept_perm(struct socket *sock, struct socket *newsock);
|
||||
int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
|
||||
struct msghdr *msg, int size);
|
||||
int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level,
|
||||
int optname);
|
||||
int aa_unix_file_perm(const struct cred *subj_cred,
|
||||
struct aa_label *label, const char *op, u32 request,
|
||||
struct socket *sock);
|
||||
|
||||
#endif /* __AA_AF_UNIX_H */
|
||||
@@ -83,6 +83,10 @@ aa_state_t aa_str_perms(struct aa_policydb *file_rules, aa_state_t start,
|
||||
const char *name, struct path_cond *cond,
|
||||
struct aa_perms *perms);
|
||||
|
||||
int __aa_path_perm(const char *op, const struct cred *subj_cred,
|
||||
struct aa_profile *profile, const char *name,
|
||||
u32 request, struct path_cond *cond, int flags,
|
||||
struct aa_perms *perms);
|
||||
int aa_path_perm(const char *op, const struct cred *subj_cred,
|
||||
struct aa_label *label, const struct path *path,
|
||||
int flags, u32 request, struct path_cond *cond);
|
||||
|
||||
@@ -261,7 +261,10 @@ for ((I).i = (I).j = 0; \
|
||||
struct label_it i; \
|
||||
int ret = 0; \
|
||||
label_for_each(i, (L), profile) { \
|
||||
if (RULE_MEDIATES(&profile->rules, (C))) { \
|
||||
struct aa_ruleset *rules = \
|
||||
list_first_entry(&profile->rules, typeof(*rules),\
|
||||
list); \
|
||||
if (RULE_MEDIATES(rules, (C))) { \
|
||||
ret = 1; \
|
||||
break; \
|
||||
} \
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
struct aa_sk_ctx {
|
||||
struct aa_label *label;
|
||||
struct aa_label *peer;
|
||||
struct path path;
|
||||
};
|
||||
|
||||
static inline bool aa_secmark(void)
|
||||
@@ -92,6 +93,9 @@ struct aa_net_compat {
|
||||
({ \
|
||||
int __e; \
|
||||
switch ((FAMILY)) { \
|
||||
case AF_UNIX: \
|
||||
__e = aa_unix_ ## FN; \
|
||||
break; \
|
||||
default: \
|
||||
__e = DEF_FN; \
|
||||
} \
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
enum path_flags {
|
||||
PATH_IS_DIR = 0x1, /* path is a directory */
|
||||
PATH_SOCK_COND = 0x2,
|
||||
PATH_CONNECT_PATH = 0x4, /* connect disconnected paths to / */
|
||||
PATH_CHROOT_REL = 0x8, /* do path lookup relative to chroot */
|
||||
PATH_CHROOT_NSCONNECT = 0x10, /* connect paths that are at ns root */
|
||||
|
||||
@@ -309,8 +309,11 @@ static inline aa_state_t RULE_MEDIATES_AF(struct aa_ruleset *rules, u16 AF)
|
||||
aa_state_t state = RULE_MEDIATES(rules, AA_CLASS_NET);
|
||||
__be16 be_af = cpu_to_be16(AF);
|
||||
|
||||
if (!state)
|
||||
return DFA_NOMATCH;
|
||||
if (!state) {
|
||||
state = RULE_MEDIATES(rules, AA_CLASS_NET_COMPAT);
|
||||
if (!state)
|
||||
return DFA_NOMATCH;
|
||||
}
|
||||
return aa_dfa_match_len(rules->policy->dfa, state, (char *) &be_af, 2);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user