diff options
author | David S. Miller <davem@davemloft.net> | 2017-10-30 01:10:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-10-30 08:09:24 -0400 |
commit | e1ea2f9856b765a2eaabb403a6751f70efc9ba4c (patch) | |
tree | 771f0f96fdab1b27757730e96d911c73f5499ee4 /security | |
parent | aad93c70b9a3b80dbc383a31e77a119f69bdd856 (diff) | |
parent | 0b07194bb55ed836c2cc7c22e866b87a14681984 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Several conflicts here.
NFP driver bug fix adding nfp_netdev_is_nfp_repr() check to
nfp_fl_output() needed some adjustments because the code block is in
an else block now.
Parallel additions to net/pkt_cls.h and net/sch_generic.h
A bug fix in __tcp_retransmit_skb() conflicted with some of
the rbtree changes in net-next.
The tc action RCU callback fixes in 'net' had some overlap with some
of the recent tcf_block reworking.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'security')
-rw-r--r-- | security/apparmor/.gitignore | 1 | ||||
-rw-r--r-- | security/apparmor/Makefile | 43 | ||||
-rw-r--r-- | security/apparmor/apparmorfs.c | 1 | ||||
-rw-r--r-- | security/apparmor/file.c | 30 | ||||
-rw-r--r-- | security/apparmor/include/audit.h | 26 | ||||
-rw-r--r-- | security/apparmor/include/net.h | 114 | ||||
-rw-r--r-- | security/apparmor/include/perms.h | 5 | ||||
-rw-r--r-- | security/apparmor/include/policy.h | 13 | ||||
-rw-r--r-- | security/apparmor/lib.c | 5 | ||||
-rw-r--r-- | security/apparmor/lsm.c | 387 | ||||
-rw-r--r-- | security/apparmor/net.c | 184 | ||||
-rw-r--r-- | security/apparmor/policy_unpack.c | 47 |
12 files changed, 16 insertions, 840 deletions
diff --git a/security/apparmor/.gitignore b/security/apparmor/.gitignore index d5b291e94264..9cdec70d72b8 100644 --- a/security/apparmor/.gitignore +++ b/security/apparmor/.gitignore | |||
@@ -1,6 +1,5 @@ | |||
1 | # | 1 | # |
2 | # Generated include files | 2 | # Generated include files |
3 | # | 3 | # |
4 | net_names.h | ||
5 | capability_names.h | 4 | capability_names.h |
6 | rlim_names.h | 5 | rlim_names.h |
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile index dafdd387d42b..81a34426d024 100644 --- a/security/apparmor/Makefile +++ b/security/apparmor/Makefile | |||
@@ -4,44 +4,11 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o | |||
4 | 4 | ||
5 | apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \ | 5 | apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \ |
6 | path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \ | 6 | path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \ |
7 | resource.o secid.o file.o policy_ns.o label.o mount.o net.o | 7 | resource.o secid.o file.o policy_ns.o label.o mount.o |
8 | apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o | 8 | apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o |
9 | 9 | ||
10 | clean-files := capability_names.h rlim_names.h net_names.h | 10 | clean-files := capability_names.h rlim_names.h |
11 | 11 | ||
12 | # Build a lower case string table of address family names | ||
13 | # Transform lines from | ||
14 | # #define AF_LOCAL 1 /* POSIX name for AF_UNIX */ | ||
15 | # #define AF_INET 2 /* Internet IP Protocol */ | ||
16 | # to | ||
17 | # [1] = "local", | ||
18 | # [2] = "inet", | ||
19 | # | ||
20 | # and build the securityfs entries for the mapping. | ||
21 | # Transforms lines from | ||
22 | # #define AF_INET 2 /* Internet IP Protocol */ | ||
23 | # to | ||
24 | # #define AA_SFS_AF_MASK "local inet" | ||
25 | quiet_cmd_make-af = GEN $@ | ||
26 | cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\ | ||
27 | sed $< >>$@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "/AF_ROUTE/d" -e \ | ||
28 | 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\ | ||
29 | echo "};" >> $@ ;\ | ||
30 | printf '%s' '\#define AA_SFS_AF_MASK "' >> $@ ;\ | ||
31 | sed -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "/AF_ROUTE/d" -e \ | ||
32 | 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/\L\1/p'\ | ||
33 | $< | tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@ | ||
34 | |||
35 | # Build a lower case string table of sock type names | ||
36 | # Transform lines from | ||
37 | # SOCK_STREAM = 1, | ||
38 | # to | ||
39 | # [1] = "stream", | ||
40 | quiet_cmd_make-sock = GEN $@ | ||
41 | cmd_make-sock = echo "static const char *sock_type_names[] = {" >> $@ ;\ | ||
42 | sed $^ >>$@ -r -n \ | ||
43 | -e 's/^\tSOCK_([A-Z0-9_]+)[\t]+=[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\ | ||
44 | echo "};" >> $@ | ||
45 | 12 | ||
46 | # Build a lower case string table of capability names | 13 | # Build a lower case string table of capability names |
47 | # Transforms lines from | 14 | # Transforms lines from |
@@ -94,7 +61,6 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \ | |||
94 | tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@ | 61 | tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@ |
95 | 62 | ||
96 | $(obj)/capability.o : $(obj)/capability_names.h | 63 | $(obj)/capability.o : $(obj)/capability_names.h |
97 | $(obj)/net.o : $(obj)/net_names.h | ||
98 | $(obj)/resource.o : $(obj)/rlim_names.h | 64 | $(obj)/resource.o : $(obj)/rlim_names.h |
99 | $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \ | 65 | $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \ |
100 | $(src)/Makefile | 66 | $(src)/Makefile |
@@ -102,8 +68,3 @@ $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \ | |||
102 | $(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \ | 68 | $(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \ |
103 | $(src)/Makefile | 69 | $(src)/Makefile |
104 | $(call cmd,make-rlim) | 70 | $(call cmd,make-rlim) |
105 | $(obj)/net_names.h : $(srctree)/include/linux/socket.h \ | ||
106 | $(srctree)/include/linux/net.h \ | ||
107 | $(src)/Makefile | ||
108 | $(call cmd,make-af) | ||
109 | $(call cmd,make-sock) | ||
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index 518d5928661b..caaf51dda648 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c | |||
@@ -2202,7 +2202,6 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = { | |||
2202 | AA_SFS_DIR("policy", aa_sfs_entry_policy), | 2202 | AA_SFS_DIR("policy", aa_sfs_entry_policy), |
2203 | AA_SFS_DIR("domain", aa_sfs_entry_domain), | 2203 | AA_SFS_DIR("domain", aa_sfs_entry_domain), |
2204 | AA_SFS_DIR("file", aa_sfs_entry_file), | 2204 | AA_SFS_DIR("file", aa_sfs_entry_file), |
2205 | AA_SFS_DIR("network", aa_sfs_entry_network), | ||
2206 | AA_SFS_DIR("mount", aa_sfs_entry_mount), | 2205 | AA_SFS_DIR("mount", aa_sfs_entry_mount), |
2207 | AA_SFS_DIR("namespaces", aa_sfs_entry_ns), | 2206 | AA_SFS_DIR("namespaces", aa_sfs_entry_ns), |
2208 | AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK), | 2207 | AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK), |
diff --git a/security/apparmor/file.c b/security/apparmor/file.c index db80221891c6..3382518b87fa 100644 --- a/security/apparmor/file.c +++ b/security/apparmor/file.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include "include/context.h" | 21 | #include "include/context.h" |
22 | #include "include/file.h" | 22 | #include "include/file.h" |
23 | #include "include/match.h" | 23 | #include "include/match.h" |
24 | #include "include/net.h" | ||
25 | #include "include/path.h" | 24 | #include "include/path.h" |
26 | #include "include/policy.h" | 25 | #include "include/policy.h" |
27 | #include "include/label.h" | 26 | #include "include/label.h" |
@@ -567,32 +566,6 @@ static int __file_path_perm(const char *op, struct aa_label *label, | |||
567 | return error; | 566 | return error; |
568 | } | 567 | } |
569 | 568 | ||
570 | static int __file_sock_perm(const char *op, struct aa_label *label, | ||
571 | struct aa_label *flabel, struct file *file, | ||
572 | u32 request, u32 denied) | ||
573 | { | ||
574 | struct socket *sock = (struct socket *) file->private_data; | ||
575 | int error; | ||
576 | |||
577 | AA_BUG(!sock); | ||
578 | |||
579 | /* revalidation due to label out of date. No revocation at this time */ | ||
580 | if (!denied && aa_label_is_subset(flabel, label)) | ||
581 | return 0; | ||
582 | |||
583 | /* TODO: improve to skip profiles cached in flabel */ | ||
584 | error = aa_sock_file_perm(label, op, request, sock); | ||
585 | if (denied) { | ||
586 | /* TODO: improve to skip profiles checked above */ | ||
587 | /* check every profile in file label to is cached */ | ||
588 | last_error(error, aa_sock_file_perm(flabel, op, request, sock)); | ||
589 | } | ||
590 | if (!error) | ||
591 | update_file_ctx(file_ctx(file), label, request); | ||
592 | |||
593 | return error; | ||
594 | } | ||
595 | |||
596 | /** | 569 | /** |
597 | * aa_file_perm - do permission revalidation check & audit for @file | 570 | * aa_file_perm - do permission revalidation check & audit for @file |
598 | * @op: operation being checked | 571 | * @op: operation being checked |
@@ -637,9 +610,6 @@ int aa_file_perm(const char *op, struct aa_label *label, struct file *file, | |||
637 | error = __file_path_perm(op, label, flabel, file, request, | 610 | error = __file_path_perm(op, label, flabel, file, request, |
638 | denied); | 611 | denied); |
639 | 612 | ||
640 | else if (S_ISSOCK(file_inode(file)->i_mode)) | ||
641 | error = __file_sock_perm(op, label, flabel, file, request, | ||
642 | denied); | ||
643 | done: | 613 | done: |
644 | rcu_read_unlock(); | 614 | rcu_read_unlock(); |
645 | 615 | ||
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h index ff4316e1068d..620e81169659 100644 --- a/security/apparmor/include/audit.h +++ b/security/apparmor/include/audit.h | |||
@@ -121,29 +121,21 @@ struct apparmor_audit_data { | |||
121 | /* these entries require a custom callback fn */ | 121 | /* these entries require a custom callback fn */ |
122 | struct { | 122 | struct { |
123 | struct aa_label *peer; | 123 | struct aa_label *peer; |
124 | union { | 124 | struct { |
125 | struct { | 125 | const char *target; |
126 | kuid_t ouid; | 126 | kuid_t ouid; |
127 | const char *target; | 127 | } fs; |
128 | } fs; | ||
129 | struct { | ||
130 | int type, protocol; | ||
131 | struct sock *peer_sk; | ||
132 | void *addr; | ||
133 | int addrlen; | ||
134 | } net; | ||
135 | int signal; | ||
136 | struct { | ||
137 | int rlim; | ||
138 | unsigned long max; | ||
139 | } rlim; | ||
140 | }; | ||
141 | }; | 128 | }; |
142 | struct { | 129 | struct { |
143 | struct aa_profile *profile; | 130 | struct aa_profile *profile; |
144 | const char *ns; | 131 | const char *ns; |
145 | long pos; | 132 | long pos; |
146 | } iface; | 133 | } iface; |
134 | int signal; | ||
135 | struct { | ||
136 | int rlim; | ||
137 | unsigned long max; | ||
138 | } rlim; | ||
147 | struct { | 139 | struct { |
148 | const char *src_name; | 140 | const char *src_name; |
149 | const char *type; | 141 | const char *type; |
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h deleted file mode 100644 index 140c8efcf364..000000000000 --- a/security/apparmor/include/net.h +++ /dev/null | |||
@@ -1,114 +0,0 @@ | |||
1 | /* | ||
2 | * AppArmor security module | ||
3 | * | ||
4 | * This file contains AppArmor network mediation definitions. | ||
5 | * | ||
6 | * Copyright (C) 1998-2008 Novell/SUSE | ||
7 | * Copyright 2009-2017 Canonical Ltd. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation, version 2 of the | ||
12 | * License. | ||
13 | */ | ||
14 | |||
15 | #ifndef __AA_NET_H | ||
16 | #define __AA_NET_H | ||
17 | |||
18 | #include <net/sock.h> | ||
19 | #include <linux/path.h> | ||
20 | |||
21 | #include "apparmorfs.h" | ||
22 | #include "label.h" | ||
23 | #include "perms.h" | ||
24 | #include "policy.h" | ||
25 | |||
26 | #define AA_MAY_SEND AA_MAY_WRITE | ||
27 | #define AA_MAY_RECEIVE AA_MAY_READ | ||
28 | |||
29 | #define AA_MAY_SHUTDOWN AA_MAY_DELETE | ||
30 | |||
31 | #define AA_MAY_CONNECT AA_MAY_OPEN | ||
32 | #define AA_MAY_ACCEPT 0x00100000 | ||
33 | |||
34 | #define AA_MAY_BIND 0x00200000 | ||
35 | #define AA_MAY_LISTEN 0x00400000 | ||
36 | |||
37 | #define AA_MAY_SETOPT 0x01000000 | ||
38 | #define AA_MAY_GETOPT 0x02000000 | ||
39 | |||
40 | #define NET_PERMS_MASK (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CREATE | \ | ||
41 | AA_MAY_SHUTDOWN | AA_MAY_BIND | AA_MAY_LISTEN | \ | ||
42 | AA_MAY_CONNECT | AA_MAY_ACCEPT | AA_MAY_SETATTR | \ | ||
43 | AA_MAY_GETATTR | AA_MAY_SETOPT | AA_MAY_GETOPT) | ||
44 | |||
45 | #define NET_FS_PERMS (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CREATE | \ | ||
46 | AA_MAY_SHUTDOWN | AA_MAY_CONNECT | AA_MAY_RENAME |\ | ||
47 | AA_MAY_SETATTR | AA_MAY_GETATTR | AA_MAY_CHMOD | \ | ||
48 | AA_MAY_CHOWN | AA_MAY_CHGRP | AA_MAY_LOCK | \ | ||
49 | AA_MAY_MPROT) | ||
50 | |||
51 | #define NET_PEER_MASK (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CONNECT | \ | ||
52 | AA_MAY_ACCEPT) | ||
53 | struct aa_sk_ctx { | ||
54 | struct aa_label *label; | ||
55 | struct aa_label *peer; | ||
56 | struct path path; | ||
57 | }; | ||
58 | |||
59 | #define SK_CTX(X) ((X)->sk_security) | ||
60 | #define SOCK_ctx(X) SOCK_INODE(X)->i_security | ||
61 | #define DEFINE_AUDIT_NET(NAME, OP, SK, F, T, P) \ | ||
62 | struct lsm_network_audit NAME ## _net = { .sk = (SK), \ | ||
63 | .family = (F)}; \ | ||
64 | DEFINE_AUDIT_DATA(NAME, \ | ||
65 | ((SK) && (F) != AF_UNIX) ? LSM_AUDIT_DATA_NET : \ | ||
66 | LSM_AUDIT_DATA_NONE, \ | ||
67 | OP); \ | ||
68 | NAME.u.net = &(NAME ## _net); \ | ||
69 | aad(&NAME)->net.type = (T); \ | ||
70 | aad(&NAME)->net.protocol = (P) | ||
71 | |||
72 | #define DEFINE_AUDIT_SK(NAME, OP, SK) \ | ||
73 | DEFINE_AUDIT_NET(NAME, OP, SK, (SK)->sk_family, (SK)->sk_type, \ | ||
74 | (SK)->sk_protocol) | ||
75 | |||
76 | /* struct aa_net - network confinement data | ||
77 | * @allow: basic network families permissions | ||
78 | * @audit: which network permissions to force audit | ||
79 | * @quiet: which network permissions to quiet rejects | ||
80 | */ | ||
81 | struct aa_net { | ||
82 | u16 allow[AF_MAX]; | ||
83 | u16 audit[AF_MAX]; | ||
84 | u16 quiet[AF_MAX]; | ||
85 | }; | ||
86 | |||
87 | |||
88 | extern struct aa_sfs_entry aa_sfs_entry_network[]; | ||
89 | |||
90 | void audit_net_cb(struct audit_buffer *ab, void *va); | ||
91 | int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa, | ||
92 | u32 request, u16 family, int type); | ||
93 | int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, | ||
94 | int type, int protocol); | ||
95 | static inline int aa_profile_af_sk_perm(struct aa_profile *profile, | ||
96 | struct common_audit_data *sa, | ||
97 | u32 request, | ||
98 | struct sock *sk) | ||
99 | { | ||
100 | return aa_profile_af_perm(profile, sa, request, sk->sk_family, | ||
101 | sk->sk_type); | ||
102 | } | ||
103 | int aa_sk_perm(const char *op, u32 request, struct sock *sk); | ||
104 | |||
105 | int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, | ||
106 | struct socket *sock); | ||
107 | |||
108 | |||
109 | static inline void aa_free_net_rules(struct aa_net *new) | ||
110 | { | ||
111 | /* NOP */ | ||
112 | } | ||
113 | |||
114 | #endif /* __AA_NET_H */ | ||
diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h index af04d5a7d73d..2b27bb79aec4 100644 --- a/security/apparmor/include/perms.h +++ b/security/apparmor/include/perms.h | |||
@@ -135,10 +135,9 @@ extern struct aa_perms allperms; | |||
135 | 135 | ||
136 | 136 | ||
137 | void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask); | 137 | void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask); |
138 | void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names, | 138 | void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask); |
139 | u32 mask); | ||
140 | void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, | 139 | void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, |
141 | u32 chrsmask, const char * const *names, u32 namesmask); | 140 | u32 chrsmask, const char **names, u32 namesmask); |
142 | void aa_apply_modes_to_perms(struct aa_profile *profile, | 141 | void aa_apply_modes_to_perms(struct aa_profile *profile, |
143 | struct aa_perms *perms); | 142 | struct aa_perms *perms); |
144 | void aa_compute_perms(struct aa_dfa *dfa, unsigned int state, | 143 | void aa_compute_perms(struct aa_dfa *dfa, unsigned int state, |
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index 4364088a0b9e..17fe41a9cac3 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h | |||
@@ -30,7 +30,6 @@ | |||
30 | #include "file.h" | 30 | #include "file.h" |
31 | #include "lib.h" | 31 | #include "lib.h" |
32 | #include "label.h" | 32 | #include "label.h" |
33 | #include "net.h" | ||
34 | #include "perms.h" | 33 | #include "perms.h" |
35 | #include "resource.h" | 34 | #include "resource.h" |
36 | 35 | ||
@@ -112,7 +111,6 @@ struct aa_data { | |||
112 | * @policy: general match rules governing policy | 111 | * @policy: general match rules governing policy |
113 | * @file: The set of rules governing basic file access and domain transitions | 112 | * @file: The set of rules governing basic file access and domain transitions |
114 | * @caps: capabilities for the profile | 113 | * @caps: capabilities for the profile |
115 | * @net: network controls for the profile | ||
116 | * @rlimits: rlimits for the profile | 114 | * @rlimits: rlimits for the profile |
117 | * | 115 | * |
118 | * @dents: dentries for the profiles file entries in apparmorfs | 116 | * @dents: dentries for the profiles file entries in apparmorfs |
@@ -150,7 +148,6 @@ struct aa_profile { | |||
150 | struct aa_policydb policy; | 148 | struct aa_policydb policy; |
151 | struct aa_file_rules file; | 149 | struct aa_file_rules file; |
152 | struct aa_caps caps; | 150 | struct aa_caps caps; |
153 | struct aa_net net; | ||
154 | struct aa_rlimit rlimits; | 151 | struct aa_rlimit rlimits; |
155 | 152 | ||
156 | struct aa_loaddata *rawdata; | 153 | struct aa_loaddata *rawdata; |
@@ -223,16 +220,6 @@ static inline unsigned int PROFILE_MEDIATES_SAFE(struct aa_profile *profile, | |||
223 | return 0; | 220 | return 0; |
224 | } | 221 | } |
225 | 222 | ||
226 | static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile, | ||
227 | u16 AF) { | ||
228 | unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET); | ||
229 | u16 be_af = cpu_to_be16(AF); | ||
230 | |||
231 | if (!state) | ||
232 | return 0; | ||
233 | return aa_dfa_match_len(profile->policy.dfa, state, (char *) &be_af, 2); | ||
234 | } | ||
235 | |||
236 | /** | 223 | /** |
237 | * aa_get_profile - increment refcount on profile @p | 224 | * aa_get_profile - increment refcount on profile @p |
238 | * @p: profile (MAYBE NULL) | 225 | * @p: profile (MAYBE NULL) |
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c index 8818621b5d95..08ca26bcca77 100644 --- a/security/apparmor/lib.c +++ b/security/apparmor/lib.c | |||
@@ -211,8 +211,7 @@ void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask) | |||
211 | *str = '\0'; | 211 | *str = '\0'; |
212 | } | 212 | } |
213 | 213 | ||
214 | void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names, | 214 | void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask) |
215 | u32 mask) | ||
216 | { | 215 | { |
217 | const char *fmt = "%s"; | 216 | const char *fmt = "%s"; |
218 | unsigned int i, perm = 1; | 217 | unsigned int i, perm = 1; |
@@ -230,7 +229,7 @@ void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names, | |||
230 | } | 229 | } |
231 | 230 | ||
232 | void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, | 231 | void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, |
233 | u32 chrsmask, const char * const *names, u32 namesmask) | 232 | u32 chrsmask, const char **names, u32 namesmask) |
234 | { | 233 | { |
235 | char str[33]; | 234 | char str[33]; |
236 | 235 | ||
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 72b915dfcaf7..1346ee5be04f 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include "include/context.h" | 33 | #include "include/context.h" |
34 | #include "include/file.h" | 34 | #include "include/file.h" |
35 | #include "include/ipc.h" | 35 | #include "include/ipc.h" |
36 | #include "include/net.h" | ||
37 | #include "include/path.h" | 36 | #include "include/path.h" |
38 | #include "include/label.h" | 37 | #include "include/label.h" |
39 | #include "include/policy.h" | 38 | #include "include/policy.h" |
@@ -737,368 +736,6 @@ static int apparmor_task_kill(struct task_struct *target, struct siginfo *info, | |||
737 | return error; | 736 | return error; |
738 | } | 737 | } |
739 | 738 | ||
740 | /** | ||
741 | * apparmor_sk_alloc_security - allocate and attach the sk_security field | ||
742 | */ | ||
743 | static int apparmor_sk_alloc_security(struct sock *sk, int family, gfp_t flags) | ||
744 | { | ||
745 | struct aa_sk_ctx *ctx; | ||
746 | |||
747 | ctx = kzalloc(sizeof(*ctx), flags); | ||
748 | if (!ctx) | ||
749 | return -ENOMEM; | ||
750 | |||
751 | SK_CTX(sk) = ctx; | ||
752 | |||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | /** | ||
757 | * apparmor_sk_free_security - free the sk_security field | ||
758 | */ | ||
759 | static void apparmor_sk_free_security(struct sock *sk) | ||
760 | { | ||
761 | struct aa_sk_ctx *ctx = SK_CTX(sk); | ||
762 | |||
763 | SK_CTX(sk) = NULL; | ||
764 | aa_put_label(ctx->label); | ||
765 | aa_put_label(ctx->peer); | ||
766 | path_put(&ctx->path); | ||
767 | kfree(ctx); | ||
768 | } | ||
769 | |||
770 | /** | ||
771 | * apparmor_clone_security - clone the sk_security field | ||
772 | */ | ||
773 | static void apparmor_sk_clone_security(const struct sock *sk, | ||
774 | struct sock *newsk) | ||
775 | { | ||
776 | struct aa_sk_ctx *ctx = SK_CTX(sk); | ||
777 | struct aa_sk_ctx *new = SK_CTX(newsk); | ||
778 | |||
779 | new->label = aa_get_label(ctx->label); | ||
780 | new->peer = aa_get_label(ctx->peer); | ||
781 | new->path = ctx->path; | ||
782 | path_get(&new->path); | ||
783 | } | ||
784 | |||
785 | static int aa_sock_create_perm(struct aa_label *label, int family, int type, | ||
786 | int protocol) | ||
787 | { | ||
788 | AA_BUG(!label); | ||
789 | AA_BUG(in_interrupt()); | ||
790 | |||
791 | return aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family, type, | ||
792 | protocol); | ||
793 | } | ||
794 | |||
795 | |||
796 | /** | ||
797 | * apparmor_socket_create - check perms before creating a new socket | ||
798 | */ | ||
799 | static int apparmor_socket_create(int family, int type, int protocol, int kern) | ||
800 | { | ||
801 | struct aa_label *label; | ||
802 | int error = 0; | ||
803 | |||
804 | label = begin_current_label_crit_section(); | ||
805 | if (!(kern || unconfined(label))) | ||
806 | error = aa_sock_create_perm(label, family, type, protocol); | ||
807 | end_current_label_crit_section(label); | ||
808 | |||
809 | return error; | ||
810 | } | ||
811 | |||
812 | /** | ||
813 | * apparmor_socket_post_create - setup the per-socket security struct | ||
814 | * | ||
815 | * Note: | ||
816 | * - kernel sockets currently labeled unconfined but we may want to | ||
817 | * move to a special kernel label | ||
818 | * - socket may not have sk here if created with sock_create_lite or | ||
819 | * sock_alloc. These should be accept cases which will be handled in | ||
820 | * sock_graft. | ||
821 | */ | ||
822 | static int apparmor_socket_post_create(struct socket *sock, int family, | ||
823 | int type, int protocol, int kern) | ||
824 | { | ||
825 | struct aa_label *label; | ||
826 | |||
827 | if (kern) { | ||
828 | struct aa_ns *ns = aa_get_current_ns(); | ||
829 | |||
830 | label = aa_get_label(ns_unconfined(ns)); | ||
831 | aa_put_ns(ns); | ||
832 | } else | ||
833 | label = aa_get_current_label(); | ||
834 | |||
835 | if (sock->sk) { | ||
836 | struct aa_sk_ctx *ctx = SK_CTX(sock->sk); | ||
837 | |||
838 | aa_put_label(ctx->label); | ||
839 | ctx->label = aa_get_label(label); | ||
840 | } | ||
841 | aa_put_label(label); | ||
842 | |||
843 | return 0; | ||
844 | } | ||
845 | |||
846 | /** | ||
847 | * apparmor_socket_bind - check perms before bind addr to socket | ||
848 | */ | ||
849 | static int apparmor_socket_bind(struct socket *sock, | ||
850 | struct sockaddr *address, int addrlen) | ||
851 | { | ||
852 | AA_BUG(!sock); | ||
853 | AA_BUG(!sock->sk); | ||
854 | AA_BUG(!address); | ||
855 | AA_BUG(in_interrupt()); | ||
856 | |||
857 | return aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk); | ||
858 | } | ||
859 | |||
860 | /** | ||
861 | * apparmor_socket_connect - check perms before connecting @sock to @address | ||
862 | */ | ||
863 | static int apparmor_socket_connect(struct socket *sock, | ||
864 | struct sockaddr *address, int addrlen) | ||
865 | { | ||
866 | AA_BUG(!sock); | ||
867 | AA_BUG(!sock->sk); | ||
868 | AA_BUG(!address); | ||
869 | AA_BUG(in_interrupt()); | ||
870 | |||
871 | return aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk); | ||
872 | } | ||
873 | |||
874 | /** | ||
875 | * apparmor_socket_list - check perms before allowing listen | ||
876 | */ | ||
877 | static int apparmor_socket_listen(struct socket *sock, int backlog) | ||
878 | { | ||
879 | AA_BUG(!sock); | ||
880 | AA_BUG(!sock->sk); | ||
881 | AA_BUG(in_interrupt()); | ||
882 | |||
883 | return aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk); | ||
884 | } | ||
885 | |||
886 | /** | ||
887 | * apparmor_socket_accept - check perms before accepting a new connection. | ||
888 | * | ||
889 | * Note: while @newsock is created and has some information, the accept | ||
890 | * has not been done. | ||
891 | */ | ||
892 | static int apparmor_socket_accept(struct socket *sock, struct socket *newsock) | ||
893 | { | ||
894 | AA_BUG(!sock); | ||
895 | AA_BUG(!sock->sk); | ||
896 | AA_BUG(!newsock); | ||
897 | AA_BUG(in_interrupt()); | ||
898 | |||
899 | return aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk); | ||
900 | } | ||
901 | |||
902 | static int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock, | ||
903 | struct msghdr *msg, int size) | ||
904 | { | ||
905 | AA_BUG(!sock); | ||
906 | AA_BUG(!sock->sk); | ||
907 | AA_BUG(!msg); | ||
908 | AA_BUG(in_interrupt()); | ||
909 | |||
910 | return aa_sk_perm(op, request, sock->sk); | ||
911 | } | ||
912 | |||
913 | /** | ||
914 | * apparmor_socket_sendmsg - check perms before sending msg to another socket | ||
915 | */ | ||
916 | static int apparmor_socket_sendmsg(struct socket *sock, | ||
917 | struct msghdr *msg, int size) | ||
918 | { | ||
919 | return aa_sock_msg_perm(OP_SENDMSG, AA_MAY_SEND, sock, msg, size); | ||
920 | } | ||
921 | |||
922 | /** | ||
923 | * apparmor_socket_recvmsg - check perms before receiving a message | ||
924 | */ | ||
925 | static int apparmor_socket_recvmsg(struct socket *sock, | ||
926 | struct msghdr *msg, int size, int flags) | ||
927 | { | ||
928 | return aa_sock_msg_perm(OP_RECVMSG, AA_MAY_RECEIVE, sock, msg, size); | ||
929 | } | ||
930 | |||
931 | /* revaliation, get/set attr, shutdown */ | ||
932 | static int aa_sock_perm(const char *op, u32 request, struct socket *sock) | ||
933 | { | ||
934 | AA_BUG(!sock); | ||
935 | AA_BUG(!sock->sk); | ||
936 | AA_BUG(in_interrupt()); | ||
937 | |||
938 | return aa_sk_perm(op, request, sock->sk); | ||
939 | } | ||
940 | |||
941 | /** | ||
942 | * apparmor_socket_getsockname - check perms before getting the local address | ||
943 | */ | ||
944 | static int apparmor_socket_getsockname(struct socket *sock) | ||
945 | { | ||
946 | return aa_sock_perm(OP_GETSOCKNAME, AA_MAY_GETATTR, sock); | ||
947 | } | ||
948 | |||
949 | /** | ||
950 | * apparmor_socket_getpeername - check perms before getting remote address | ||
951 | */ | ||
952 | static int apparmor_socket_getpeername(struct socket *sock) | ||
953 | { | ||
954 | return aa_sock_perm(OP_GETPEERNAME, AA_MAY_GETATTR, sock); | ||
955 | } | ||
956 | |||
957 | /* revaliation, get/set attr, opt */ | ||
958 | static int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, | ||
959 | int level, int optname) | ||
960 | { | ||
961 | AA_BUG(!sock); | ||
962 | AA_BUG(!sock->sk); | ||
963 | AA_BUG(in_interrupt()); | ||
964 | |||
965 | return aa_sk_perm(op, request, sock->sk); | ||
966 | } | ||
967 | |||
968 | /** | ||
969 | * apparmor_getsockopt - check perms before getting socket options | ||
970 | */ | ||
971 | static int apparmor_socket_getsockopt(struct socket *sock, int level, | ||
972 | int optname) | ||
973 | { | ||
974 | return aa_sock_opt_perm(OP_GETSOCKOPT, AA_MAY_GETOPT, sock, | ||
975 | level, optname); | ||
976 | } | ||
977 | |||
978 | /** | ||
979 | * apparmor_setsockopt - check perms before setting socket options | ||
980 | */ | ||
981 | static int apparmor_socket_setsockopt(struct socket *sock, int level, | ||
982 | int optname) | ||
983 | { | ||
984 | return aa_sock_opt_perm(OP_SETSOCKOPT, AA_MAY_SETOPT, sock, | ||
985 | level, optname); | ||
986 | } | ||
987 | |||
988 | /** | ||
989 | * apparmor_socket_shutdown - check perms before shutting down @sock conn | ||
990 | */ | ||
991 | static int apparmor_socket_shutdown(struct socket *sock, int how) | ||
992 | { | ||
993 | return aa_sock_perm(OP_SHUTDOWN, AA_MAY_SHUTDOWN, sock); | ||
994 | } | ||
995 | |||
996 | /** | ||
997 | * apparmor_socket_sock_recv_skb - check perms before associating skb to sk | ||
998 | * | ||
999 | * Note: can not sleep may be called with locks held | ||
1000 | * | ||
1001 | * dont want protocol specific in __skb_recv_datagram() | ||
1002 | * to deny an incoming connection socket_sock_rcv_skb() | ||
1003 | */ | ||
1004 | static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | ||
1005 | { | ||
1006 | return 0; | ||
1007 | } | ||
1008 | |||
1009 | |||
1010 | static struct aa_label *sk_peer_label(struct sock *sk) | ||
1011 | { | ||
1012 | struct aa_sk_ctx *ctx = SK_CTX(sk); | ||
1013 | |||
1014 | if (ctx->peer) | ||
1015 | return ctx->peer; | ||
1016 | |||
1017 | return ERR_PTR(-ENOPROTOOPT); | ||
1018 | } | ||
1019 | |||
1020 | /** | ||
1021 | * apparmor_socket_getpeersec_stream - get security context of peer | ||
1022 | * | ||
1023 | * Note: for tcp only valid if using ipsec or cipso on lan | ||
1024 | */ | ||
1025 | static int apparmor_socket_getpeersec_stream(struct socket *sock, | ||
1026 | char __user *optval, | ||
1027 | int __user *optlen, | ||
1028 | unsigned int len) | ||
1029 | { | ||
1030 | char *name; | ||
1031 | int slen, error = 0; | ||
1032 | struct aa_label *label; | ||
1033 | struct aa_label *peer; | ||
1034 | |||
1035 | label = begin_current_label_crit_section(); | ||
1036 | peer = sk_peer_label(sock->sk); | ||
1037 | if (IS_ERR(peer)) { | ||
1038 | error = PTR_ERR(peer); | ||
1039 | goto done; | ||
1040 | } | ||
1041 | slen = aa_label_asxprint(&name, labels_ns(label), peer, | ||
1042 | FLAG_SHOW_MODE | FLAG_VIEW_SUBNS | | ||
1043 | FLAG_HIDDEN_UNCONFINED, GFP_KERNEL); | ||
1044 | /* don't include terminating \0 in slen, it breaks some apps */ | ||
1045 | if (slen < 0) { | ||
1046 | error = -ENOMEM; | ||
1047 | } else { | ||
1048 | if (slen > len) { | ||
1049 | error = -ERANGE; | ||
1050 | } else if (copy_to_user(optval, name, slen)) { | ||
1051 | error = -EFAULT; | ||
1052 | goto out; | ||
1053 | } | ||
1054 | if (put_user(slen, optlen)) | ||
1055 | error = -EFAULT; | ||
1056 | out: | ||
1057 | kfree(name); | ||
1058 | |||
1059 | } | ||
1060 | |||
1061 | done: | ||
1062 | end_current_label_crit_section(label); | ||
1063 | |||
1064 | return error; | ||
1065 | } | ||
1066 | |||
1067 | /** | ||
1068 | * apparmor_socket_getpeersec_dgram - get security label of packet | ||
1069 | * @sock: the peer socket | ||
1070 | * @skb: packet data | ||
1071 | * @secid: pointer to where to put the secid of the packet | ||
1072 | * | ||
1073 | * Sets the netlabel socket state on sk from parent | ||
1074 | */ | ||
1075 | static int apparmor_socket_getpeersec_dgram(struct socket *sock, | ||
1076 | struct sk_buff *skb, u32 *secid) | ||
1077 | |||
1078 | { | ||
1079 | /* TODO: requires secid support */ | ||
1080 | return -ENOPROTOOPT; | ||
1081 | } | ||
1082 | |||
1083 | /** | ||
1084 | * apparmor_sock_graft - Initialize newly created socket | ||
1085 | * @sk: child sock | ||
1086 | * @parent: parent socket | ||
1087 | * | ||
1088 | * Note: could set off of SOCK_CTX(parent) but need to track inode and we can | ||
1089 | * just set sk security information off of current creating process label | ||
1090 | * Labeling of sk for accept case - probably should be sock based | ||
1091 | * instead of task, because of the case where an implicitly labeled | ||
1092 | * socket is shared by different tasks. | ||
1093 | */ | ||
1094 | static void apparmor_sock_graft(struct sock *sk, struct socket *parent) | ||
1095 | { | ||
1096 | struct aa_sk_ctx *ctx = SK_CTX(sk); | ||
1097 | |||
1098 | if (!ctx->label) | ||
1099 | ctx->label = aa_get_current_label(); | ||
1100 | } | ||
1101 | |||
1102 | static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { | 739 | static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { |
1103 | LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), | 740 | LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), |
1104 | LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), | 741 | LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), |
@@ -1133,30 +770,6 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { | |||
1133 | LSM_HOOK_INIT(getprocattr, apparmor_getprocattr), | 770 | LSM_HOOK_INIT(getprocattr, apparmor_getprocattr), |
1134 | LSM_HOOK_INIT(setprocattr, apparmor_setprocattr), | 771 | LSM_HOOK_INIT(setprocattr, apparmor_setprocattr), |
1135 | 772 | ||
1136 | LSM_HOOK_INIT(sk_alloc_security, apparmor_sk_alloc_security), | ||
1137 | LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security), | ||
1138 | LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security), | ||
1139 | |||
1140 | LSM_HOOK_INIT(socket_create, apparmor_socket_create), | ||
1141 | LSM_HOOK_INIT(socket_post_create, apparmor_socket_post_create), | ||
1142 | LSM_HOOK_INIT(socket_bind, apparmor_socket_bind), | ||
1143 | LSM_HOOK_INIT(socket_connect, apparmor_socket_connect), | ||
1144 | LSM_HOOK_INIT(socket_listen, apparmor_socket_listen), | ||
1145 | LSM_HOOK_INIT(socket_accept, apparmor_socket_accept), | ||
1146 | LSM_HOOK_INIT(socket_sendmsg, apparmor_socket_sendmsg), | ||
1147 | LSM_HOOK_INIT(socket_recvmsg, apparmor_socket_recvmsg), | ||
1148 | LSM_HOOK_INIT(socket_getsockname, apparmor_socket_getsockname), | ||
1149 | LSM_HOOK_INIT(socket_getpeername, apparmor_socket_getpeername), | ||
1150 | LSM_HOOK_INIT(socket_getsockopt, apparmor_socket_getsockopt), | ||
1151 | LSM_HOOK_INIT(socket_setsockopt, apparmor_socket_setsockopt), | ||
1152 | LSM_HOOK_INIT(socket_shutdown, apparmor_socket_shutdown), | ||
1153 | LSM_HOOK_INIT(socket_sock_rcv_skb, apparmor_socket_sock_rcv_skb), | ||
1154 | LSM_HOOK_INIT(socket_getpeersec_stream, | ||
1155 | apparmor_socket_getpeersec_stream), | ||
1156 | LSM_HOOK_INIT(socket_getpeersec_dgram, | ||
1157 | apparmor_socket_getpeersec_dgram), | ||
1158 | LSM_HOOK_INIT(sock_graft, apparmor_sock_graft), | ||
1159 | |||
1160 | LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank), | 773 | LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank), |
1161 | LSM_HOOK_INIT(cred_free, apparmor_cred_free), | 774 | LSM_HOOK_INIT(cred_free, apparmor_cred_free), |
1162 | LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare), | 775 | LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare), |
diff --git a/security/apparmor/net.c b/security/apparmor/net.c deleted file mode 100644 index 33d54435f8d6..000000000000 --- a/security/apparmor/net.c +++ /dev/null | |||
@@ -1,184 +0,0 @@ | |||
1 | /* | ||
2 | * AppArmor security module | ||
3 | * | ||
4 | * This file contains AppArmor network mediation | ||
5 | * | ||
6 | * Copyright (C) 1998-2008 Novell/SUSE | ||
7 | * Copyright 2009-2017 Canonical Ltd. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation, version 2 of the | ||
12 | * License. | ||
13 | */ | ||
14 | |||
15 | #include "include/apparmor.h" | ||
16 | #include "include/audit.h" | ||
17 | #include "include/context.h" | ||
18 | #include "include/label.h" | ||
19 | #include "include/net.h" | ||
20 | #include "include/policy.h" | ||
21 | |||
22 | #include "net_names.h" | ||
23 | |||
24 | |||
25 | struct aa_sfs_entry aa_sfs_entry_network[] = { | ||
26 | AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK), | ||
27 | { } | ||
28 | }; | ||
29 | |||
30 | static const char * const net_mask_names[] = { | ||
31 | "unknown", | ||
32 | "send", | ||
33 | "receive", | ||
34 | "unknown", | ||
35 | |||
36 | "create", | ||
37 | "shutdown", | ||
38 | "connect", | ||
39 | "unknown", | ||
40 | |||
41 | "setattr", | ||
42 | "getattr", | ||
43 | "setcred", | ||
44 | "getcred", | ||
45 | |||
46 | "chmod", | ||
47 | "chown", | ||
48 | "chgrp", | ||
49 | "lock", | ||
50 | |||
51 | "mmap", | ||
52 | "mprot", | ||
53 | "unknown", | ||
54 | "unknown", | ||
55 | |||
56 | "accept", | ||
57 | "bind", | ||
58 | "listen", | ||
59 | "unknown", | ||
60 | |||
61 | "setopt", | ||
62 | "getopt", | ||
63 | "unknown", | ||
64 | "unknown", | ||
65 | |||
66 | "unknown", | ||
67 | "unknown", | ||
68 | "unknown", | ||
69 | "unknown", | ||
70 | }; | ||
71 | |||
72 | |||
73 | /* audit callback for net specific fields */ | ||
74 | void audit_net_cb(struct audit_buffer *ab, void *va) | ||
75 | { | ||
76 | struct common_audit_data *sa = va; | ||
77 | |||
78 | audit_log_format(ab, " family="); | ||
79 | if (address_family_names[sa->u.net->family]) | ||
80 | audit_log_string(ab, address_family_names[sa->u.net->family]); | ||
81 | else | ||
82 | audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family); | ||
83 | audit_log_format(ab, " sock_type="); | ||
84 | if (sock_type_names[aad(sa)->net.type]) | ||
85 | audit_log_string(ab, sock_type_names[aad(sa)->net.type]); | ||
86 | else | ||
87 | audit_log_format(ab, "\"unknown(%d)\"", aad(sa)->net.type); | ||
88 | audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol); | ||
89 | |||
90 | if (aad(sa)->request & NET_PERMS_MASK) { | ||
91 | audit_log_format(ab, " requested_mask="); | ||
92 | aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0, | ||
93 | net_mask_names, NET_PERMS_MASK); | ||
94 | |||
95 | if (aad(sa)->denied & NET_PERMS_MASK) { | ||
96 | audit_log_format(ab, " denied_mask="); | ||
97 | aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0, | ||
98 | net_mask_names, NET_PERMS_MASK); | ||
99 | } | ||
100 | } | ||
101 | if (aad(sa)->peer) { | ||
102 | audit_log_format(ab, " peer="); | ||
103 | aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, | ||
104 | FLAGS_NONE, GFP_ATOMIC); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | |||
109 | /* Generic af perm */ | ||
110 | int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa, | ||
111 | u32 request, u16 family, int type) | ||
112 | { | ||
113 | struct aa_perms perms = { }; | ||
114 | |||
115 | AA_BUG(family >= AF_MAX); | ||
116 | AA_BUG(type < 0 || type >= SOCK_MAX); | ||
117 | |||
118 | if (profile_unconfined(profile)) | ||
119 | return 0; | ||
120 | |||
121 | perms.allow = (profile->net.allow[family] & (1 << type)) ? | ||
122 | ALL_PERMS_MASK : 0; | ||
123 | perms.audit = (profile->net.audit[family] & (1 << type)) ? | ||
124 | ALL_PERMS_MASK : 0; | ||
125 | perms.quiet = (profile->net.quiet[family] & (1 << type)) ? | ||
126 | ALL_PERMS_MASK : 0; | ||
127 | aa_apply_modes_to_perms(profile, &perms); | ||
128 | |||
129 | return aa_check_perms(profile, &perms, request, sa, audit_net_cb); | ||
130 | } | ||
131 | |||
132 | int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, | ||
133 | int type, int protocol) | ||
134 | { | ||
135 | struct aa_profile *profile; | ||
136 | DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol); | ||
137 | |||
138 | return fn_for_each_confined(label, profile, | ||
139 | aa_profile_af_perm(profile, &sa, request, family, | ||
140 | type)); | ||
141 | } | ||
142 | |||
143 | static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request, | ||
144 | struct sock *sk) | ||
145 | { | ||
146 | struct aa_profile *profile; | ||
147 | DEFINE_AUDIT_SK(sa, op, sk); | ||
148 | |||
149 | AA_BUG(!label); | ||
150 | AA_BUG(!sk); | ||
151 | |||
152 | if (unconfined(label)) | ||
153 | return 0; | ||
154 | |||
155 | return fn_for_each_confined(label, profile, | ||
156 | aa_profile_af_sk_perm(profile, &sa, request, sk)); | ||
157 | } | ||
158 | |||
159 | int aa_sk_perm(const char *op, u32 request, struct sock *sk) | ||
160 | { | ||
161 | struct aa_label *label; | ||
162 | int error; | ||
163 | |||
164 | AA_BUG(!sk); | ||
165 | AA_BUG(in_interrupt()); | ||
166 | |||
167 | /* TODO: switch to begin_current_label ???? */ | ||
168 | label = begin_current_label_crit_section(); | ||
169 | error = aa_label_sk_perm(label, op, request, sk); | ||
170 | end_current_label_crit_section(label); | ||
171 | |||
172 | return error; | ||
173 | } | ||
174 | |||
175 | |||
176 | int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, | ||
177 | struct socket *sock) | ||
178 | { | ||
179 | AA_BUG(!label); | ||
180 | AA_BUG(!sock); | ||
181 | AA_BUG(!sock->sk); | ||
182 | |||
183 | return aa_label_sk_perm(label, op, request, sock->sk); | ||
184 | } | ||
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index 5a2aec358322..4ede87c30f8b 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c | |||
@@ -275,19 +275,6 @@ fail: | |||
275 | return 0; | 275 | return 0; |
276 | } | 276 | } |
277 | 277 | ||
278 | static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name) | ||
279 | { | ||
280 | if (unpack_nameX(e, AA_U16, name)) { | ||
281 | if (!inbounds(e, sizeof(u16))) | ||
282 | return 0; | ||
283 | if (data) | ||
284 | *data = le16_to_cpu(get_unaligned((__le16 *) e->pos)); | ||
285 | e->pos += sizeof(u16); | ||
286 | return 1; | ||
287 | } | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) | 278 | static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) |
292 | { | 279 | { |
293 | if (unpack_nameX(e, AA_U32, name)) { | 280 | if (unpack_nameX(e, AA_U32, name)) { |
@@ -597,7 +584,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |||
597 | struct aa_profile *profile = NULL; | 584 | struct aa_profile *profile = NULL; |
598 | const char *tmpname, *tmpns = NULL, *name = NULL; | 585 | const char *tmpname, *tmpns = NULL, *name = NULL; |
599 | const char *info = "failed to unpack profile"; | 586 | const char *info = "failed to unpack profile"; |
600 | size_t size = 0, ns_len; | 587 | size_t ns_len; |
601 | struct rhashtable_params params = { 0 }; | 588 | struct rhashtable_params params = { 0 }; |
602 | char *key = NULL; | 589 | char *key = NULL; |
603 | struct aa_data *data; | 590 | struct aa_data *data; |
@@ -730,38 +717,6 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |||
730 | goto fail; | 717 | goto fail; |
731 | } | 718 | } |
732 | 719 | ||
733 | size = unpack_array(e, "net_allowed_af"); | ||
734 | if (size) { | ||
735 | |||
736 | for (i = 0; i < size; i++) { | ||
737 | /* discard extraneous rules that this kernel will | ||
738 | * never request | ||
739 | */ | ||
740 | if (i >= AF_MAX) { | ||
741 | u16 tmp; | ||
742 | |||
743 | if (!unpack_u16(e, &tmp, NULL) || | ||
744 | !unpack_u16(e, &tmp, NULL) || | ||
745 | !unpack_u16(e, &tmp, NULL)) | ||
746 | goto fail; | ||
747 | continue; | ||
748 | } | ||
749 | if (!unpack_u16(e, &profile->net.allow[i], NULL)) | ||
750 | goto fail; | ||
751 | if (!unpack_u16(e, &profile->net.audit[i], NULL)) | ||
752 | goto fail; | ||
753 | if (!unpack_u16(e, &profile->net.quiet[i], NULL)) | ||
754 | goto fail; | ||
755 | } | ||
756 | if (!unpack_nameX(e, AA_ARRAYEND, NULL)) | ||
757 | goto fail; | ||
758 | } | ||
759 | if (VERSION_LT(e->version, v7)) { | ||
760 | /* pre v7 policy always allowed these */ | ||
761 | profile->net.allow[AF_UNIX] = 0xffff; | ||
762 | profile->net.allow[AF_NETLINK] = 0xffff; | ||
763 | } | ||
764 | |||
765 | if (unpack_nameX(e, AA_STRUCT, "policydb")) { | 720 | if (unpack_nameX(e, AA_STRUCT, "policydb")) { |
766 | /* generic policy dfa - optional and may be NULL */ | 721 | /* generic policy dfa - optional and may be NULL */ |
767 | info = "failed to unpack policydb"; | 722 | info = "failed to unpack policydb"; |