Browse code

linux, linux-aws, linux-secure: Apply out-of-tree patches needed for AppArmor

The AppArmor source code distributes out-of-tree kernel patches that
are needed in order to support the full functionality of AppArmor.
So, import those kernel patches (as applicable to version 4.14) from
the latest available version of AppArmor, i.e., v2.13.

Change-Id: I5a261ab1ee5ecae5a636de236f89166fd8655bb5
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/5564
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Sharath George

Srivatsa S. Bhat authored on 2018/08/31 08:38:53
Showing 5 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,1110 @@
0
+From f34488a615da4b0dd68f697587f1cf13e4535e5d Mon Sep 17 00:00:00 2001
1
+From: John Johansen <john.johansen@canonical.com>
2
+Date: Tue, 18 Jul 2017 23:18:33 -0700
3
+Subject: [PATCH 1/2] apparmor: add base infastructure for socket mediation
4
+
5
+Provide a basic mediation of sockets. This is not a full net mediation
6
+but just whether a spcific family of socket can be used by an
7
+application, along with setting up some basic infrastructure for
8
+network mediation to follow.
9
+
10
+the user space rule hav the basic form of
11
+  NETWORK RULE = [ QUALIFIERS ] 'network' [ DOMAIN ]
12
+                 [ TYPE | PROTOCOL ]
13
+
14
+  DOMAIN = ( 'inet' | 'ax25' | 'ipx' | 'appletalk' | 'netrom' |
15
+             'bridge' | 'atmpvc' | 'x25' | 'inet6' | 'rose' |
16
+	     'netbeui' | 'security' | 'key' | 'packet' | 'ash' |
17
+	     'econet' | 'atmsvc' | 'sna' | 'irda' | 'pppox' |
18
+	     'wanpipe' | 'bluetooth' | 'netlink' | 'unix' | 'rds' |
19
+	     'llc' | 'can' | 'tipc' | 'iucv' | 'rxrpc' | 'isdn' |
20
+	     'phonet' | 'ieee802154' | 'caif' | 'alg' | 'nfc' |
21
+	     'vsock' | 'mpls' | 'ib' | 'kcm' ) ','
22
+
23
+  TYPE = ( 'stream' | 'dgram' | 'seqpacket' |  'rdm' | 'raw' |
24
+           'packet' )
25
+
26
+  PROTOCOL = ( 'tcp' | 'udp' | 'icmp' )
27
+
28
+eg.
29
+  network,
30
+  network inet,
31
+
32
+Signed-off-by: John Johansen <john.johansen@canonical.com>
33
+Acked-by: Seth Arnold <seth.arnold@canonical.com>
34
+---
35
+ security/apparmor/.gitignore       |   1 +
36
+ security/apparmor/Makefile         |  43 ++++-
37
+ security/apparmor/apparmorfs.c     |   1 +
38
+ security/apparmor/file.c           |  30 +++
39
+ security/apparmor/include/audit.h  |  26 ++-
40
+ security/apparmor/include/net.h    | 114 +++++++++++
41
+ security/apparmor/include/perms.h  |   5 +-
42
+ security/apparmor/include/policy.h |  13 ++
43
+ security/apparmor/lib.c            |   5 +-
44
+ security/apparmor/lsm.c            | 387 +++++++++++++++++++++++++++++++++++++
45
+ security/apparmor/net.c            | 184 ++++++++++++++++++
46
+ security/apparmor/policy_unpack.c  |  51 ++++-
47
+ 12 files changed, 844 insertions(+), 16 deletions(-)
48
+ create mode 100644 security/apparmor/include/net.h
49
+ create mode 100644 security/apparmor/net.c
50
+
51
+diff --git a/security/apparmor/.gitignore b/security/apparmor/.gitignore
52
+index 9cdec70d72b8..d5b291e94264 100644
53
+--- a/security/apparmor/.gitignore
54
+@@ -1,5 +1,6 @@
55
+ #
56
+ # Generated include files
57
+ #
58
++net_names.h
59
+ capability_names.h
60
+ rlim_names.h
61
+diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
62
+index 9a6b4033d52b..e7ff2183532a 100644
63
+--- a/security/apparmor/Makefile
64
+@@ -5,11 +5,44 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
65
+ 
66
+ apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
67
+               path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
68
+-              resource.o secid.o file.o policy_ns.o label.o mount.o
69
++              resource.o secid.o file.o policy_ns.o label.o mount.o net.o
70
+ apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
71
+ 
72
+-clean-files := capability_names.h rlim_names.h
73
++clean-files := capability_names.h rlim_names.h net_names.h
74
+ 
75
++# Build a lower case string table of address family names
76
++# Transform lines from
77
++#    #define AF_LOCAL		1	/* POSIX name for AF_UNIX	*/
78
++#    #define AF_INET		2	/* Internet IP Protocol 	*/
79
++# to
80
++#    [1] = "local",
81
++#    [2] = "inet",
82
++#
83
++# and build the securityfs entries for the mapping.
84
++# Transforms lines from
85
++#    #define AF_INET		2	/* Internet IP Protocol 	*/
86
++# to
87
++#    #define AA_SFS_AF_MASK "local inet"
88
++quiet_cmd_make-af = GEN     $@
89
++cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\
90
++	sed $< >>$@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "/AF_ROUTE/d" -e \
91
++	 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
92
++	echo "};" >> $@ ;\
93
++	printf '%s' '\#define AA_SFS_AF_MASK "' >> $@ ;\
94
++	sed -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "/AF_ROUTE/d" -e \
95
++	 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/\L\1/p'\
96
++	 $< | tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
97
++
98
++# Build a lower case string table of sock type names
99
++# Transform lines from
100
++#    SOCK_STREAM	= 1,
101
++# to
102
++#    [1] = "stream",
103
++quiet_cmd_make-sock = GEN     $@
104
++cmd_make-sock = echo "static const char *sock_type_names[] = {" >> $@ ;\
105
++	sed $^ >>$@ -r -n \
106
++	-e 's/^\tSOCK_([A-Z0-9_]+)[\t]+=[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
107
++	echo "};" >> $@
108
+ 
109
+ # Build a lower case string table of capability names
110
+ # Transforms lines from
111
+@@ -62,6 +95,7 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
112
+ 	    tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
113
+ 
114
+ $(obj)/capability.o : $(obj)/capability_names.h
115
++$(obj)/net.o : $(obj)/net_names.h
116
+ $(obj)/resource.o : $(obj)/rlim_names.h
117
+ $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
118
+ 			    $(src)/Makefile
119
+@@ -69,3 +103,8 @@ $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
120
+ $(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \
121
+ 		      $(src)/Makefile
122
+ 	$(call cmd,make-rlim)
123
++$(obj)/net_names.h : $(srctree)/include/linux/socket.h \
124
++		     $(srctree)/include/linux/net.h \
125
++		     $(src)/Makefile
126
++	$(call cmd,make-af)
127
++	$(call cmd,make-sock)
128
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
129
+index caaf51dda648..518d5928661b 100644
130
+--- a/security/apparmor/apparmorfs.c
131
+@@ -2202,6 +2202,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
132
+ 	AA_SFS_DIR("policy",			aa_sfs_entry_policy),
133
+ 	AA_SFS_DIR("domain",			aa_sfs_entry_domain),
134
+ 	AA_SFS_DIR("file",			aa_sfs_entry_file),
135
++	AA_SFS_DIR("network",			aa_sfs_entry_network),
136
+ 	AA_SFS_DIR("mount",			aa_sfs_entry_mount),
137
+ 	AA_SFS_DIR("namespaces",		aa_sfs_entry_ns),
138
+ 	AA_SFS_FILE_U64("capability",		VFS_CAP_FLAGS_MASK),
139
+diff --git a/security/apparmor/file.c b/security/apparmor/file.c
140
+index 3382518b87fa..db80221891c6 100644
141
+--- a/security/apparmor/file.c
142
+@@ -21,6 +21,7 @@
143
+ #include "include/context.h"
144
+ #include "include/file.h"
145
+ #include "include/match.h"
146
++#include "include/net.h"
147
+ #include "include/path.h"
148
+ #include "include/policy.h"
149
+ #include "include/label.h"
150
+@@ -566,6 +567,32 @@ static int __file_path_perm(const char *op, struct aa_label *label,
151
+ 	return error;
152
+ }
153
+ 
154
++static int __file_sock_perm(const char *op, struct aa_label *label,
155
++			    struct aa_label *flabel, struct file *file,
156
++			    u32 request, u32 denied)
157
++{
158
++	struct socket *sock = (struct socket *) file->private_data;
159
++	int error;
160
++
161
++	AA_BUG(!sock);
162
++
163
++	/* revalidation due to label out of date. No revocation at this time */
164
++	if (!denied && aa_label_is_subset(flabel, label))
165
++		return 0;
166
++
167
++	/* TODO: improve to skip profiles cached in flabel */
168
++	error = aa_sock_file_perm(label, op, request, sock);
169
++	if (denied) {
170
++		/* TODO: improve to skip profiles checked above */
171
++		/* check every profile in file label to is cached */
172
++		last_error(error, aa_sock_file_perm(flabel, op, request, sock));
173
++	}
174
++	if (!error)
175
++		update_file_ctx(file_ctx(file), label, request);
176
++
177
++	return error;
178
++}
179
++
180
+ /**
181
+  * aa_file_perm - do permission revalidation check & audit for @file
182
+  * @op: operation being checked
183
+@@ -610,6 +637,9 @@ int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
184
+ 		error = __file_path_perm(op, label, flabel, file, request,
185
+ 					 denied);
186
+ 
187
++	else if (S_ISSOCK(file_inode(file)->i_mode))
188
++		error = __file_sock_perm(op, label, flabel, file, request,
189
++					 denied);
190
+ done:
191
+ 	rcu_read_unlock();
192
+ 
193
+diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
194
+index 2ebc00a..ff4316e 100644
195
+--- a/security/apparmor/include/audit.h
196
+@@ -123,14 +123,20 @@ struct apparmor_audit_data {
197
+ 			struct aa_label *peer;
198
+ 			union {
199
+ 				struct {
200
+-					const char *target;
201
+ 					kuid_t ouid;
202
++					const char *target;
203
+ 				} fs;
204
+ 				struct {
205
++					int type, protocol;
206
++					struct sock *peer_sk;
207
++					void *addr;
208
++					int addrlen;
209
++				} net;
210
++				int signal;
211
++				struct {
212
+ 					int rlim;
213
+ 					unsigned long max;
214
+ 				} rlim;
215
+-				int signal;
216
+ 			};
217
+ 		};
218
+ 		struct {
219
+diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
220
+new file mode 100644
221
+index 000000000000..140c8efcf364
222
+--- /dev/null
223
+@@ -0,0 +1,114 @@
224
++/*
225
++ * AppArmor security module
226
++ *
227
++ * This file contains AppArmor network mediation definitions.
228
++ *
229
++ * Copyright (C) 1998-2008 Novell/SUSE
230
++ * Copyright 2009-2017 Canonical Ltd.
231
++ *
232
++ * This program is free software; you can redistribute it and/or
233
++ * modify it under the terms of the GNU General Public License as
234
++ * published by the Free Software Foundation, version 2 of the
235
++ * License.
236
++ */
237
++
238
++#ifndef __AA_NET_H
239
++#define __AA_NET_H
240
++
241
++#include <net/sock.h>
242
++#include <linux/path.h>
243
++
244
++#include "apparmorfs.h"
245
++#include "label.h"
246
++#include "perms.h"
247
++#include "policy.h"
248
++
249
++#define AA_MAY_SEND		AA_MAY_WRITE
250
++#define AA_MAY_RECEIVE		AA_MAY_READ
251
++
252
++#define AA_MAY_SHUTDOWN		AA_MAY_DELETE
253
++
254
++#define AA_MAY_CONNECT		AA_MAY_OPEN
255
++#define AA_MAY_ACCEPT		0x00100000
256
++
257
++#define AA_MAY_BIND		0x00200000
258
++#define AA_MAY_LISTEN		0x00400000
259
++
260
++#define AA_MAY_SETOPT		0x01000000
261
++#define AA_MAY_GETOPT		0x02000000
262
++
263
++#define NET_PERMS_MASK (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CREATE |    \
264
++			AA_MAY_SHUTDOWN | AA_MAY_BIND | AA_MAY_LISTEN |	  \
265
++			AA_MAY_CONNECT | AA_MAY_ACCEPT | AA_MAY_SETATTR | \
266
++			AA_MAY_GETATTR | AA_MAY_SETOPT | AA_MAY_GETOPT)
267
++
268
++#define NET_FS_PERMS (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CREATE |	\
269
++		      AA_MAY_SHUTDOWN | AA_MAY_CONNECT | AA_MAY_RENAME |\
270
++		      AA_MAY_SETATTR | AA_MAY_GETATTR | AA_MAY_CHMOD |	\
271
++		      AA_MAY_CHOWN | AA_MAY_CHGRP | AA_MAY_LOCK |	\
272
++		      AA_MAY_MPROT)
273
++
274
++#define NET_PEER_MASK (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CONNECT |	\
275
++		       AA_MAY_ACCEPT)
276
++struct aa_sk_ctx {
277
++	struct aa_label *label;
278
++	struct aa_label *peer;
279
++	struct path path;
280
++};
281
++
282
++#define SK_CTX(X) ((X)->sk_security)
283
++#define SOCK_ctx(X) SOCK_INODE(X)->i_security
284
++#define DEFINE_AUDIT_NET(NAME, OP, SK, F, T, P)				  \
285
++	struct lsm_network_audit NAME ## _net = { .sk = (SK),		  \
286
++						  .family = (F)};	  \
287
++	DEFINE_AUDIT_DATA(NAME,						  \
288
++			  ((SK) && (F) != AF_UNIX) ? LSM_AUDIT_DATA_NET : \
289
++						     LSM_AUDIT_DATA_NONE, \
290
++			  OP);						  \
291
++	NAME.u.net = &(NAME ## _net);					  \
292
++	aad(&NAME)->net.type = (T);					  \
293
++	aad(&NAME)->net.protocol = (P)
294
++
295
++#define DEFINE_AUDIT_SK(NAME, OP, SK)					\
296
++	DEFINE_AUDIT_NET(NAME, OP, SK, (SK)->sk_family, (SK)->sk_type,	\
297
++			 (SK)->sk_protocol)
298
++
299
++/* struct aa_net - network confinement data
300
++ * @allow: basic network families permissions
301
++ * @audit: which network permissions to force audit
302
++ * @quiet: which network permissions to quiet rejects
303
++ */
304
++struct aa_net {
305
++	u16 allow[AF_MAX];
306
++	u16 audit[AF_MAX];
307
++	u16 quiet[AF_MAX];
308
++};
309
++
310
++
311
++extern struct aa_sfs_entry aa_sfs_entry_network[];
312
++
313
++void audit_net_cb(struct audit_buffer *ab, void *va);
314
++int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
315
++		       u32 request, u16 family, int type);
316
++int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
317
++	       int type, int protocol);
318
++static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
319
++					struct common_audit_data *sa,
320
++					u32 request,
321
++					struct sock *sk)
322
++{
323
++	return aa_profile_af_perm(profile, sa, request, sk->sk_family,
324
++				  sk->sk_type);
325
++}
326
++int aa_sk_perm(const char *op, u32 request, struct sock *sk);
327
++
328
++int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
329
++		      struct socket *sock);
330
++
331
++
332
++static inline void aa_free_net_rules(struct aa_net *new)
333
++{
334
++	/* NOP */
335
++}
336
++
337
++#endif /* __AA_NET_H */
338
+diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h
339
+index 2b27bb79aec4..af04d5a7d73d 100644
340
+--- a/security/apparmor/include/perms.h
341
+@@ -135,9 +135,10 @@ extern struct aa_perms allperms;
342
+ 
343
+ 
344
+ void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask);
345
+-void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask);
346
++void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names,
347
++			 u32 mask);
348
+ void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
349
+-			u32 chrsmask, const char **names, u32 namesmask);
350
++			u32 chrsmask, const char * const *names, u32 namesmask);
351
+ void aa_apply_modes_to_perms(struct aa_profile *profile,
352
+ 			     struct aa_perms *perms);
353
+ void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
354
+diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
355
+index 17fe41a9cac3..4364088a0b9e 100644
356
+--- a/security/apparmor/include/policy.h
357
+@@ -30,6 +30,7 @@
358
+ #include "file.h"
359
+ #include "lib.h"
360
+ #include "label.h"
361
++#include "net.h"
362
+ #include "perms.h"
363
+ #include "resource.h"
364
+ 
365
+@@ -111,6 +112,7 @@ struct aa_data {
366
+  * @policy: general match rules governing policy
367
+  * @file: The set of rules governing basic file access and domain transitions
368
+  * @caps: capabilities for the profile
369
++ * @net: network controls for the profile
370
+  * @rlimits: rlimits for the profile
371
+  *
372
+  * @dents: dentries for the profiles file entries in apparmorfs
373
+@@ -148,6 +150,7 @@ struct aa_profile {
374
+ 	struct aa_policydb policy;
375
+ 	struct aa_file_rules file;
376
+ 	struct aa_caps caps;
377
++	struct aa_net net;
378
+ 	struct aa_rlimit rlimits;
379
+ 
380
+ 	struct aa_loaddata *rawdata;
381
+@@ -220,6 +223,16 @@ static inline unsigned int PROFILE_MEDIATES_SAFE(struct aa_profile *profile,
382
+ 	return 0;
383
+ }
384
+ 
385
++static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile,
386
++					       u16 AF) {
387
++	unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
388
++	u16 be_af = cpu_to_be16(AF);
389
++
390
++	if (!state)
391
++		return 0;
392
++	return aa_dfa_match_len(profile->policy.dfa, state, (char *) &be_af, 2);
393
++}
394
++
395
+ /**
396
+  * aa_get_profile - increment refcount on profile @p
397
+  * @p: profile  (MAYBE NULL)
398
+diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
399
+index 08ca26bcca77..8818621b5d95 100644
400
+--- a/security/apparmor/lib.c
401
+@@ -211,7 +211,8 @@ void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask)
402
+ 	*str = '\0';
403
+ }
404
+ 
405
+-void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask)
406
++void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names,
407
++			 u32 mask)
408
+ {
409
+ 	const char *fmt = "%s";
410
+ 	unsigned int i, perm = 1;
411
+@@ -229,7 +230,7 @@ void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask)
412
+ }
413
+ 
414
+ void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
415
+-			u32 chrsmask, const char **names, u32 namesmask)
416
++			u32 chrsmask, const char * const *names, u32 namesmask)
417
+ {
418
+ 	char str[33];
419
+ 
420
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
421
+index 1346ee5be04f..72b915dfcaf7 100644
422
+--- a/security/apparmor/lsm.c
423
+@@ -33,6 +33,7 @@
424
+ #include "include/context.h"
425
+ #include "include/file.h"
426
+ #include "include/ipc.h"
427
++#include "include/net.h"
428
+ #include "include/path.h"
429
+ #include "include/label.h"
430
+ #include "include/policy.h"
431
+@@ -736,6 +737,368 @@ static int apparmor_task_kill(struct task_struct *target, struct siginfo *info,
432
+ 	return error;
433
+ }
434
+ 
435
++/**
436
++ * apparmor_sk_alloc_security - allocate and attach the sk_security field
437
++ */
438
++static int apparmor_sk_alloc_security(struct sock *sk, int family, gfp_t flags)
439
++{
440
++	struct aa_sk_ctx *ctx;
441
++
442
++	ctx = kzalloc(sizeof(*ctx), flags);
443
++	if (!ctx)
444
++		return -ENOMEM;
445
++
446
++	SK_CTX(sk) = ctx;
447
++
448
++	return 0;
449
++}
450
++
451
++/**
452
++ * apparmor_sk_free_security - free the sk_security field
453
++ */
454
++static void apparmor_sk_free_security(struct sock *sk)
455
++{
456
++	struct aa_sk_ctx *ctx = SK_CTX(sk);
457
++
458
++	SK_CTX(sk) = NULL;
459
++	aa_put_label(ctx->label);
460
++	aa_put_label(ctx->peer);
461
++	path_put(&ctx->path);
462
++	kfree(ctx);
463
++}
464
++
465
++/**
466
++ * apparmor_clone_security - clone the sk_security field
467
++ */
468
++static void apparmor_sk_clone_security(const struct sock *sk,
469
++				       struct sock *newsk)
470
++{
471
++	struct aa_sk_ctx *ctx = SK_CTX(sk);
472
++	struct aa_sk_ctx *new = SK_CTX(newsk);
473
++
474
++	new->label = aa_get_label(ctx->label);
475
++	new->peer = aa_get_label(ctx->peer);
476
++	new->path = ctx->path;
477
++	path_get(&new->path);
478
++}
479
++
480
++static int aa_sock_create_perm(struct aa_label *label, int family, int type,
481
++			       int protocol)
482
++{
483
++	AA_BUG(!label);
484
++	AA_BUG(in_interrupt());
485
++
486
++	return aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family, type,
487
++			  protocol);
488
++}
489
++
490
++
491
++/**
492
++ * apparmor_socket_create - check perms before creating a new socket
493
++ */
494
++static int apparmor_socket_create(int family, int type, int protocol, int kern)
495
++{
496
++	struct aa_label *label;
497
++	int error = 0;
498
++
499
++	label = begin_current_label_crit_section();
500
++	if (!(kern || unconfined(label)))
501
++		error = aa_sock_create_perm(label, family, type, protocol);
502
++	end_current_label_crit_section(label);
503
++
504
++	return error;
505
++}
506
++
507
++/**
508
++ * apparmor_socket_post_create - setup the per-socket security struct
509
++ *
510
++ * Note:
511
++ * -   kernel sockets currently labeled unconfined but we may want to
512
++ *     move to a special kernel label
513
++ * -   socket may not have sk here if created with sock_create_lite or
514
++ *     sock_alloc. These should be accept cases which will be handled in
515
++ *     sock_graft.
516
++ */
517
++static int apparmor_socket_post_create(struct socket *sock, int family,
518
++				       int type, int protocol, int kern)
519
++{
520
++	struct aa_label *label;
521
++
522
++	if (kern) {
523
++		struct aa_ns *ns = aa_get_current_ns();
524
++
525
++		label = aa_get_label(ns_unconfined(ns));
526
++		aa_put_ns(ns);
527
++	} else
528
++		label = aa_get_current_label();
529
++
530
++	if (sock->sk) {
531
++		struct aa_sk_ctx *ctx = SK_CTX(sock->sk);
532
++
533
++		aa_put_label(ctx->label);
534
++		ctx->label = aa_get_label(label);
535
++	}
536
++	aa_put_label(label);
537
++
538
++	return 0;
539
++}
540
++
541
++/**
542
++ * apparmor_socket_bind - check perms before bind addr to socket
543
++ */
544
++static int apparmor_socket_bind(struct socket *sock,
545
++				struct sockaddr *address, int addrlen)
546
++{
547
++	AA_BUG(!sock);
548
++	AA_BUG(!sock->sk);
549
++	AA_BUG(!address);
550
++	AA_BUG(in_interrupt());
551
++
552
++	return aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk);
553
++}
554
++
555
++/**
556
++ * apparmor_socket_connect - check perms before connecting @sock to @address
557
++ */
558
++static int apparmor_socket_connect(struct socket *sock,
559
++				   struct sockaddr *address, int addrlen)
560
++{
561
++	AA_BUG(!sock);
562
++	AA_BUG(!sock->sk);
563
++	AA_BUG(!address);
564
++	AA_BUG(in_interrupt());
565
++
566
++	return aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk);
567
++}
568
++
569
++/**
570
++ * apparmor_socket_list - check perms before allowing listen
571
++ */
572
++static int apparmor_socket_listen(struct socket *sock, int backlog)
573
++{
574
++	AA_BUG(!sock);
575
++	AA_BUG(!sock->sk);
576
++	AA_BUG(in_interrupt());
577
++
578
++	return aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk);
579
++}
580
++
581
++/**
582
++ * apparmor_socket_accept - check perms before accepting a new connection.
583
++ *
584
++ * Note: while @newsock is created and has some information, the accept
585
++ *       has not been done.
586
++ */
587
++static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
588
++{
589
++	AA_BUG(!sock);
590
++	AA_BUG(!sock->sk);
591
++	AA_BUG(!newsock);
592
++	AA_BUG(in_interrupt());
593
++
594
++	return aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk);
595
++}
596
++
597
++static int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
598
++			    struct msghdr *msg, int size)
599
++{
600
++	AA_BUG(!sock);
601
++	AA_BUG(!sock->sk);
602
++	AA_BUG(!msg);
603
++	AA_BUG(in_interrupt());
604
++
605
++	return aa_sk_perm(op, request, sock->sk);
606
++}
607
++
608
++/**
609
++ * apparmor_socket_sendmsg - check perms before sending msg to another socket
610
++ */
611
++static int apparmor_socket_sendmsg(struct socket *sock,
612
++				   struct msghdr *msg, int size)
613
++{
614
++	return aa_sock_msg_perm(OP_SENDMSG, AA_MAY_SEND, sock, msg, size);
615
++}
616
++
617
++/**
618
++ * apparmor_socket_recvmsg - check perms before receiving a message
619
++ */
620
++static int apparmor_socket_recvmsg(struct socket *sock,
621
++				   struct msghdr *msg, int size, int flags)
622
++{
623
++	return aa_sock_msg_perm(OP_RECVMSG, AA_MAY_RECEIVE, sock, msg, size);
624
++}
625
++
626
++/* revaliation, get/set attr, shutdown */
627
++static int aa_sock_perm(const char *op, u32 request, struct socket *sock)
628
++{
629
++	AA_BUG(!sock);
630
++	AA_BUG(!sock->sk);
631
++	AA_BUG(in_interrupt());
632
++
633
++	return aa_sk_perm(op, request, sock->sk);
634
++}
635
++
636
++/**
637
++ * apparmor_socket_getsockname - check perms before getting the local address
638
++ */
639
++static int apparmor_socket_getsockname(struct socket *sock)
640
++{
641
++	return aa_sock_perm(OP_GETSOCKNAME, AA_MAY_GETATTR, sock);
642
++}
643
++
644
++/**
645
++ * apparmor_socket_getpeername - check perms before getting remote address
646
++ */
647
++static int apparmor_socket_getpeername(struct socket *sock)
648
++{
649
++	return aa_sock_perm(OP_GETPEERNAME, AA_MAY_GETATTR, sock);
650
++}
651
++
652
++/* revaliation, get/set attr, opt */
653
++static int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock,
654
++			    int level, int optname)
655
++{
656
++	AA_BUG(!sock);
657
++	AA_BUG(!sock->sk);
658
++	AA_BUG(in_interrupt());
659
++
660
++	return aa_sk_perm(op, request, sock->sk);
661
++}
662
++
663
++/**
664
++ * apparmor_getsockopt - check perms before getting socket options
665
++ */
666
++static int apparmor_socket_getsockopt(struct socket *sock, int level,
667
++				      int optname)
668
++{
669
++	return aa_sock_opt_perm(OP_GETSOCKOPT, AA_MAY_GETOPT, sock,
670
++				level, optname);
671
++}
672
++
673
++/**
674
++ * apparmor_setsockopt - check perms before setting socket options
675
++ */
676
++static int apparmor_socket_setsockopt(struct socket *sock, int level,
677
++				      int optname)
678
++{
679
++	return aa_sock_opt_perm(OP_SETSOCKOPT, AA_MAY_SETOPT, sock,
680
++				level, optname);
681
++}
682
++
683
++/**
684
++ * apparmor_socket_shutdown - check perms before shutting down @sock conn
685
++ */
686
++static int apparmor_socket_shutdown(struct socket *sock, int how)
687
++{
688
++	return aa_sock_perm(OP_SHUTDOWN, AA_MAY_SHUTDOWN, sock);
689
++}
690
++
691
++/**
692
++ * apparmor_socket_sock_recv_skb - check perms before associating skb to sk
693
++ *
694
++ * Note: can not sleep may be called with locks held
695
++ *
696
++ * dont want protocol specific in __skb_recv_datagram()
697
++ * to deny an incoming connection  socket_sock_rcv_skb()
698
++ */
699
++static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
700
++{
701
++	return 0;
702
++}
703
++
704
++
705
++static struct aa_label *sk_peer_label(struct sock *sk)
706
++{
707
++	struct aa_sk_ctx *ctx = SK_CTX(sk);
708
++
709
++	if (ctx->peer)
710
++		return ctx->peer;
711
++
712
++	return ERR_PTR(-ENOPROTOOPT);
713
++}
714
++
715
++/**
716
++ * apparmor_socket_getpeersec_stream - get security context of peer
717
++ *
718
++ * Note: for tcp only valid if using ipsec or cipso on lan
719
++ */
720
++static int apparmor_socket_getpeersec_stream(struct socket *sock,
721
++					     char __user *optval,
722
++					     int __user *optlen,
723
++					     unsigned int len)
724
++{
725
++	char *name;
726
++	int slen, error = 0;
727
++	struct aa_label *label;
728
++	struct aa_label *peer;
729
++
730
++	label = begin_current_label_crit_section();
731
++	peer = sk_peer_label(sock->sk);
732
++	if (IS_ERR(peer)) {
733
++		error = PTR_ERR(peer);
734
++		goto done;
735
++	}
736
++	slen = aa_label_asxprint(&name, labels_ns(label), peer,
737
++				 FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
738
++				 FLAG_HIDDEN_UNCONFINED, GFP_KERNEL);
739
++	/* don't include terminating \0 in slen, it breaks some apps */
740
++	if (slen < 0) {
741
++		error = -ENOMEM;
742
++	} else {
743
++		if (slen > len) {
744
++			error = -ERANGE;
745
++		} else if (copy_to_user(optval, name, slen)) {
746
++			error = -EFAULT;
747
++			goto out;
748
++		}
749
++		if (put_user(slen, optlen))
750
++			error = -EFAULT;
751
++out:
752
++		kfree(name);
753
++
754
++	}
755
++
756
++done:
757
++	end_current_label_crit_section(label);
758
++
759
++	return error;
760
++}
761
++
762
++/**
763
++ * apparmor_socket_getpeersec_dgram - get security label of packet
764
++ * @sock: the peer socket
765
++ * @skb: packet data
766
++ * @secid: pointer to where to put the secid of the packet
767
++ *
768
++ * Sets the netlabel socket state on sk from parent
769
++ */
770
++static int apparmor_socket_getpeersec_dgram(struct socket *sock,
771
++					    struct sk_buff *skb, u32 *secid)
772
++
773
++{
774
++	/* TODO: requires secid support */
775
++	return -ENOPROTOOPT;
776
++}
777
++
778
++/**
779
++ * apparmor_sock_graft - Initialize newly created socket
780
++ * @sk: child sock
781
++ * @parent: parent socket
782
++ *
783
++ * Note: could set off of SOCK_CTX(parent) but need to track inode and we can
784
++ *       just set sk security information off of current creating process label
785
++ *       Labeling of sk for accept case - probably should be sock based
786
++ *       instead of task, because of the case where an implicitly labeled
787
++ *       socket is shared by different tasks.
788
++ */
789
++static void apparmor_sock_graft(struct sock *sk, struct socket *parent)
790
++{
791
++	struct aa_sk_ctx *ctx = SK_CTX(sk);
792
++
793
++	if (!ctx->label)
794
++		ctx->label = aa_get_current_label();
795
++}
796
++
797
+ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
798
+ 	LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
799
+ 	LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
800
+@@ -770,6 +1133,30 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
801
+ 	LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
802
+ 	LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
803
+ 
804
++	LSM_HOOK_INIT(sk_alloc_security, apparmor_sk_alloc_security),
805
++	LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security),
806
++	LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security),
807
++
808
++	LSM_HOOK_INIT(socket_create, apparmor_socket_create),
809
++	LSM_HOOK_INIT(socket_post_create, apparmor_socket_post_create),
810
++	LSM_HOOK_INIT(socket_bind, apparmor_socket_bind),
811
++	LSM_HOOK_INIT(socket_connect, apparmor_socket_connect),
812
++	LSM_HOOK_INIT(socket_listen, apparmor_socket_listen),
813
++	LSM_HOOK_INIT(socket_accept, apparmor_socket_accept),
814
++	LSM_HOOK_INIT(socket_sendmsg, apparmor_socket_sendmsg),
815
++	LSM_HOOK_INIT(socket_recvmsg, apparmor_socket_recvmsg),
816
++	LSM_HOOK_INIT(socket_getsockname, apparmor_socket_getsockname),
817
++	LSM_HOOK_INIT(socket_getpeername, apparmor_socket_getpeername),
818
++	LSM_HOOK_INIT(socket_getsockopt, apparmor_socket_getsockopt),
819
++	LSM_HOOK_INIT(socket_setsockopt, apparmor_socket_setsockopt),
820
++	LSM_HOOK_INIT(socket_shutdown, apparmor_socket_shutdown),
821
++	LSM_HOOK_INIT(socket_sock_rcv_skb, apparmor_socket_sock_rcv_skb),
822
++	LSM_HOOK_INIT(socket_getpeersec_stream,
823
++		      apparmor_socket_getpeersec_stream),
824
++	LSM_HOOK_INIT(socket_getpeersec_dgram,
825
++		      apparmor_socket_getpeersec_dgram),
826
++	LSM_HOOK_INIT(sock_graft, apparmor_sock_graft),
827
++
828
+ 	LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank),
829
+ 	LSM_HOOK_INIT(cred_free, apparmor_cred_free),
830
+ 	LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare),
831
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
832
+new file mode 100644
833
+index 000000000000..33d54435f8d6
834
+--- /dev/null
835
+@@ -0,0 +1,184 @@
836
++/*
837
++ * AppArmor security module
838
++ *
839
++ * This file contains AppArmor network mediation
840
++ *
841
++ * Copyright (C) 1998-2008 Novell/SUSE
842
++ * Copyright 2009-2017 Canonical Ltd.
843
++ *
844
++ * This program is free software; you can redistribute it and/or
845
++ * modify it under the terms of the GNU General Public License as
846
++ * published by the Free Software Foundation, version 2 of the
847
++ * License.
848
++ */
849
++
850
++#include "include/apparmor.h"
851
++#include "include/audit.h"
852
++#include "include/context.h"
853
++#include "include/label.h"
854
++#include "include/net.h"
855
++#include "include/policy.h"
856
++
857
++#include "net_names.h"
858
++
859
++
860
++struct aa_sfs_entry aa_sfs_entry_network[] = {
861
++	AA_SFS_FILE_STRING("af_mask",	AA_SFS_AF_MASK),
862
++	{ }
863
++};
864
++
865
++static const char * const net_mask_names[] = {
866
++	"unknown",
867
++	"send",
868
++	"receive",
869
++	"unknown",
870
++
871
++	"create",
872
++	"shutdown",
873
++	"connect",
874
++	"unknown",
875
++
876
++	"setattr",
877
++	"getattr",
878
++	"setcred",
879
++	"getcred",
880
++
881
++	"chmod",
882
++	"chown",
883
++	"chgrp",
884
++	"lock",
885
++
886
++	"mmap",
887
++	"mprot",
888
++	"unknown",
889
++	"unknown",
890
++
891
++	"accept",
892
++	"bind",
893
++	"listen",
894
++	"unknown",
895
++
896
++	"setopt",
897
++	"getopt",
898
++	"unknown",
899
++	"unknown",
900
++
901
++	"unknown",
902
++	"unknown",
903
++	"unknown",
904
++	"unknown",
905
++};
906
++
907
++
908
++/* audit callback for net specific fields */
909
++void audit_net_cb(struct audit_buffer *ab, void *va)
910
++{
911
++	struct common_audit_data *sa = va;
912
++
913
++	audit_log_format(ab, " family=");
914
++	if (address_family_names[sa->u.net->family])
915
++		audit_log_string(ab, address_family_names[sa->u.net->family]);
916
++	else
917
++		audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
918
++	audit_log_format(ab, " sock_type=");
919
++	if (sock_type_names[aad(sa)->net.type])
920
++		audit_log_string(ab, sock_type_names[aad(sa)->net.type]);
921
++	else
922
++		audit_log_format(ab, "\"unknown(%d)\"", aad(sa)->net.type);
923
++	audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol);
924
++
925
++	if (aad(sa)->request & NET_PERMS_MASK) {
926
++		audit_log_format(ab, " requested_mask=");
927
++		aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0,
928
++				   net_mask_names, NET_PERMS_MASK);
929
++
930
++		if (aad(sa)->denied & NET_PERMS_MASK) {
931
++			audit_log_format(ab, " denied_mask=");
932
++			aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0,
933
++					   net_mask_names, NET_PERMS_MASK);
934
++		}
935
++	}
936
++	if (aad(sa)->peer) {
937
++		audit_log_format(ab, " peer=");
938
++		aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
939
++				FLAGS_NONE, GFP_ATOMIC);
940
++	}
941
++}
942
++
943
++
944
++/* Generic af perm */
945
++int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
946
++		       u32 request, u16 family, int type)
947
++{
948
++	struct aa_perms perms = { };
949
++
950
++	AA_BUG(family >= AF_MAX);
951
++	AA_BUG(type < 0 || type >= SOCK_MAX);
952
++
953
++	if (profile_unconfined(profile))
954
++		return 0;
955
++
956
++	perms.allow = (profile->net.allow[family] & (1 << type)) ?
957
++		ALL_PERMS_MASK : 0;
958
++	perms.audit = (profile->net.audit[family] & (1 << type)) ?
959
++		ALL_PERMS_MASK : 0;
960
++	perms.quiet = (profile->net.quiet[family] & (1 << type)) ?
961
++		ALL_PERMS_MASK : 0;
962
++	aa_apply_modes_to_perms(profile, &perms);
963
++
964
++	return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
965
++}
966
++
967
++int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
968
++	       int type, int protocol)
969
++{
970
++	struct aa_profile *profile;
971
++	DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol);
972
++
973
++	return fn_for_each_confined(label, profile,
974
++			aa_profile_af_perm(profile, &sa, request, family,
975
++					   type));
976
++}
977
++
978
++static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
979
++			    struct sock *sk)
980
++{
981
++	struct aa_profile *profile;
982
++	DEFINE_AUDIT_SK(sa, op, sk);
983
++
984
++	AA_BUG(!label);
985
++	AA_BUG(!sk);
986
++
987
++	if (unconfined(label))
988
++		return 0;
989
++
990
++	return fn_for_each_confined(label, profile,
991
++			aa_profile_af_sk_perm(profile, &sa, request, sk));
992
++}
993
++
994
++int aa_sk_perm(const char *op, u32 request, struct sock *sk)
995
++{
996
++	struct aa_label *label;
997
++	int error;
998
++
999
++	AA_BUG(!sk);
1000
++	AA_BUG(in_interrupt());
1001
++
1002
++	/* TODO: switch to begin_current_label ???? */
1003
++	label = begin_current_label_crit_section();
1004
++	error = aa_label_sk_perm(label, op, request, sk);
1005
++	end_current_label_crit_section(label);
1006
++
1007
++	return error;
1008
++}
1009
++
1010
++
1011
++int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
1012
++		      struct socket *sock)
1013
++{
1014
++	AA_BUG(!label);
1015
++	AA_BUG(!sock);
1016
++	AA_BUG(!sock->sk);
1017
++
1018
++	return aa_label_sk_perm(label, op, request, sock->sk);
1019
++}
1020
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
1021
+index 4ede87c30f8b..e348f8dec45d 100644
1022
+--- a/security/apparmor/policy_unpack.c
1023
+@@ -275,6 +275,19 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
1024
+ 	return 0;
1025
+ }
1026
+ 
1027
++static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
1028
++{
1029
++	if (unpack_nameX(e, AA_U16, name)) {
1030
++		if (!inbounds(e, sizeof(u16)))
1031
++			return 0;
1032
++		if (data)
1033
++			*data = le16_to_cpu(get_unaligned((__le16 *) e->pos));
1034
++		e->pos += sizeof(u16);
1035
++		return 1;
1036
++	}
1037
++	return 0;
1038
++}
1039
++
1040
+ static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
1041
+ {
1042
+ 	if (unpack_nameX(e, AA_U32, name)) {
1043
+@@ -584,7 +597,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
1044
+ 	struct aa_profile *profile = NULL;
1045
+ 	const char *tmpname, *tmpns = NULL, *name = NULL;
1046
+ 	const char *info = "failed to unpack profile";
1047
+-	size_t ns_len;
1048
++	size_t size = 0, ns_len;
1049
+ 	struct rhashtable_params params = { 0 };
1050
+ 	char *key = NULL;
1051
+ 	struct aa_data *data;
1052
+@@ -717,6 +730,42 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
1053
+ 		goto fail;
1054
+ 	}
1055
+ 
1056
++	size = unpack_array(e, "net_allowed_af");
1057
++	if (size) {
1058
++
1059
++		for (i = 0; i < size; i++) {
1060
++			/* discard extraneous rules that this kernel will
1061
++			 * never request
1062
++			 */
1063
++			if (i >= AF_MAX) {
1064
++				u16 tmp;
1065
++
1066
++				if (!unpack_u16(e, &tmp, NULL) ||
1067
++				    !unpack_u16(e, &tmp, NULL) ||
1068
++				    !unpack_u16(e, &tmp, NULL))
1069
++					goto fail;
1070
++				continue;
1071
++			}
1072
++			if (!unpack_u16(e, &profile->net.allow[i], NULL))
1073
++				goto fail;
1074
++			if (!unpack_u16(e, &profile->net.audit[i], NULL))
1075
++				goto fail;
1076
++			if (!unpack_u16(e, &profile->net.quiet[i], NULL))
1077
++				goto fail;
1078
++		}
1079
++		if (!unpack_nameX(e, AA_ARRAYEND, NULL))
1080
++			goto fail;
1081
++	} else {
1082
++		/* support policy pre AF socket mediation */
1083
++		for (i = 0; i < AF_MAX; i++)
1084
++			profile->net.allow[i] = 0xffff;
1085
++	}
1086
++	if (VERSION_LT(e->version, v7)) {
1087
++		/* pre v7 policy always allowed these */
1088
++		profile->net.allow[AF_UNIX] = 0xffff;
1089
++		profile->net.allow[AF_NETLINK] = 0xffff;
1090
++	}
1091
++
1092
+ 	if (unpack_nameX(e, AA_STRUCT, "policydb")) {
1093
+ 		/* generic policy dfa - optional and may be NULL */
1094
+ 		info = "failed to unpack policydb";
1095
+-- 
1096
+2.14.1
1097
+
0 1098
new file mode 100644
... ...
@@ -0,0 +1,1395 @@
0
+From 2e7f6d0dc0f1d3642950f529b451af73fa1baf9c Mon Sep 17 00:00:00 2001
1
+From: John Johansen <john.johansen@canonical.com>
2
+Date: Tue, 18 Jul 2017 23:27:23 -0700
3
+Subject: [PATCH 2/2] apparmor: af_unix mediation
4
+
5
+af_socket mediation did not make it into 4.14 so add remaining out
6
+of tree patch
7
+
8
+Signed-off-by: John Johansen <john.johansen@canonical.com>
9
+Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
10
+---
11
+ security/apparmor/Makefile          |   3 +-
12
+ security/apparmor/af_unix.c         | 651 ++++++++++++++++++++++++++++++++++++
13
+ security/apparmor/apparmorfs.c      |   6 +
14
+ security/apparmor/file.c            |   4 +-
15
+ security/apparmor/include/af_unix.h | 114 +++++++
16
+ security/apparmor/include/net.h     |  16 +-
17
+ security/apparmor/include/path.h    |   1 +
18
+ security/apparmor/include/policy.h  |   2 +-
19
+ security/apparmor/lsm.c             | 169 ++++++----
20
+ security/apparmor/net.c             | 174 +++++++++-
21
+ 10 files changed, 1072 insertions(+), 68 deletions(-)
22
+ create mode 100644 security/apparmor/af_unix.c
23
+ create mode 100644 security/apparmor/include/af_unix.h
24
+
25
+diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
26
+index e7ff2183532a..90c118f39e13 100644
27
+--- a/security/apparmor/Makefile
28
+@@ -5,7 +5,8 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
29
+ 
30
+ apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
31
+               path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
32
+-              resource.o secid.o file.o policy_ns.o label.o mount.o net.o
33
++              resource.o secid.o file.o policy_ns.o label.o mount.o net.o \
34
++              af_unix.o
35
+ apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
36
+ 
37
+ clean-files := capability_names.h rlim_names.h net_names.h
38
+diff --git a/security/apparmor/af_unix.c b/security/apparmor/af_unix.c
39
+new file mode 100644
40
+index 000000000000..c6876db2dbde
41
+--- /dev/null
42
+@@ -0,0 +1,651 @@
43
++/*
44
++ * AppArmor security module
45
++ *
46
++ * This file contains AppArmor af_unix fine grained mediation
47
++ *
48
++ * Copyright 2014 Canonical Ltd.
49
++ *
50
++ * This program is free software; you can redistribute it and/or
51
++ * modify it under the terms of the GNU General Public License as
52
++ * published by the Free Software Foundation, version 2 of the
53
++ * License.
54
++ */
55
++
56
++#include <net/tcp_states.h>
57
++
58
++#include "include/af_unix.h"
59
++#include "include/apparmor.h"
60
++#include "include/context.h"
61
++#include "include/file.h"
62
++#include "include/label.h"
63
++#include "include/path.h"
64
++#include "include/policy.h"
65
++
66
++static inline struct sock *aa_sock(struct unix_sock *u)
67
++{
68
++	return &u->sk;
69
++}
70
++
71
++static inline int unix_fs_perm(const char *op, u32 mask, struct aa_label *label,
72
++			       struct unix_sock *u, int flags)
73
++{
74
++	AA_BUG(!label);
75
++	AA_BUG(!u);
76
++	AA_BUG(!UNIX_FS(aa_sock(u)));
77
++
78
++	if (unconfined(label) || !LABEL_MEDIATES(label, AA_CLASS_FILE))
79
++		return 0;
80
++
81
++	mask &= NET_FS_PERMS;
82
++	if (!u->path.dentry) {
83
++		struct path_cond cond = { };
84
++		struct aa_perms perms = { };
85
++		struct aa_profile *profile;
86
++
87
++		/* socket path has been cleared because it is being shutdown
88
++		 * can only fall back to original sun_path request
89
++		 */
90
++		struct aa_sk_ctx *ctx = SK_CTX(&u->sk);
91
++		if (ctx->path.dentry)
92
++			return aa_path_perm(op, label, &ctx->path, flags, mask,
93
++					    &cond);
94
++		return fn_for_each_confined(label, profile,
95
++			((flags | profile->path_flags) & PATH_MEDIATE_DELETED) ?
96
++				__aa_path_perm(op, profile,
97
++					       u->addr->name->sun_path, mask,
98
++					       &cond, flags, &perms) :
99
++				aa_audit_file(profile, &nullperms, op, mask,
100
++					      u->addr->name->sun_path, NULL,
101
++					      NULL, cond.uid,
102
++					      "Failed name lookup - "
103
++					      "deleted entry", -EACCES));
104
++	} else {
105
++		/* the sunpath may not be valid for this ns so use the path */
106
++		struct path_cond cond = { u->path.dentry->d_inode->i_uid,
107
++					  u->path.dentry->d_inode->i_mode
108
++		};
109
++
110
++		return aa_path_perm(op, label, &u->path, flags, mask, &cond);
111
++	}
112
++
113
++	return 0;
114
++}
115
++
116
++/* passing in state returned by PROFILE_MEDIATES_AF */
117
++static unsigned int match_to_prot(struct aa_profile *profile,
118
++				  unsigned int state, int type, int protocol,
119
++				  const char **info)
120
++{
121
++	__be16 buffer[2];
122
++	buffer[0] = cpu_to_be16(type);
123
++	buffer[1] = cpu_to_be16(protocol);
124
++	state = aa_dfa_match_len(profile->policy.dfa, state, (char *) &buffer,
125
++				 4);
126
++	if (!state)
127
++		*info = "failed type and protocol match";
128
++	return state;
129
++}
130
++
131
++static unsigned int match_addr(struct aa_profile *profile, unsigned int state,
132
++			       struct sockaddr_un *addr, int addrlen)
133
++{
134
++	if (addr)
135
++		/* include leading \0 */
136
++		state = aa_dfa_match_len(profile->policy.dfa, state,
137
++					 addr->sun_path,
138
++					 unix_addr_len(addrlen));
139
++	else
140
++		/* anonymous end point */
141
++		state = aa_dfa_match_len(profile->policy.dfa, state, "\x01",
142
++					 1);
143
++	/* todo change to out of band */
144
++	state = aa_dfa_null_transition(profile->policy.dfa, state);
145
++	return state;
146
++}
147
++
148
++static unsigned int match_to_local(struct aa_profile *profile,
149
++				   unsigned int state, int type, int protocol,
150
++				   struct sockaddr_un *addr, int addrlen,
151
++				   const char **info)
152
++{
153
++	state = match_to_prot(profile, state, type, protocol, info);
154
++	if (state) {
155
++		state = match_addr(profile, state, addr, addrlen);
156
++		if (state) {
157
++			/* todo: local label matching */
158
++			state = aa_dfa_null_transition(profile->policy.dfa,
159
++						       state);
160
++			if (!state)
161
++				*info = "failed local label match";
162
++		} else
163
++			*info = "failed local address match";
164
++	}
165
++
166
++	return state;
167
++}
168
++
169
++static unsigned int match_to_sk(struct aa_profile *profile,
170
++				unsigned int state, struct unix_sock *u,
171
++				const char **info)
172
++{
173
++	struct sockaddr_un *addr = NULL;
174
++	int addrlen = 0;
175
++
176
++	if (u->addr) {
177
++		addr = u->addr->name;
178
++		addrlen = u->addr->len;
179
++	}
180
++
181
++	return match_to_local(profile, state, u->sk.sk_type, u->sk.sk_protocol,
182
++			      addr, addrlen, info);
183
++}
184
++
185
++#define CMD_ADDR	1
186
++#define CMD_LISTEN	2
187
++#define CMD_OPT		4
188
++
189
++static inline unsigned int match_to_cmd(struct aa_profile *profile,
190
++					unsigned int state, struct unix_sock *u,
191
++					char cmd, const char **info)
192
++{
193
++	state = match_to_sk(profile, state, u, info);
194
++	if (state) {
195
++		state = aa_dfa_match_len(profile->policy.dfa, state, &cmd, 1);
196
++		if (!state)
197
++			*info = "failed cmd selection match";
198
++	}
199
++
200
++	return state;
201
++}
202
++
203
++static inline unsigned int match_to_peer(struct aa_profile *profile,
204
++					 unsigned int state,
205
++					 struct unix_sock *u,
206
++					 struct sockaddr_un *peer_addr,
207
++					 int peer_addrlen,
208
++					 const char **info)
209
++{
210
++	state = match_to_cmd(profile, state, u, CMD_ADDR, info);
211
++	if (state) {
212
++		state = match_addr(profile, state, peer_addr, peer_addrlen);
213
++		if (!state)
214
++			*info = "failed peer address match";
215
++	}
216
++	return state;
217
++}
218
++
219
++static int do_perms(struct aa_profile *profile, unsigned int state, u32 request,
220
++		    struct common_audit_data *sa)
221
++{
222
++	struct aa_perms perms;
223
++
224
++	AA_BUG(!profile);
225
++
226
++	aa_compute_perms(profile->policy.dfa, state, &perms);
227
++	aa_apply_modes_to_perms(profile, &perms);
228
++	return aa_check_perms(profile, &perms, request, sa,
229
++			      audit_net_cb);
230
++}
231
++
232
++static int match_label(struct aa_profile *profile, struct aa_profile *peer,
233
++			      unsigned int state, u32 request,
234
++			      struct common_audit_data *sa)
235
++{
236
++	AA_BUG(!profile);
237
++	AA_BUG(!peer);
238
++
239
++	aad(sa)->peer = &peer->label;
240
++
241
++	if (state) {
242
++		state = aa_dfa_match(profile->policy.dfa, state,
243
++				     peer->base.hname);
244
++		if (!state)
245
++			aad(sa)->info = "failed peer label match";
246
++	}
247
++	return do_perms(profile, state, request, sa);
248
++}
249
++
250
++
251
++/* unix sock creation comes before we know if the socket will be an fs
252
++ * socket
253
++ * v6 - semantics are handled by mapping in profile load
254
++ * v7 - semantics require sock create for tasks creating an fs socket.
255
++ */
256
++static int profile_create_perm(struct aa_profile *profile, int family,
257
++			       int type, int protocol)
258
++{
259
++	unsigned int state;
260
++	DEFINE_AUDIT_NET(sa, OP_CREATE, NULL, family, type, protocol);
261
++
262
++	AA_BUG(!profile);
263
++	AA_BUG(profile_unconfined(profile));
264
++
265
++	if ((state = PROFILE_MEDIATES_AF(profile, AF_UNIX))) {
266
++		state = match_to_prot(profile, state, type, protocol,
267
++				      &aad(&sa)->info);
268
++		return do_perms(profile, state, AA_MAY_CREATE, &sa);
269
++	}
270
++
271
++	return aa_profile_af_perm(profile, &sa, AA_MAY_CREATE, family, type);
272
++}
273
++
274
++int aa_unix_create_perm(struct aa_label *label, int family, int type,
275
++			int protocol)
276
++{
277
++	struct aa_profile *profile;
278
++
279
++	if (unconfined(label))
280
++		return 0;
281
++
282
++	return fn_for_each_confined(label, profile,
283
++			profile_create_perm(profile, family, type, protocol));
284
++}
285
++
286
++
287
++static inline int profile_sk_perm(struct aa_profile *profile, const char *op,
288
++				  u32 request, struct sock *sk)
289
++{
290
++	unsigned int state;
291
++	DEFINE_AUDIT_SK(sa, op, sk);
292
++
293
++	AA_BUG(!profile);
294
++	AA_BUG(!sk);
295
++	AA_BUG(UNIX_FS(sk));
296
++	AA_BUG(profile_unconfined(profile));
297
++
298
++	state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
299
++	if (state) {
300
++		state = match_to_sk(profile, state, unix_sk(sk),
301
++				    &aad(&sa)->info);
302
++		return do_perms(profile, state, request, &sa);
303
++	}
304
++
305
++	return aa_profile_af_sk_perm(profile, &sa, request, sk);
306
++}
307
++
308
++int aa_unix_label_sk_perm(struct aa_label *label, const char *op, u32 request,
309
++			  struct sock *sk)
310
++{
311
++	struct aa_profile *profile;
312
++
313
++	return fn_for_each_confined(label, profile,
314
++			profile_sk_perm(profile, op, request, sk));
315
++}
316
++
317
++static int unix_label_sock_perm(struct aa_label *label, const char *op, u32 request,
318
++				struct socket *sock)
319
++{
320
++	if (unconfined(label))
321
++		return 0;
322
++	if (UNIX_FS(sock->sk))
323
++		return unix_fs_perm(op, request, label, unix_sk(sock->sk), 0);
324
++
325
++	return aa_unix_label_sk_perm(label, op, request, sock->sk);
326
++}
327
++
328
++/* revaliation, get/set attr */
329
++int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock)
330
++{
331
++	struct aa_label *label;
332
++	int error;
333
++
334
++	label = begin_current_label_crit_section();
335
++	error = unix_label_sock_perm(label, op, request, sock);
336
++	end_current_label_crit_section(label);
337
++
338
++	return error;
339
++}
340
++
341
++static int profile_bind_perm(struct aa_profile *profile, struct sock *sk,
342
++			     struct sockaddr *addr, int addrlen)
343
++{
344
++	unsigned int state;
345
++	DEFINE_AUDIT_SK(sa, OP_BIND, sk);
346
++
347
++	AA_BUG(!profile);
348
++	AA_BUG(!sk);
349
++	AA_BUG(addr->sa_family != AF_UNIX);
350
++	AA_BUG(profile_unconfined(profile));
351
++	AA_BUG(unix_addr_fs(addr, addrlen));
352
++
353
++	state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
354
++	if (state) {
355
++		/* bind for abstract socket */
356
++		aad(&sa)->net.addr = unix_addr(addr);
357
++		aad(&sa)->net.addrlen = addrlen;
358
++
359
++		state = match_to_local(profile, state,
360
++				       sk->sk_type, sk->sk_protocol,
361
++				       unix_addr(addr), addrlen,
362
++				       &aad(&sa)->info);
363
++		return do_perms(profile, state, AA_MAY_BIND, &sa);
364
++	}
365
++
366
++	return aa_profile_af_sk_perm(profile, &sa, AA_MAY_BIND, sk);
367
++}
368
++
369
++int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address,
370
++		      int addrlen)
371
++{
372
++	struct aa_profile *profile;
373
++	struct aa_label *label;
374
++	int error = 0;
375
++
376
++	 label = begin_current_label_crit_section();
377
++	 /* fs bind is handled by mknod */
378
++	if (!(unconfined(label) || unix_addr_fs(address, addrlen)))
379
++		error = fn_for_each_confined(label, profile,
380
++				profile_bind_perm(profile, sock->sk, address,
381
++						  addrlen));
382
++	end_current_label_crit_section(label);
383
++
384
++	return error;
385
++}
386
++
387
++int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
388
++			 int addrlen)
389
++{
390
++	/* unix connections are covered by the
391
++	 * - unix_stream_connect (stream) and unix_may_send hooks (dgram)
392
++	 * - fs connect is handled by open
393
++	 */
394
++	return 0;
395
++}
396
++
397
++static int profile_listen_perm(struct aa_profile *profile, struct sock *sk,
398
++			       int backlog)
399
++{
400
++	unsigned int state;
401
++	DEFINE_AUDIT_SK(sa, OP_LISTEN, sk);
402
++
403
++	AA_BUG(!profile);
404
++	AA_BUG(!sk);
405
++	AA_BUG(UNIX_FS(sk));
406
++	AA_BUG(profile_unconfined(profile));
407
++
408
++	state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
409
++	if (state) {
410
++		__be16 b = cpu_to_be16(backlog);
411
++
412
++		state = match_to_cmd(profile, state, unix_sk(sk), CMD_LISTEN,
413
++				     &aad(&sa)->info);
414
++		if (state) {
415
++			state = aa_dfa_match_len(profile->policy.dfa, state,
416
++						 (char *) &b, 2);
417
++			if (!state)
418
++				aad(&sa)->info = "failed listen backlog match";
419
++		}
420
++		return do_perms(profile, state, AA_MAY_LISTEN, &sa);
421
++	}
422
++
423
++	return aa_profile_af_sk_perm(profile, &sa, AA_MAY_LISTEN, sk);
424
++}
425
++
426
++int aa_unix_listen_perm(struct socket *sock, int backlog)
427
++{
428
++	struct aa_profile *profile;
429
++	struct aa_label *label;
430
++	int error = 0;
431
++
432
++	label = begin_current_label_crit_section();
433
++	if (!(unconfined(label) || UNIX_FS(sock->sk)))
434
++		error = fn_for_each_confined(label, profile,
435
++				profile_listen_perm(profile, sock->sk,
436
++						    backlog));
437
++	end_current_label_crit_section(label);
438
++
439
++	return error;
440
++}
441
++
442
++
443
++static inline int profile_accept_perm(struct aa_profile *profile,
444
++				      struct sock *sk,
445
++				      struct sock *newsk)
446
++{
447
++	unsigned int state;
448
++	DEFINE_AUDIT_SK(sa, OP_ACCEPT, sk);
449
++
450
++	AA_BUG(!profile);
451
++	AA_BUG(!sk);
452
++	AA_BUG(UNIX_FS(sk));
453
++	AA_BUG(profile_unconfined(profile));
454
++
455
++	state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
456
++	if (state) {
457
++		state = match_to_sk(profile, state, unix_sk(sk),
458
++				    &aad(&sa)->info);
459
++		return do_perms(profile, state, AA_MAY_ACCEPT, &sa);
460
++	}
461
++
462
++	return aa_profile_af_sk_perm(profile, &sa, AA_MAY_ACCEPT, sk);
463
++}
464
++
465
++/* ability of sock to connect, not peer address binding */
466
++int aa_unix_accept_perm(struct socket *sock, struct socket *newsock)
467
++{
468
++	struct aa_profile *profile;
469
++	struct aa_label *label;
470
++	int error = 0;
471
++
472
++	label = begin_current_label_crit_section();
473
++	if (!(unconfined(label) || UNIX_FS(sock->sk)))
474
++		error = fn_for_each_confined(label, profile,
475
++				profile_accept_perm(profile, sock->sk,
476
++						    newsock->sk));
477
++	end_current_label_crit_section(label);
478
++
479
++	return error;
480
++}
481
++
482
++
483
++/* dgram handled by unix_may_sendmsg, right to send on stream done at connect
484
++ * could do per msg unix_stream here
485
++ */
486
++/* sendmsg, recvmsg */
487
++int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
488
++		     struct msghdr *msg, int size)
489
++{
490
++	return 0;
491
++}
492
++
493
++
494
++static int profile_opt_perm(struct aa_profile *profile, const char *op, u32 request,
495
++			    struct sock *sk, int level, int optname)
496
++{
497
++	unsigned int state;
498
++	DEFINE_AUDIT_SK(sa, op, sk);
499
++
500
++	AA_BUG(!profile);
501
++	AA_BUG(!sk);
502
++	AA_BUG(UNIX_FS(sk));
503
++	AA_BUG(profile_unconfined(profile));
504
++
505
++	state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
506
++	if (state) {
507
++		__be16 b = cpu_to_be16(optname);
508
++
509
++		state = match_to_cmd(profile, state, unix_sk(sk), CMD_OPT,
510
++				     &aad(&sa)->info);
511
++		if (state) {
512
++			state = aa_dfa_match_len(profile->policy.dfa, state,
513
++						 (char *) &b, 2);
514
++			if (!state)
515
++				aad(&sa)->info = "failed sockopt match";
516
++		}
517
++		return do_perms(profile, state, request, &sa);
518
++	}
519
++
520
++	return aa_profile_af_sk_perm(profile, &sa, request, sk);
521
++}
522
++
523
++int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level,
524
++		     int optname)
525
++{
526
++	struct aa_profile *profile;
527
++	struct aa_label *label;
528
++	int error = 0;
529
++
530
++	label = begin_current_label_crit_section();
531
++	if (!(unconfined(label) || UNIX_FS(sock->sk)))
532
++		error = fn_for_each_confined(label, profile,
533
++				profile_opt_perm(profile, op, request,
534
++						 sock->sk, level, optname));
535
++	end_current_label_crit_section(label);
536
++
537
++	return error;
538
++}
539
++
540
++/* null peer_label is allowed, in which case the peer_sk label is used */
541
++static int profile_peer_perm(struct aa_profile *profile, const char *op, u32 request,
542
++			     struct sock *sk, struct sock *peer_sk,
543
++			     struct aa_label *peer_label,
544
++			     struct common_audit_data *sa)
545
++{
546
++	unsigned int state;
547
++
548
++	AA_BUG(!profile);
549
++	AA_BUG(profile_unconfined(profile));
550
++	AA_BUG(!sk);
551
++	AA_BUG(!peer_sk);
552
++	AA_BUG(UNIX_FS(peer_sk));
553
++
554
++	state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
555
++	if (state) {
556
++		struct aa_sk_ctx *peer_ctx = SK_CTX(peer_sk);
557
++		struct aa_profile *peerp;
558
++		struct sockaddr_un *addr = NULL;
559
++		int len = 0;
560
++		if (unix_sk(peer_sk)->addr) {
561
++			addr = unix_sk(peer_sk)->addr->name;
562
++			len = unix_sk(peer_sk)->addr->len;
563
++		}
564
++		state = match_to_peer(profile, state, unix_sk(sk),
565
++				      addr, len, &aad(sa)->info);
566
++		if (!peer_label)
567
++			peer_label = peer_ctx->label;
568
++		return fn_for_each_in_ns(peer_label, peerp,
569
++				   match_label(profile, peerp, state, request,
570
++					       sa));
571
++	}
572
++
573
++	return aa_profile_af_sk_perm(profile, sa, request, sk);
574
++}
575
++
576
++/**
577
++ *
578
++ * Requires: lock held on both @sk and @peer_sk
579
++ */
580
++int aa_unix_peer_perm(struct aa_label *label, const char *op, u32 request,
581
++		      struct sock *sk, struct sock *peer_sk,
582
++		      struct aa_label *peer_label)
583
++{
584
++	struct unix_sock *peeru = unix_sk(peer_sk);
585
++	struct unix_sock *u = unix_sk(sk);
586
++
587
++	AA_BUG(!label);
588
++	AA_BUG(!sk);
589
++	AA_BUG(!peer_sk);
590
++
591
++	if (UNIX_FS(aa_sock(peeru)))
592
++		return unix_fs_perm(op, request, label, peeru, 0);
593
++	else if (UNIX_FS(aa_sock(u)))
594
++		return unix_fs_perm(op, request, label, u, 0);
595
++	else {
596
++		struct aa_profile *profile;
597
++		DEFINE_AUDIT_SK(sa, op, sk);
598
++		aad(&sa)->net.peer_sk = peer_sk;
599
++
600
++		/* TODO: ns!!! */
601
++		if (!net_eq(sock_net(sk), sock_net(peer_sk))) {
602
++			;
603
++		}
604
++
605
++		if (unconfined(label))
606
++			return 0;
607
++
608
++		return fn_for_each_confined(label, profile,
609
++				profile_peer_perm(profile, op, request, sk,
610
++						  peer_sk, peer_label, &sa));
611
++	}
612
++}
613
++
614
++
615
++/* from net/unix/af_unix.c */
616
++static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
617
++{
618
++	if (unlikely(sk1 == sk2) || !sk2) {
619
++		unix_state_lock(sk1);
620
++		return;
621
++	}
622
++	if (sk1 < sk2) {
623
++		unix_state_lock(sk1);
624
++		unix_state_lock_nested(sk2);
625
++	} else {
626
++		unix_state_lock(sk2);
627
++		unix_state_lock_nested(sk1);
628
++	}
629
++}
630
++
631
++static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
632
++{
633
++	if (unlikely(sk1 == sk2) || !sk2) {
634
++		unix_state_unlock(sk1);
635
++		return;
636
++	}
637
++	unix_state_unlock(sk1);
638
++	unix_state_unlock(sk2);
639
++}
640
++
641
++int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request,
642
++		      struct socket *sock)
643
++{
644
++	struct sock *peer_sk = NULL;
645
++	u32 sk_req = request & ~NET_PEER_MASK;
646
++	int error = 0;
647
++
648
++	AA_BUG(!label);
649
++	AA_BUG(!sock);
650
++	AA_BUG(!sock->sk);
651
++	AA_BUG(sock->sk->sk_family != AF_UNIX);
652
++
653
++	/* TODO: update sock label with new task label */
654
++	unix_state_lock(sock->sk);
655
++	peer_sk = unix_peer(sock->sk);
656
++	if (peer_sk)
657
++		sock_hold(peer_sk);
658
++	if (!unix_connected(sock) && sk_req) {
659
++		error = unix_label_sock_perm(label, op, sk_req, sock);
660
++		if (!error) {
661
++			// update label
662
++		}
663
++	}
664
++	unix_state_unlock(sock->sk);
665
++	if (!peer_sk)
666
++		return error;
667
++
668
++	unix_state_double_lock(sock->sk, peer_sk);
669
++	if (UNIX_FS(sock->sk)) {
670
++		error = unix_fs_perm(op, request, label, unix_sk(sock->sk),
671
++				     PATH_SOCK_COND);
672
++	} else if (UNIX_FS(peer_sk)) {
673
++		error = unix_fs_perm(op, request, label, unix_sk(peer_sk),
674
++				     PATH_SOCK_COND);
675
++	} else {
676
++		struct aa_sk_ctx *pctx = SK_CTX(peer_sk);
677
++		if (sk_req)
678
++			error = aa_unix_label_sk_perm(label, op, sk_req,
679
++						      sock->sk);
680
++		last_error(error,
681
++			xcheck(aa_unix_peer_perm(label, op,
682
++						 MAY_READ | MAY_WRITE,
683
++						 sock->sk, peer_sk, NULL),
684
++			       aa_unix_peer_perm(pctx->label, op,
685
++						 MAY_READ | MAY_WRITE,
686
++						 peer_sk, sock->sk, label)));
687
++	}
688
++
689
++	unix_state_double_unlock(sock->sk, peer_sk);
690
++	sock_put(peer_sk);
691
++
692
++	return error;
693
++}
694
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
695
+index 518d5928661b..63a8a462fc96 100644
696
+--- a/security/apparmor/apparmorfs.c
697
+@@ -2187,6 +2187,11 @@ static struct aa_sfs_entry aa_sfs_entry_ns[] = {
698
+ 	{ }
699
+ };
700
+ 
701
++static struct aa_sfs_entry aa_sfs_entry_dbus[] = {
702
++	AA_SFS_FILE_STRING("mask", "acquire send receive"),
703
++	{ }
704
++};
705
++
706
+ static struct aa_sfs_entry aa_sfs_entry_query_label[] = {
707
+ 	AA_SFS_FILE_STRING("perms", "allow deny audit quiet"),
708
+ 	AA_SFS_FILE_BOOLEAN("data",		1),
709
+@@ -2210,6 +2215,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
710
+ 	AA_SFS_DIR("caps",			aa_sfs_entry_caps),
711
+ 	AA_SFS_DIR("ptrace",			aa_sfs_entry_ptrace),
712
+ 	AA_SFS_DIR("signal",			aa_sfs_entry_signal),
713
++	AA_SFS_DIR("dbus",			aa_sfs_entry_dbus),
714
+ 	AA_SFS_DIR("query",			aa_sfs_entry_query),
715
+ 	{ }
716
+ };
717
+diff --git a/security/apparmor/file.c b/security/apparmor/file.c
718
+index db80221891c6..e62791106900 100644
719
+--- a/security/apparmor/file.c
720
+@@ -16,6 +16,7 @@
721
+ #include <linux/fdtable.h>
722
+ #include <linux/file.h>
723
+ 
724
++#include "include/af_unix.h"
725
+ #include "include/apparmor.h"
726
+ #include "include/audit.h"
727
+ #include "include/context.h"
728
+@@ -289,7 +290,8 @@ int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name,
729
+ {
730
+ 	int e = 0;
731
+ 
732
+-	if (profile_unconfined(profile))
733
++	if (profile_unconfined(profile) ||
734
++	    ((flags & PATH_SOCK_COND) && !PROFILE_MEDIATES_AF(profile, AF_UNIX)))
735
+ 		return 0;
736
+ 	aa_str_perms(profile->file.dfa, profile->file.start, name, cond, perms);
737
+ 	if (request & ~perms->allow)
738
+diff --git a/security/apparmor/include/af_unix.h b/security/apparmor/include/af_unix.h
739
+new file mode 100644
740
+index 000000000000..d1b7f2316be4
741
+--- /dev/null
742
+@@ -0,0 +1,114 @@
743
++/*
744
++ * AppArmor security module
745
++ *
746
++ * This file contains AppArmor af_unix fine grained mediation
747
++ *
748
++ * Copyright 2014 Canonical Ltd.
749
++ *
750
++ * This program is free software; you can redistribute it and/or
751
++ * modify it under the terms of the GNU General Public License as
752
++ * published by the Free Software Foundation, version 2 of the
753
++ * License.
754
++ */
755
++#ifndef __AA_AF_UNIX_H
756
++
757
++#include <net/af_unix.h>
758
++
759
++#include "label.h"
760
++//#include "include/net.h"
761
++
762
++#define unix_addr_len(L) ((L) - sizeof(sa_family_t))
763
++#define unix_abstract_name_len(L) (unix_addr_len(L) - 1)
764
++#define unix_abstract_len(U) (unix_abstract_name_len((U)->addr->len))
765
++#define addr_unix_abstract_name(B) ((B)[0] == 0)
766
++#define addr_unix_anonymous(U) (addr_unix_len(U) <= 0)
767
++#define addr_unix_abstract(U) (!addr_unix_anonymous(U) && addr_unix_abstract_name((U)->addr))
768
++//#define unix_addr_fs(U) (!unix_addr_anonymous(U) && !unix_addr_abstract_name((U)->addr))
769
++
770
++#define unix_addr(A) ((struct sockaddr_un *)(A))
771
++#define unix_addr_anon(A, L) ((A) && unix_addr_len(L) <= 0)
772
++#define unix_addr_fs(A, L) (!unix_addr_anon(A, L) && !addr_unix_abstract_name(unix_addr(A)->sun_path))
773
++
774
++#define UNIX_ANONYMOUS(U) (!unix_sk(U)->addr)
775
++/* from net/unix/af_unix.c */
776
++#define UNIX_ABSTRACT(U) (!UNIX_ANONYMOUS(U) &&				\
777
++			  unix_sk(U)->addr->hash < UNIX_HASH_SIZE)
778
++#define UNIX_FS(U) (!UNIX_ANONYMOUS(U) && unix_sk(U)->addr->name->sun_path[0])
779
++#define unix_peer(sk) (unix_sk(sk)->peer)
780
++#define unix_connected(S) ((S)->state == SS_CONNECTED)
781
++
782
++static inline void print_unix_addr(struct sockaddr_un *A, int L)
783
++{
784
++	char *buf = (A) ? (char *) &(A)->sun_path : NULL;
785
++	int len = unix_addr_len(L);
786
++	if (!buf || len <= 0)
787
++		printk(" <anonymous>");
788
++	else if (buf[0])
789
++		printk(" %s", buf);
790
++	else
791
++		/* abstract name len includes leading \0 */
792
++		printk(" %d @%.*s", len - 1, len - 1, buf+1);
793
++};
794
++
795
++/*
796
++	printk("%s: %s: f %d, t %d, p %d", __FUNCTION__,		\
797
++	       #SK ,							\
798
++*/
799
++#define print_unix_sk(SK)						\
800
++do {									\
801
++	struct unix_sock *u = unix_sk(SK);				\
802
++	printk("%s: f %d, t %d, p %d",	#SK ,				\
803
++	       (SK)->sk_family, (SK)->sk_type, (SK)->sk_protocol);	\
804
++	if (u->addr)							\
805
++		print_unix_addr(u->addr->name, u->addr->len);		\
806
++	else								\
807
++		print_unix_addr(NULL, sizeof(sa_family_t));		\
808
++	/* printk("\n");*/						\
809
++} while (0)
810
++
811
++#define print_sk(SK)							\
812
++do {									\
813
++	if (!(SK)) {							\
814
++		printk("%s: %s is null\n", __FUNCTION__, #SK);		\
815
++	} else if ((SK)->sk_family == PF_UNIX) {			\
816
++		print_unix_sk(SK);					\
817
++		printk("\n");						\
818
++	} else {							\
819
++		printk("%s: %s: family %d\n", __FUNCTION__, #SK ,	\
820
++		       (SK)->sk_family);				\
821
++	}								\
822
++} while (0)
823
++
824
++#define print_sock_addr(U) \
825
++do {			       \
826
++	printk("%s:\n", __FUNCTION__);					\
827
++	printk("    sock %s:", sock_ctx && sock_ctx->label ? aa_label_printk(sock_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(sock); \
828
++	printk("    other %s:", other_ctx && other_ctx->label ? aa_label_printk(other_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(other); \
829
++	printk("    new %s", new_ctx && new_ctx->label ? aa_label_printk(new_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(newsk); \
830
++} while (0)
831
++
832
++
833
++
834
++
835
++int aa_unix_peer_perm(struct aa_label *label, const char *op, u32 request,
836
++		      struct sock *sk, struct sock *peer_sk,
837
++		      struct aa_label *peer_label);
838
++int aa_unix_label_sk_perm(struct aa_label *label, const char *op, u32 request,
839
++			  struct sock *sk);
840
++int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock);
841
++int aa_unix_create_perm(struct aa_label *label, int family, int type,
842
++			int protocol);
843
++int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address,
844
++		      int addrlen);
845
++int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
846
++			 int addrlen);
847
++int aa_unix_listen_perm(struct socket *sock, int backlog);
848
++int aa_unix_accept_perm(struct socket *sock, struct socket *newsock);
849
++int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
850
++		     struct msghdr *msg, int size);
851
++int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level,
852
++		     int optname);
853
++int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request,
854
++		      struct socket *sock);
855
++
856
++#endif /* __AA_AF_UNIX_H */
857
+diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
858
+index 140c8efcf364..0ae45240c352 100644
859
+--- a/security/apparmor/include/net.h
860
+@@ -90,8 +90,6 @@ extern struct aa_sfs_entry aa_sfs_entry_network[];
861
+ void audit_net_cb(struct audit_buffer *ab, void *va);
862
+ int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
863
+ 		       u32 request, u16 family, int type);
864
+-int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
865
+-	       int type, int protocol);
866
+ static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
867
+ 					struct common_audit_data *sa,
868
+ 					u32 request,
869
+@@ -100,8 +98,20 @@ static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
870
+ 	return aa_profile_af_perm(profile, sa, request, sk->sk_family,
871
+ 				  sk->sk_type);
872
+ }
873
+-int aa_sk_perm(const char *op, u32 request, struct sock *sk);
874
+ 
875
++int aa_sock_perm(const char *op, u32 request, struct socket *sock);
876
++int aa_sock_create_perm(struct aa_label *label, int family, int type,
877
++			int protocol);
878
++int aa_sock_bind_perm(struct socket *sock, struct sockaddr *address,
879
++		      int addrlen);
880
++int aa_sock_connect_perm(struct socket *sock, struct sockaddr *address,
881
++			 int addrlen);
882
++int aa_sock_listen_perm(struct socket *sock, int backlog);
883
++int aa_sock_accept_perm(struct socket *sock, struct socket *newsock);
884
++int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
885
++		     struct msghdr *msg, int size);
886
++int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, int level,
887
++		     int optname);
888
+ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
889
+ 		      struct socket *sock);
890
+ 
891
+diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
892
+index 05fb3305671e..26762db2207d 100644
893
+--- a/security/apparmor/include/path.h
894
+@@ -18,6 +18,7 @@
895
+ 
896
+ enum path_flags {
897
+ 	PATH_IS_DIR = 0x1,		/* path is a directory */
898
++	PATH_SOCK_COND = 0x2,
899
+ 	PATH_CONNECT_PATH = 0x4,	/* connect disconnected paths to / */
900
+ 	PATH_CHROOT_REL = 0x8,		/* do path lookup relative to chroot */
901
+ 	PATH_CHROOT_NSCONNECT = 0x10,	/* connect paths that are at ns root */
902
+diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
903
+index 4364088a0b9e..26660a1a50b0 100644
904
+--- a/security/apparmor/include/policy.h
905
+@@ -226,7 +226,7 @@ static inline unsigned int PROFILE_MEDIATES_SAFE(struct aa_profile *profile,
906
+ static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile,
907
+ 					       u16 AF) {
908
+ 	unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
909
+-	u16 be_af = cpu_to_be16(AF);
910
++	__be16 be_af = cpu_to_be16(AF);
911
+ 
912
+ 	if (!state)
913
+ 		return 0;
914
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
915
+index 72b915dfcaf7..5533d2f1d9de 100644
916
+--- a/security/apparmor/lsm.c
917
+@@ -26,6 +26,7 @@
918
+ #include <linux/kmemleak.h>
919
+ #include <net/sock.h>
920
+ 
921
++#include "include/af_unix.h"
922
+ #include "include/apparmor.h"
923
+ #include "include/apparmorfs.h"
924
+ #include "include/audit.h"
925
+@@ -782,16 +783,96 @@ static void apparmor_sk_clone_security(const struct sock *sk,
926
+ 	path_get(&new->path);
927
+ }
928
+ 
929
+-static int aa_sock_create_perm(struct aa_label *label, int family, int type,
930
+-			       int protocol)
931
++static struct path *UNIX_FS_CONN_PATH(struct sock *sk, struct sock *newsk)
932
+ {
933
+-	AA_BUG(!label);
934
+-	AA_BUG(in_interrupt());
935
++	if (sk->sk_family == PF_UNIX && UNIX_FS(sk))
936
++		return &unix_sk(sk)->path;
937
++	else if (newsk->sk_family == PF_UNIX && UNIX_FS(newsk))
938
++		return &unix_sk(newsk)->path;
939
++	return NULL;
940
++}
941
++
942
++/**
943
++ * apparmor_unix_stream_connect - check perms before making unix domain conn
944
++ *
945
++ * peer is locked when this hook is called
946
++ */
947
++static int apparmor_unix_stream_connect(struct sock *sk, struct sock *peer_sk,
948
++					struct sock *newsk)
949
++{
950
++	struct aa_sk_ctx *sk_ctx = SK_CTX(sk);
951
++	struct aa_sk_ctx *peer_ctx = SK_CTX(peer_sk);
952
++	struct aa_sk_ctx *new_ctx = SK_CTX(newsk);
953
++	struct aa_label *label;
954
++	struct path *path;
955
++	int error;
956
+ 
957
+-	return aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family, type,
958
+-			  protocol);
959
++	label = __begin_current_label_crit_section();
960
++	error = aa_unix_peer_perm(label, OP_CONNECT,
961
++				(AA_MAY_CONNECT | AA_MAY_SEND | AA_MAY_RECEIVE),
962
++				  sk, peer_sk, NULL);
963
++	if (!UNIX_FS(peer_sk)) {
964
++		last_error(error,
965
++			aa_unix_peer_perm(peer_ctx->label, OP_CONNECT,
966
++				(AA_MAY_ACCEPT | AA_MAY_SEND | AA_MAY_RECEIVE),
967
++				peer_sk, sk, label));
968
++	}
969
++	__end_current_label_crit_section(label);
970
++
971
++	if (error)
972
++		return error;
973
++
974
++	/* label newsk if it wasn't labeled in post_create. Normally this
975
++	 * would be done in sock_graft, but because we are directly looking
976
++	 * at the peer_sk to obtain peer_labeling for unix socks this
977
++	 * does not work
978
++	 */
979
++	if (!new_ctx->label)
980
++		new_ctx->label = aa_get_label(peer_ctx->label);
981
++
982
++	/* Cross reference the peer labels for SO_PEERSEC */
983
++	if (new_ctx->peer)
984
++		aa_put_label(new_ctx->peer);
985
++
986
++	if (sk_ctx->peer)
987
++		aa_put_label(sk_ctx->peer);
988
++
989
++	new_ctx->peer = aa_get_label(sk_ctx->label);
990
++	sk_ctx->peer = aa_get_label(peer_ctx->label);
991
++
992
++	path = UNIX_FS_CONN_PATH(sk, peer_sk);
993
++	if (path) {
994
++		new_ctx->path = *path;
995
++		sk_ctx->path = *path;
996
++		path_get(path);
997
++		path_get(path);
998
++	}
999
++	return 0;
1000
+ }
1001
+ 
1002
++/**
1003
++ * apparmor_unix_may_send - check perms before conn or sending unix dgrams
1004
++ *
1005
++ * other is locked when this hook is called
1006
++ *
1007
++ * dgram connect calls may_send, peer setup but path not copied?????
1008
++ */
1009
++static int apparmor_unix_may_send(struct socket *sock, struct socket *peer)
1010
++{
1011
++	struct aa_sk_ctx *peer_ctx = SK_CTX(peer->sk);
1012
++	struct aa_label *label;
1013
++	int error;
1014
++
1015
++	label = __begin_current_label_crit_section();
1016
++	error = xcheck(aa_unix_peer_perm(label, OP_SENDMSG, AA_MAY_SEND,
1017
++					 sock->sk, peer->sk, NULL),
1018
++		       aa_unix_peer_perm(peer_ctx->label, OP_SENDMSG,
1019
++					 AA_MAY_RECEIVE,
1020
++					 peer->sk, sock->sk, label));
1021
++	__end_current_label_crit_section(label);
1022
++
1023
++	return error;
1024
++}
1025
+ 
1026
+ /**
1027
+  * apparmor_socket_create - check perms before creating a new socket
1028
+@@ -849,12 +930,7 @@ static int apparmor_socket_post_create(struct socket *sock, int family,
1029
+ static int apparmor_socket_bind(struct socket *sock,
1030
+ 				struct sockaddr *address, int addrlen)
1031
+ {
1032
+-	AA_BUG(!sock);
1033
+-	AA_BUG(!sock->sk);
1034
+-	AA_BUG(!address);
1035
+-	AA_BUG(in_interrupt());
1036
+-
1037
+-	return aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk);
1038
++	return aa_sock_bind_perm(sock, address, addrlen);
1039
+ }
1040
+ 
1041
+ /**
1042
+@@ -863,12 +939,7 @@ static int apparmor_socket_bind(struct socket *sock,
1043
+ static int apparmor_socket_connect(struct socket *sock,
1044
+ 				   struct sockaddr *address, int addrlen)
1045
+ {
1046
+-	AA_BUG(!sock);
1047
+-	AA_BUG(!sock->sk);
1048
+-	AA_BUG(!address);
1049
+-	AA_BUG(in_interrupt());
1050
+-
1051
+-	return aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk);
1052
++	return aa_sock_connect_perm(sock, address, addrlen);
1053
+ }
1054
+ 
1055
+ /**
1056
+@@ -876,11 +947,7 @@ static int apparmor_socket_connect(struct socket *sock,
1057
+  */
1058
+ static int apparmor_socket_listen(struct socket *sock, int backlog)
1059
+ {
1060
+-	AA_BUG(!sock);
1061
+-	AA_BUG(!sock->sk);
1062
+-	AA_BUG(in_interrupt());
1063
+-
1064
+-	return aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk);
1065
++	return aa_sock_listen_perm(sock, backlog);
1066
+ }
1067
+ 
1068
+ /**
1069
+@@ -891,23 +958,7 @@ static int apparmor_socket_listen(struct socket *sock, int backlog)
1070
+  */
1071
+ static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
1072
+ {
1073
+-	AA_BUG(!sock);
1074
+-	AA_BUG(!sock->sk);
1075
+-	AA_BUG(!newsock);
1076
+-	AA_BUG(in_interrupt());
1077
+-
1078
+-	return aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk);
1079
+-}
1080
+-
1081
+-static int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
1082
+-			    struct msghdr *msg, int size)
1083
+-{
1084
+-	AA_BUG(!sock);
1085
+-	AA_BUG(!sock->sk);
1086
+-	AA_BUG(!msg);
1087
+-	AA_BUG(in_interrupt());
1088
+-
1089
+-	return aa_sk_perm(op, request, sock->sk);
1090
++	return aa_sock_accept_perm(sock, newsock);
1091
+ }
1092
+ 
1093
+ /**
1094
+@@ -928,16 +979,6 @@ static int apparmor_socket_recvmsg(struct socket *sock,
1095
+ 	return aa_sock_msg_perm(OP_RECVMSG, AA_MAY_RECEIVE, sock, msg, size);
1096
+ }
1097
+ 
1098
+-/* revaliation, get/set attr, shutdown */
1099
+-static int aa_sock_perm(const char *op, u32 request, struct socket *sock)
1100
+-{
1101
+-	AA_BUG(!sock);
1102
+-	AA_BUG(!sock->sk);
1103
+-	AA_BUG(in_interrupt());
1104
+-
1105
+-	return aa_sk_perm(op, request, sock->sk);
1106
+-}
1107
+-
1108
+ /**
1109
+  * apparmor_socket_getsockname - check perms before getting the local address
1110
+  */
1111
+@@ -954,17 +995,6 @@ static int apparmor_socket_getpeername(struct socket *sock)
1112
+ 	return aa_sock_perm(OP_GETPEERNAME, AA_MAY_GETATTR, sock);
1113
+ }
1114
+ 
1115
+-/* revaliation, get/set attr, opt */
1116
+-static int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock,
1117
+-			    int level, int optname)
1118
+-{
1119
+-	AA_BUG(!sock);
1120
+-	AA_BUG(!sock->sk);
1121
+-	AA_BUG(in_interrupt());
1122
+-
1123
+-	return aa_sk_perm(op, request, sock->sk);
1124
+-}
1125
+-
1126
+ /**
1127
+  * apparmor_getsockopt - check perms before getting socket options
1128
+  */
1129
+@@ -1009,11 +1039,25 @@ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
1130
+ 
1131
+ static struct aa_label *sk_peer_label(struct sock *sk)
1132
+ {
1133
++	struct sock *peer_sk;
1134
+ 	struct aa_sk_ctx *ctx = SK_CTX(sk);
1135
+ 
1136
+ 	if (ctx->peer)
1137
+ 		return ctx->peer;
1138
+ 
1139
++	if (sk->sk_family != PF_UNIX)
1140
++		return ERR_PTR(-ENOPROTOOPT);
1141
++
1142
++	/* check for sockpair peering which does not go through
1143
++	 * security_unix_stream_connect
1144
++	 */
1145
++	peer_sk = unix_peer(sk);
1146
++	if (peer_sk) {
1147
++		ctx = SK_CTX(peer_sk);
1148
++		if (ctx->label)
1149
++			return ctx->label;
1150
++	}
1151
++
1152
+ 	return ERR_PTR(-ENOPROTOOPT);
1153
+ }
1154
+ 
1155
+@@ -1137,6 +1181,9 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
1156
+ 	LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security),
1157
+ 	LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security),
1158
+ 
1159
++	LSM_HOOK_INIT(unix_stream_connect, apparmor_unix_stream_connect),
1160
++	LSM_HOOK_INIT(unix_may_send, apparmor_unix_may_send),
1161
++
1162
+ 	LSM_HOOK_INIT(socket_create, apparmor_socket_create),
1163
+ 	LSM_HOOK_INIT(socket_post_create, apparmor_socket_post_create),
1164
+ 	LSM_HOOK_INIT(socket_bind, apparmor_socket_bind),
1165
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
1166
+index 33d54435f8d6..dd1953b08e58 100644
1167
+--- a/security/apparmor/net.c
1168
+@@ -12,6 +12,7 @@
1169
+  * License.
1170
+  */
1171
+ 
1172
++#include "include/af_unix.h"
1173
+ #include "include/apparmor.h"
1174
+ #include "include/audit.h"
1175
+ #include "include/context.h"
1176
+@@ -24,6 +25,7 @@
1177
+ 
1178
+ struct aa_sfs_entry aa_sfs_entry_network[] = {
1179
+ 	AA_SFS_FILE_STRING("af_mask",	AA_SFS_AF_MASK),
1180
++	AA_SFS_FILE_BOOLEAN("af_unix",	1),
1181
+ 	{ }
1182
+ };
1183
+ 
1184
+@@ -69,6 +71,36 @@ static const char * const net_mask_names[] = {
1185
+ 	"unknown",
1186
+ };
1187
+ 
1188
++static void audit_unix_addr(struct audit_buffer *ab, const char *str,
1189
++			    struct sockaddr_un *addr, int addrlen)
1190
++{
1191
++	int len = unix_addr_len(addrlen);
1192
++
1193
++	if (!addr || len <= 0) {
1194
++		audit_log_format(ab, " %s=none", str);
1195
++	} else if (addr->sun_path[0]) {
1196
++		audit_log_format(ab, " %s=", str);
1197
++		audit_log_untrustedstring(ab, addr->sun_path);
1198
++	} else {
1199
++		audit_log_format(ab, " %s=\"@", str);
1200
++		if (audit_string_contains_control(&addr->sun_path[1], len - 1))
1201
++			audit_log_n_hex(ab, &addr->sun_path[1], len - 1);
1202
++		else
1203
++			audit_log_format(ab, "%.*s", len - 1,
1204
++					 &addr->sun_path[1]);
1205
++		audit_log_format(ab, "\"");
1206
++	}
1207
++}
1208
++
1209
++static void audit_unix_sk_addr(struct audit_buffer *ab, const char *str,
1210
++			       struct sock *sk)
1211
++{
1212
++	struct unix_sock *u = unix_sk(sk);
1213
++	if (u && u->addr)
1214
++		audit_unix_addr(ab, str, u->addr->name, u->addr->len);
1215
++	else
1216
++		audit_unix_addr(ab, str, NULL, 0);
1217
++}
1218
+ 
1219
+ /* audit callback for net specific fields */
1220
+ void audit_net_cb(struct audit_buffer *ab, void *va)
1221
+@@ -98,6 +130,23 @@ void audit_net_cb(struct audit_buffer *ab, void *va)
1222
+ 					   net_mask_names, NET_PERMS_MASK);
1223
+ 		}
1224
+ 	}
1225
++	if (sa->u.net->family == AF_UNIX) {
1226
++		if ((aad(sa)->request & ~NET_PEER_MASK) && aad(sa)->net.addr)
1227
++			audit_unix_addr(ab, "addr",
1228
++					unix_addr(aad(sa)->net.addr),
1229
++					aad(sa)->net.addrlen);
1230
++		else
1231
++			audit_unix_sk_addr(ab, "addr", sa->u.net->sk);
1232
++		if (aad(sa)->request & NET_PEER_MASK) {
1233
++			if (aad(sa)->net.addr)
1234
++				audit_unix_addr(ab, "peer_addr",
1235
++						unix_addr(aad(sa)->net.addr),
1236
++						aad(sa)->net.addrlen);
1237
++			else
1238
++				audit_unix_sk_addr(ab, "peer_addr",
1239
++						   aad(sa)->net.peer_sk);
1240
++		}
1241
++	}
1242
+ 	if (aad(sa)->peer) {
1243
+ 		audit_log_format(ab, " peer=");
1244
+ 		aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
1245
+@@ -172,6 +221,127 @@ int aa_sk_perm(const char *op, u32 request, struct sock *sk)
1246
+ 	return error;
1247
+ }
1248
+ 
1249
++#define af_select(FAMILY, FN, DEF_FN)		\
1250
++({						\
1251
++	int __e;				\
1252
++	switch ((FAMILY)) {			\
1253
++	case AF_UNIX:				\
1254
++		__e = aa_unix_ ## FN;		\
1255
++		break;				\
1256
++	default:				\
1257
++		__e = DEF_FN;			\
1258
++	}					\
1259
++	__e;					\
1260
++})
1261
++
1262
++/* TODO: push into lsm.c ???? */
1263
++
1264
++/* revaliation, get/set attr, shutdown */
1265
++int aa_sock_perm(const char *op, u32 request, struct socket *sock)
1266
++{
1267
++	AA_BUG(!sock);
1268
++	AA_BUG(!sock->sk);
1269
++	AA_BUG(in_interrupt());
1270
++
1271
++	return af_select(sock->sk->sk_family,
1272
++			 sock_perm(op, request, sock),
1273
++			 aa_sk_perm(op, request, sock->sk));
1274
++}
1275
++
1276
++int aa_sock_create_perm(struct aa_label *label, int family, int type,
1277
++			int protocol)
1278
++{
1279
++	AA_BUG(!label);
1280
++	/* TODO: .... */
1281
++	AA_BUG(in_interrupt());
1282
++
1283
++	return af_select(family,
1284
++			 create_perm(label, family, type, protocol),
1285
++			 aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family,
1286
++				    type, protocol));
1287
++}
1288
++
1289
++int aa_sock_bind_perm(struct socket *sock, struct sockaddr *address,
1290
++		      int addrlen)
1291
++{
1292
++	AA_BUG(!sock);
1293
++	AA_BUG(!sock->sk);
1294
++	AA_BUG(!address);
1295
++	/* TODO: .... */
1296
++	AA_BUG(in_interrupt());
1297
++
1298
++	return af_select(sock->sk->sk_family,
1299
++			 bind_perm(sock, address, addrlen),
1300
++			 aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk));
1301
++}
1302
++
1303
++int aa_sock_connect_perm(struct socket *sock, struct sockaddr *address,
1304
++			 int addrlen)
1305
++{
1306
++	AA_BUG(!sock);
1307
++	AA_BUG(!sock->sk);
1308
++	AA_BUG(!address);
1309
++	/* TODO: .... */
1310
++	AA_BUG(in_interrupt());
1311
++
1312
++	return af_select(sock->sk->sk_family,
1313
++			 connect_perm(sock, address, addrlen),
1314
++			 aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk));
1315
++}
1316
++
1317
++int aa_sock_listen_perm(struct socket *sock, int backlog)
1318
++{
1319
++	AA_BUG(!sock);
1320
++	AA_BUG(!sock->sk);
1321
++	/* TODO: .... */
1322
++	AA_BUG(in_interrupt());
1323
++
1324
++	return af_select(sock->sk->sk_family,
1325
++			 listen_perm(sock, backlog),
1326
++			 aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk));
1327
++}
1328
++
1329
++/* ability of sock to connect, not peer address binding */
1330
++int aa_sock_accept_perm(struct socket *sock, struct socket *newsock)
1331
++{
1332
++	AA_BUG(!sock);
1333
++	AA_BUG(!sock->sk);
1334
++	AA_BUG(!newsock);
1335
++	/* TODO: .... */
1336
++	AA_BUG(in_interrupt());
1337
++
1338
++	return af_select(sock->sk->sk_family,
1339
++			 accept_perm(sock, newsock),
1340
++			 aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk));
1341
++}
1342
++
1343
++/* sendmsg, recvmsg */
1344
++int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
1345
++		     struct msghdr *msg, int size)
1346
++{
1347
++	AA_BUG(!sock);
1348
++	AA_BUG(!sock->sk);
1349
++	AA_BUG(!msg);
1350
++	/* TODO: .... */
1351
++	AA_BUG(in_interrupt());
1352
++
1353
++	return af_select(sock->sk->sk_family,
1354
++			 msg_perm(op, request, sock, msg, size),
1355
++			 aa_sk_perm(op, request, sock->sk));
1356
++}
1357
++
1358
++/* revaliation, get/set attr, opt */
1359
++int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, int level,
1360
++		     int optname)
1361
++{
1362
++	AA_BUG(!sock);
1363
++	AA_BUG(!sock->sk);
1364
++	AA_BUG(in_interrupt());
1365
++
1366
++	return af_select(sock->sk->sk_family,
1367
++			 opt_perm(op, request, sock, level, optname),
1368
++			 aa_sk_perm(op, request, sock->sk));
1369
++}
1370
+ 
1371
+ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
1372
+ 		      struct socket *sock)
1373
+@@ -180,5 +350,7 @@ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
1374
+ 	AA_BUG(!sock);
1375
+ 	AA_BUG(!sock->sk);
1376
+ 
1377
+-	return aa_label_sk_perm(label, op, request, sock->sk);
1378
++	return af_select(sock->sk->sk_family,
1379
++			 file_perm(label, op, request, sock),
1380
++			 aa_label_sk_perm(label, op, request, sock->sk));
1381
+ }
1382
+-- 
1383
+2.14.1
1384
+
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:        Kernel
3 3
 Name:           linux-aws
4 4
 Version:        4.14.54
5
-Release:        1%{?kat_build:.%kat_build}%{?dist}
5
+Release:        2%{?kat_build:.%kat_build}%{?dist}
6 6
 License:    	GPLv2
7 7
 URL:        	http://www.kernel.org/
8 8
 Group:        	System Environment/Kernel
... ...
@@ -33,6 +33,9 @@ Patch24:        Allow-some-algo-tests-for-FIPS.patch
33 33
 Patch26:        add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch
34 34
 # Fix CVE-2017-1000252
35 35
 Patch28:        kvm-dont-accept-wrong-gsi-values.patch
36
+# Out-of-tree patches from AppArmor:
37
+Patch29:        0001-apparmor-add-base-infastructure-for-socket-mediation.patch
38
+Patch30:        0002-apparmor-af_unix-mediation.patch
36 39
 
37 40
 %if 0%{?kat_build:1}
38 41
 Patch1000:	%{kat_build}.patch
... ...
@@ -119,6 +122,9 @@ This package contains the 'perf' performance analysis tools for Linux kernel.
119 119
 %patch24 -p1
120 120
 %patch26 -p1
121 121
 %patch28 -p1
122
+%patch29 -p1
123
+%patch30 -p1
124
+
122 125
 %if 0%{?kat_build:1}
123 126
 %patch1000 -p1
124 127
 %endif
... ...
@@ -305,6 +311,8 @@ ln -sf %{name}-%{uname_r}.cfg /boot/photon.cfg
305 305
 /usr/share/doc/*
306 306
 
307 307
 %changelog
308
+*   Thu Aug 30 2018 Srivatsa S. Bhat <srivatsa@csail.mit.edu> 4.14.54-2
309
+-   Apply out-of-tree patches needed for AppArmor.
308 310
 *   Mon Jul 09 2018 Him Kalyan Bordoloi <bordoloih@vmware.com> 4.14.54-1
309 311
 -   Update to version 4.14.54
310 312
 *   Thu Feb 22 2018 Srivatsa S. Bhat <srivatsa@csail.mit.edu> 4.14.8-1
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:        Kernel
3 3
 Name:           linux-secure
4 4
 Version:        4.14.54
5
-Release:        1%{?kat_build:.%kat_build}%{?dist}
5
+Release:        2%{?kat_build:.%kat_build}%{?dist}
6 6
 License:        GPLv2
7 7
 URL:            http://www.kernel.org/
8 8
 Group:          System Environment/Kernel
... ...
@@ -32,6 +32,9 @@ Patch24:        Allow-some-algo-tests-for-FIPS.patch
32 32
 Patch26:        add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch
33 33
 # Fix CVE-2017-1000252
34 34
 Patch31:        kvm-dont-accept-wrong-gsi-values.patch
35
+# Out-of-tree patches from AppArmor:
36
+Patch32:        0001-apparmor-add-base-infastructure-for-socket-mediation.patch
37
+Patch33:        0002-apparmor-af_unix-mediation.patch
35 38
 # NSX requirements (should be removed)
36 39
 Patch99:        LKCM.patch
37 40
 
... ...
@@ -95,6 +98,8 @@ The Linux package contains the Linux kernel doc files
95 95
 %patch24 -p1
96 96
 %patch26 -p1
97 97
 %patch31 -p1
98
+%patch32 -p1
99
+%patch33 -p1
98 100
 
99 101
 pushd ..
100 102
 %patch99 -p0
... ...
@@ -222,6 +227,8 @@ ln -sf linux-%{uname_r}.cfg /boot/photon.cfg
222 222
 /usr/src/linux-headers-%{uname_r}
223 223
 
224 224
 %changelog
225
+*   Thu Aug 30 2018 Srivatsa S. Bhat <srivatsa@csail.mit.edu> 4.14.54-2
226
+-   Apply out-of-tree patches needed for AppArmor.
225 227
 *   Mon Jul 09 2018 Him Kalyan Bordoloi <bordoloih@vmware.com> 4.14.54-1
226 228
 -   Update to version 4.14.54
227 229
 *   Mon Mar 19 2018 Alexey Makhalov <amakhalov@vmware.com> 4.14.8-2
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:        Kernel
3 3
 Name:           linux
4 4
 Version:        4.14.54
5
-Release:        4%{?kat_build:.%kat_build}%{?dist}
5
+Release:        5%{?kat_build:.%kat_build}%{?dist}
6 6
 License:    	GPLv2
7 7
 URL:        	http://www.kernel.org/
8 8
 Group:        	System Environment/Kernel
... ...
@@ -41,6 +41,9 @@ Patch24:        Allow-some-algo-tests-for-FIPS.patch
41 41
 Patch26:        add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch
42 42
 # Fix CVE-2017-1000252
43 43
 Patch28:        kvm-dont-accept-wrong-gsi-values.patch
44
+# Out-of-tree patches from AppArmor:
45
+Patch29:        0001-apparmor-add-base-infastructure-for-socket-mediation.patch
46
+Patch30:        0002-apparmor-af_unix-mediation.patch
44 47
 
45 48
 %if 0%{?kat_build:1}
46 49
 Patch1000:	%{kat_build}.patch
... ...
@@ -141,6 +144,9 @@ Kernel Device Tree Blob files for Raspberry Pi3
141 141
 %patch24 -p1
142 142
 %patch26 -p1
143 143
 %patch28 -p1
144
+%patch29 -p1
145
+%patch30 -p1
146
+
144 147
 %if 0%{?kat_build:1}
145 148
 %patch1000 -p1
146 149
 %endif
... ...
@@ -360,6 +366,8 @@ ln -sf %{name}-%{uname_r}.cfg /boot/photon.cfg
360 360
 %endif
361 361
 
362 362
 %changelog
363
+*   Thu Aug 30 2018 Srivatsa S. Bhat <srivatsa@csail.mit.edu> 4.14.54-5
364
+-   Apply out-of-tree patches needed for AppArmor.
363 365
 *   Wed Aug 22 2018 Alexey Makhalov <amakhalov@vmware.com> 4.14.54-4
364 366
 -   Fix overflow kernel panic in rsi driver.
365 367
 -   .config: enable BT stack, enable GPIO sysfs.