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 from the latest available version of
AppArmor, i.e., v2.13.

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

Srivatsa S. Bhat authored on 2018/07/20 08:48:20
Showing 6 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,607 @@
0
+From 20f953a08580786932c6b2c214c7dc2e2f99cf75 Mon Sep 17 00:00:00 2001
1
+From: John Johansen <john.johansen@canonical.com>
2
+Date: Mon, 4 Oct 2010 15:03:36 -0700
3
+Subject: [PATCH 1/3] UBUNTU: SAUCE: AppArmor: basic networking rules
4
+
5
+[ This is an out-of-tree patch distributed with the AppArmor source
6
+  code (v2.13) ]
7
+
8
+Base support for network mediation.
9
+
10
+Signed-off-by: John Johansen <john.johansen@canonical.com>
11
+Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu>
12
+---
13
+ security/apparmor/.gitignore       |   1 +
14
+ security/apparmor/Makefile         |  42 +++++++++-
15
+ security/apparmor/apparmorfs.c     |   1 +
16
+ security/apparmor/include/audit.h  |   4 +
17
+ security/apparmor/include/net.h    |  44 ++++++++++
18
+ security/apparmor/include/policy.h |   3 +
19
+ security/apparmor/lsm.c            | 112 +++++++++++++++++++++++++
20
+ security/apparmor/net.c            | 162 +++++++++++++++++++++++++++++++++++++
21
+ security/apparmor/policy.c         |   1 +
22
+ security/apparmor/policy_unpack.c  |  46 +++++++++++
23
+ 10 files changed, 414 insertions(+), 2 deletions(-)
24
+ create mode 100644 security/apparmor/include/net.h
25
+ create mode 100644 security/apparmor/net.c
26
+
27
+diff --git a/security/apparmor/.gitignore b/security/apparmor/.gitignore
28
+index 9cdec70..d5b291e 100644
29
+--- a/security/apparmor/.gitignore
30
+@@ -1,5 +1,6 @@
31
+ #
32
+ # Generated include files
33
+ #
34
++net_names.h
35
+ capability_names.h
36
+ rlim_names.h
37
+diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
38
+index d693df8..5dbb72f 100644
39
+--- a/security/apparmor/Makefile
40
+@@ -4,10 +4,10 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
41
+ 
42
+ apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
43
+               path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
44
+-              resource.o sid.o file.o
45
++              resource.o sid.o file.o net.o
46
+ apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
47
+ 
48
+-clean-files := capability_names.h rlim_names.h
49
++clean-files := capability_names.h rlim_names.h net_names.h
50
+ 
51
+ 
52
+ # Build a lower case string table of capability names
53
+@@ -25,6 +25,38 @@ cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\
54
+ 	    -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/\L\1/p' | \
55
+ 	     tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
56
+ 
57
++# Build a lower case string table of address family names
58
++# Transform lines from
59
++#    define AF_LOCAL	1	/* POSIX name for AF_UNIX	*/
60
++#    #define AF_INET		2	/* Internet IP Protocol 	*/
61
++# to
62
++#    [1] = "local",
63
++#    [2] = "inet",
64
++#
65
++# and build the securityfs entries for the mapping.
66
++# Transforms lines from
67
++#    #define AF_INET		2	/* Internet IP Protocol 	*/
68
++# to
69
++#    #define AA_FS_AF_MASK "local inet"
70
++quiet_cmd_make-af = GEN     $@
71
++cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\
72
++	sed $< >>$@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e \
73
++	 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
74
++	echo "};" >> $@ ;\
75
++	echo -n '\#define AA_FS_AF_MASK "' >> $@ ;\
76
++	sed -r -n 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/\L\1/p'\
77
++	 $< | tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
78
++
79
++# Build a lower case string table of sock type names
80
++# Transform lines from
81
++#    SOCK_STREAM	= 1,
82
++# to
83
++#    [1] = "stream",
84
++quiet_cmd_make-sock = GEN     $@
85
++cmd_make-sock = echo "static const char *sock_type_names[] = {" >> $@ ;\
86
++	sed $^ >>$@ -r -n \
87
++	-e 's/^\tSOCK_([A-Z0-9_]+)[\t]+=[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
88
++	echo "};" >> $@
89
+ 
90
+ # Build a lower case string table of rlimit names.
91
+ # Transforms lines from
92
+@@ -61,6 +93,7 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
93
+ 	    tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
94
+ 
95
+ $(obj)/capability.o : $(obj)/capability_names.h
96
++$(obj)/net.o : $(obj)/net_names.h
97
+ $(obj)/resource.o : $(obj)/rlim_names.h
98
+ $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
99
+ 			    $(src)/Makefile
100
+@@ -68,3 +101,8 @@ $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
101
+ $(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \
102
+ 		      $(src)/Makefile
103
+ 	$(call cmd,make-rlim)
104
++$(obj)/net_names.h : $(srctree)/include/linux/socket.h \
105
++		     $(srctree)/include/linux/net.h \
106
++		     $(src)/Makefile
107
++	$(call cmd,make-af)
108
++	$(call cmd,make-sock)
109
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
110
+index 5923d56..bd558db 100644
111
+--- a/security/apparmor/apparmorfs.c
112
+@@ -807,6 +807,7 @@ static struct aa_fs_entry aa_fs_entry_features[] = {
113
+ 	AA_FS_DIR("policy",			aa_fs_entry_policy),
114
+ 	AA_FS_DIR("domain",			aa_fs_entry_domain),
115
+ 	AA_FS_DIR("file",			aa_fs_entry_file),
116
++	AA_FS_DIR("network",                    aa_fs_entry_network),
117
+ 	AA_FS_FILE_U64("capability",		VFS_CAP_FLAGS_MASK),
118
+ 	AA_FS_DIR("rlimit",			aa_fs_entry_rlimit),
119
+ 	AA_FS_DIR("caps",			aa_fs_entry_caps),
120
+diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
121
+index ba3dfd1..5d3c419 100644
122
+--- a/security/apparmor/include/audit.h
123
+@@ -125,6 +125,10 @@ struct apparmor_audit_data {
124
+ 			u32 denied;
125
+ 			kuid_t ouid;
126
+ 		} fs;
127
++		struct {
128
++			int type, protocol;
129
++			struct sock *sk;
130
++		} net;
131
+ 	};
132
+ };
133
+ 
134
+diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
135
+new file mode 100644
136
+index 0000000..cb8a121
137
+--- /dev/null
138
+@@ -0,0 +1,44 @@
139
++/*
140
++ * AppArmor security module
141
++ *
142
++ * This file contains AppArmor network mediation definitions.
143
++ *
144
++ * Copyright (C) 1998-2008 Novell/SUSE
145
++ * Copyright 2009-2012 Canonical Ltd.
146
++ *
147
++ * This program is free software; you can redistribute it and/or
148
++ * modify it under the terms of the GNU General Public License as
149
++ * published by the Free Software Foundation, version 2 of the
150
++ * License.
151
++ */
152
++
153
++#ifndef __AA_NET_H
154
++#define __AA_NET_H
155
++
156
++#include <net/sock.h>
157
++
158
++#include "apparmorfs.h"
159
++
160
++/* struct aa_net - network confinement data
161
++ * @allowed: basic network families permissions
162
++ * @audit_network: which network permissions to force audit
163
++ * @quiet_network: which network permissions to quiet rejects
164
++ */
165
++struct aa_net {
166
++	u16 allow[AF_MAX];
167
++	u16 audit[AF_MAX];
168
++	u16 quiet[AF_MAX];
169
++};
170
++
171
++extern struct aa_fs_entry aa_fs_entry_network[];
172
++
173
++extern int aa_net_perm(int op, struct aa_profile *profile, u16 family,
174
++		       int type, int protocol, struct sock *sk);
175
++extern int aa_revalidate_sk(int op, struct sock *sk);
176
++
177
++static inline void aa_free_net_rules(struct aa_net *new)
178
++{
179
++	/* NOP */
180
++}
181
++
182
++#endif /* __AA_NET_H */
183
+diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
184
+index 52275f0..4fc4dac 100644
185
+--- a/security/apparmor/include/policy.h
186
+@@ -27,6 +27,7 @@
187
+ #include "capability.h"
188
+ #include "domain.h"
189
+ #include "file.h"
190
++#include "net.h"
191
+ #include "resource.h"
192
+ 
193
+ extern const char *const aa_profile_mode_names[];
194
+@@ -176,6 +177,7 @@ struct aa_replacedby {
195
+  * @policy: general match rules governing policy
196
+  * @file: The set of rules governing basic file access and domain transitions
197
+  * @caps: capabilities for the profile
198
++ * @net: network controls for the profile
199
+  * @rlimits: rlimits for the profile
200
+  *
201
+  * @dents: dentries for the profiles file entries in apparmorfs
202
+@@ -217,6 +219,7 @@ struct aa_profile {
203
+ 	struct aa_policydb policy;
204
+ 	struct aa_file_rules file;
205
+ 	struct aa_caps caps;
206
++	struct aa_net net;
207
+ 	struct aa_rlimit rlimits;
208
+ 
209
+ 	unsigned char *hash;
210
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
211
+index 02cc952..de3b68a 100644
212
+--- a/security/apparmor/lsm.c
213
+@@ -32,6 +32,7 @@
214
+ #include "include/context.h"
215
+ #include "include/file.h"
216
+ #include "include/ipc.h"
217
++#include "include/net.h"
218
+ #include "include/path.h"
219
+ #include "include/policy.h"
220
+ #include "include/procattr.h"
221
+@@ -584,6 +585,104 @@ static int apparmor_task_setrlimit(struct task_struct *task,
222
+ 	return error;
223
+ }
224
+ 
225
++static int apparmor_socket_create(int family, int type, int protocol, int kern)
226
++{
227
++	struct aa_profile *profile;
228
++	int error = 0;
229
++
230
++	if (kern)
231
++		return 0;
232
++
233
++	profile = __aa_current_profile();
234
++	if (!unconfined(profile))
235
++		error = aa_net_perm(OP_CREATE, profile, family, type, protocol,
236
++				    NULL);
237
++	return error;
238
++}
239
++
240
++static int apparmor_socket_bind(struct socket *sock,
241
++				struct sockaddr *address, int addrlen)
242
++{
243
++	struct sock *sk = sock->sk;
244
++
245
++	return aa_revalidate_sk(OP_BIND, sk);
246
++}
247
++
248
++static int apparmor_socket_connect(struct socket *sock,
249
++				   struct sockaddr *address, int addrlen)
250
++{
251
++	struct sock *sk = sock->sk;
252
++
253
++	return aa_revalidate_sk(OP_CONNECT, sk);
254
++}
255
++
256
++static int apparmor_socket_listen(struct socket *sock, int backlog)
257
++{
258
++	struct sock *sk = sock->sk;
259
++
260
++	return aa_revalidate_sk(OP_LISTEN, sk);
261
++}
262
++
263
++static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
264
++{
265
++	struct sock *sk = sock->sk;
266
++
267
++	return aa_revalidate_sk(OP_ACCEPT, sk);
268
++}
269
++
270
++static int apparmor_socket_sendmsg(struct socket *sock,
271
++				   struct msghdr *msg, int size)
272
++{
273
++	struct sock *sk = sock->sk;
274
++
275
++	return aa_revalidate_sk(OP_SENDMSG, sk);
276
++}
277
++
278
++static int apparmor_socket_recvmsg(struct socket *sock,
279
++				   struct msghdr *msg, int size, int flags)
280
++{
281
++	struct sock *sk = sock->sk;
282
++
283
++	return aa_revalidate_sk(OP_RECVMSG, sk);
284
++}
285
++
286
++static int apparmor_socket_getsockname(struct socket *sock)
287
++{
288
++	struct sock *sk = sock->sk;
289
++
290
++	return aa_revalidate_sk(OP_GETSOCKNAME, sk);
291
++}
292
++
293
++static int apparmor_socket_getpeername(struct socket *sock)
294
++{
295
++	struct sock *sk = sock->sk;
296
++
297
++	return aa_revalidate_sk(OP_GETPEERNAME, sk);
298
++}
299
++
300
++static int apparmor_socket_getsockopt(struct socket *sock, int level,
301
++				      int optname)
302
++{
303
++	struct sock *sk = sock->sk;
304
++
305
++	return aa_revalidate_sk(OP_GETSOCKOPT, sk);
306
++}
307
++
308
++static int apparmor_socket_setsockopt(struct socket *sock, int level,
309
++				      int optname)
310
++{
311
++	struct sock *sk = sock->sk;
312
++
313
++	return aa_revalidate_sk(OP_SETSOCKOPT, sk);
314
++}
315
++
316
++static int apparmor_socket_shutdown(struct socket *sock, int how)
317
++{
318
++	struct sock *sk = sock->sk;
319
++
320
++	return aa_revalidate_sk(OP_SOCK_SHUTDOWN, sk);
321
++}
322
++
323
+ static struct security_hook_list apparmor_hooks[] = {
324
+ 	LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
325
+ 	LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
326
+@@ -613,6 +712,19 @@ static struct security_hook_list apparmor_hooks[] = {
327
+ 	LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
328
+ 	LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
329
+ 
330
++	LSM_HOOK_INIT(socket_create, apparmor_socket_create),
331
++	LSM_HOOK_INIT(socket_bind, apparmor_socket_bind),
332
++	LSM_HOOK_INIT(socket_connect, apparmor_socket_connect),
333
++	LSM_HOOK_INIT(socket_listen, apparmor_socket_listen),
334
++	LSM_HOOK_INIT(socket_accept, apparmor_socket_accept),
335
++	LSM_HOOK_INIT(socket_sendmsg, apparmor_socket_sendmsg),
336
++	LSM_HOOK_INIT(socket_recvmsg, apparmor_socket_recvmsg),
337
++	LSM_HOOK_INIT(socket_getsockname, apparmor_socket_getsockname),
338
++	LSM_HOOK_INIT(socket_getpeername, apparmor_socket_getpeername),
339
++	LSM_HOOK_INIT(socket_getsockopt, apparmor_socket_getsockopt),
340
++	LSM_HOOK_INIT(socket_setsockopt, apparmor_socket_setsockopt),
341
++	LSM_HOOK_INIT(socket_shutdown, apparmor_socket_shutdown),
342
++
343
+ 	LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank),
344
+ 	LSM_HOOK_INIT(cred_free, apparmor_cred_free),
345
+ 	LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare),
346
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
347
+new file mode 100644
348
+index 0000000..003dd18
349
+--- /dev/null
350
+@@ -0,0 +1,162 @@
351
++/*
352
++ * AppArmor security module
353
++ *
354
++ * This file contains AppArmor network mediation
355
++ *
356
++ * Copyright (C) 1998-2008 Novell/SUSE
357
++ * Copyright 2009-2012 Canonical Ltd.
358
++ *
359
++ * This program is free software; you can redistribute it and/or
360
++ * modify it under the terms of the GNU General Public License as
361
++ * published by the Free Software Foundation, version 2 of the
362
++ * License.
363
++ */
364
++
365
++#include "include/apparmor.h"
366
++#include "include/audit.h"
367
++#include "include/context.h"
368
++#include "include/net.h"
369
++#include "include/policy.h"
370
++
371
++#include "net_names.h"
372
++
373
++struct aa_fs_entry aa_fs_entry_network[] = {
374
++	AA_FS_FILE_STRING("af_mask", AA_FS_AF_MASK),
375
++	{ }
376
++};
377
++
378
++/* audit callback for net specific fields */
379
++static void audit_cb(struct audit_buffer *ab, void *va)
380
++{
381
++	struct common_audit_data *sa = va;
382
++
383
++	audit_log_format(ab, " family=");
384
++	if (address_family_names[sa->u.net->family]) {
385
++		audit_log_string(ab, address_family_names[sa->u.net->family]);
386
++	} else {
387
++		audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
388
++	}
389
++	audit_log_format(ab, " sock_type=");
390
++	if (sock_type_names[sa->aad->net.type]) {
391
++		audit_log_string(ab, sock_type_names[sa->aad->net.type]);
392
++	} else {
393
++		audit_log_format(ab, "\"unknown(%d)\"", sa->aad->net.type);
394
++	}
395
++	audit_log_format(ab, " protocol=%d", sa->aad->net.protocol);
396
++}
397
++
398
++/**
399
++ * audit_net - audit network access
400
++ * @profile: profile being enforced  (NOT NULL)
401
++ * @op: operation being checked
402
++ * @family: network family
403
++ * @type:   network type
404
++ * @protocol: network protocol
405
++ * @sk: socket auditing is being applied to
406
++ * @error: error code for failure else 0
407
++ *
408
++ * Returns: %0 or sa->error else other errorcode on failure
409
++ */
410
++static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
411
++		     int protocol, struct sock *sk, int error)
412
++{
413
++	int audit_type = AUDIT_APPARMOR_AUTO;
414
++	struct common_audit_data sa;
415
++	struct apparmor_audit_data aad = { };
416
++	struct lsm_network_audit net = { };
417
++	if (sk) {
418
++		sa.type = LSM_AUDIT_DATA_NET;
419
++	} else {
420
++		sa.type = LSM_AUDIT_DATA_NONE;
421
++	}
422
++	/* todo fill in socket addr info */
423
++	sa.aad = &aad;
424
++	sa.u.net = &net;
425
++	sa.aad->op = op,
426
++	sa.u.net->family = family;
427
++	sa.u.net->sk = sk;
428
++	sa.aad->net.type = type;
429
++	sa.aad->net.protocol = protocol;
430
++	sa.aad->error = error;
431
++
432
++	if (likely(!sa.aad->error)) {
433
++		u16 audit_mask = profile->net.audit[sa.u.net->family];
434
++		if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
435
++			   !(1 << sa.aad->net.type & audit_mask)))
436
++			return 0;
437
++		audit_type = AUDIT_APPARMOR_AUDIT;
438
++	} else {
439
++		u16 quiet_mask = profile->net.quiet[sa.u.net->family];
440
++		u16 kill_mask = 0;
441
++		u16 denied = (1 << sa.aad->net.type) & ~quiet_mask;
442
++
443
++		if (denied & kill_mask)
444
++			audit_type = AUDIT_APPARMOR_KILL;
445
++
446
++		if ((denied & quiet_mask) &&
447
++		    AUDIT_MODE(profile) != AUDIT_NOQUIET &&
448
++		    AUDIT_MODE(profile) != AUDIT_ALL)
449
++			return COMPLAIN_MODE(profile) ? 0 : sa.aad->error;
450
++	}
451
++
452
++	return aa_audit(audit_type, profile, GFP_KERNEL, &sa, audit_cb);
453
++}
454
++
455
++/**
456
++ * aa_net_perm - very course network access check
457
++ * @op: operation being checked
458
++ * @profile: profile being enforced  (NOT NULL)
459
++ * @family: network family
460
++ * @type:   network type
461
++ * @protocol: network protocol
462
++ *
463
++ * Returns: %0 else error if permission denied
464
++ */
465
++int aa_net_perm(int op, struct aa_profile *profile, u16 family, int type,
466
++		int protocol, struct sock *sk)
467
++{
468
++	u16 family_mask;
469
++	int error;
470
++
471
++	if ((family < 0) || (family >= AF_MAX))
472
++		return -EINVAL;
473
++
474
++	if ((type < 0) || (type >= SOCK_MAX))
475
++		return -EINVAL;
476
++
477
++	/* unix domain and netlink sockets are handled by ipc */
478
++	if (family == AF_UNIX || family == AF_NETLINK)
479
++		return 0;
480
++
481
++	family_mask = profile->net.allow[family];
482
++
483
++	error = (family_mask & (1 << type)) ? 0 : -EACCES;
484
++
485
++	return audit_net(profile, op, family, type, protocol, sk, error);
486
++}
487
++
488
++/**
489
++ * aa_revalidate_sk - Revalidate access to a sock
490
++ * @op: operation being checked
491
++ * @sk: sock being revalidated  (NOT NULL)
492
++ *
493
++ * Returns: %0 else error if permission denied
494
++ */
495
++int aa_revalidate_sk(int op, struct sock *sk)
496
++{
497
++	struct aa_profile *profile;
498
++	int error = 0;
499
++
500
++	/* aa_revalidate_sk should not be called from interrupt context
501
++	 * don't mediate these calls as they are not task related
502
++	 */
503
++	if (in_interrupt())
504
++		return 0;
505
++
506
++	profile = __aa_current_profile();
507
++	if (!unconfined(profile))
508
++		error = aa_net_perm(op, profile, sk->sk_family, sk->sk_type,
509
++				    sk->sk_protocol, sk);
510
++
511
++	return error;
512
++}
513
+diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
514
+index 179e68d..f1a8541 100644
515
+--- a/security/apparmor/policy.c
516
+@@ -603,6 +603,7 @@ void aa_free_profile(struct aa_profile *profile)
517
+ 
518
+ 	aa_free_file_rules(&profile->file);
519
+ 	aa_free_cap_rules(&profile->caps);
520
++	aa_free_net_rules(&profile->net);
521
+ 	aa_free_rlimit_rules(&profile->rlimits);
522
+ 
523
+ 	kzfree(profile->dirname);
524
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
525
+index 1381206..7dc15ff 100644
526
+--- a/security/apparmor/policy_unpack.c
527
+@@ -193,6 +193,19 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
528
+ 	return 0;
529
+ }
530
+ 
531
++static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
532
++{
533
++	if (unpack_nameX(e, AA_U16, name)) {
534
++		if (!inbounds(e, sizeof(u16)))
535
++			return 0;
536
++		if (data)
537
++			*data = le16_to_cpu(get_unaligned((u16 *) e->pos));
538
++		e->pos += sizeof(u16);
539
++		return 1;
540
++	}
541
++	return 0;
542
++}
543
++
544
+ static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
545
+ {
546
+ 	if (unpack_nameX(e, AA_U32, name)) {
547
+@@ -476,6 +489,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
548
+ {
549
+ 	struct aa_profile *profile = NULL;
550
+ 	const char *name = NULL;
551
++	size_t size = 0;
552
+ 	int i, error = -EPROTO;
553
+ 	kernel_cap_t tmpcap;
554
+ 	u32 tmp;
555
+@@ -576,6 +590,38 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
556
+ 	if (!unpack_rlimits(e, profile))
557
+ 		goto fail;
558
+ 
559
++	size = unpack_array(e, "net_allowed_af");
560
++	if (size) {
561
++
562
++		for (i = 0; i < size; i++) {
563
++			/* discard extraneous rules that this kernel will
564
++			 * never request
565
++			 */
566
++			if (i >= AF_MAX) {
567
++				u16 tmp;
568
++				if (!unpack_u16(e, &tmp, NULL) ||
569
++				    !unpack_u16(e, &tmp, NULL) ||
570
++				    !unpack_u16(e, &tmp, NULL))
571
++					goto fail;
572
++				continue;
573
++			}
574
++			if (!unpack_u16(e, &profile->net.allow[i], NULL))
575
++				goto fail;
576
++			if (!unpack_u16(e, &profile->net.audit[i], NULL))
577
++				goto fail;
578
++			if (!unpack_u16(e, &profile->net.quiet[i], NULL))
579
++				goto fail;
580
++		}
581
++		if (!unpack_nameX(e, AA_ARRAYEND, NULL))
582
++			goto fail;
583
++	}
584
++	/*
585
++	 * allow unix domain and netlink sockets they are handled
586
++	 * by IPC
587
++	 */
588
++	profile->net.allow[AF_UNIX] = 0xffff;
589
++	profile->net.allow[AF_NETLINK] = 0xffff;
590
++
591
+ 	if (unpack_nameX(e, AA_STRUCT, "policydb")) {
592
+ 		/* generic policy dfa - optional and may be NULL */
593
+ 		profile->policy.dfa = unpack_dfa(e);
594
+-- 
595
+2.7.4
596
+
0 597
new file mode 100644
... ...
@@ -0,0 +1,42 @@
0
+From 43d2482f8472a21571feadade4d945d3048aec00 Mon Sep 17 00:00:00 2001
1
+From: John Johansen <john.johansen@canonical.com>
2
+Date: Fri, 29 Jun 2012 17:34:00 -0700
3
+Subject: [PATCH 2/3] apparmor: Fix quieting of audit messages for network
4
+ mediation
5
+
6
+[ This is an out-of-tree patch distributed with the AppArmor source
7
+  code (v2.13) ]
8
+
9
+If a profile specified a quieting of network denials for a given rule by
10
+either the quiet or deny rule qualifiers, the resultant quiet mask for
11
+denied requests was applied incorrectly, resulting in two potential bugs.
12
+1. The misapplied quiet mask would prevent denials from being correctly
13
+   tested against the kill mask/mode. Thus network access requests that
14
+   should have resulted in the application being killed did not.
15
+
16
+2. The actual quieting of the denied network request was not being applied.
17
+   This would result in network rejections always being logged even when
18
+   they had been specifically marked as quieted.
19
+
20
+Signed-off-by: John Johansen <john.johansen@canonical.com>
21
+Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu>
22
+---
23
+ security/apparmor/net.c | 2 +-
24
+ 1 file changed, 1 insertion(+), 1 deletion(-)
25
+
26
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
27
+index 003dd18..6e6e5c9 100644
28
+--- a/security/apparmor/net.c
29
+@@ -88,7 +88,7 @@ static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
30
+ 	} else {
31
+ 		u16 quiet_mask = profile->net.quiet[sa.u.net->family];
32
+ 		u16 kill_mask = 0;
33
+-		u16 denied = (1 << sa.aad->net.type) & ~quiet_mask;
34
++		u16 denied = (1 << sa.aad->net.type);
35
+ 
36
+ 		if (denied & kill_mask)
37
+ 			audit_type = AUDIT_APPARMOR_KILL;
38
+-- 
39
+2.7.4
40
+
0 41
new file mode 100644
... ...
@@ -0,0 +1,966 @@
0
+From 4d628e0f2b5d6346131f117b7e61ca873b6ad99b Mon Sep 17 00:00:00 2001
1
+From: John Johansen <john.johansen@canonical.com>
2
+Date: Wed, 16 May 2012 10:58:05 -0700
3
+Subject: [PATCH 3/3] UBUNTU: SAUCE: apparmor: Add the ability to mediate mount
4
+
5
+[ This is an out-of-tree patch distributed with the AppArmor source
6
+  code (v2.13) ]
7
+
8
+Add the ability for apparmor to do mediation of mount operations. Mount
9
+rules require an updated apparmor_parser (2.8 series) for policy compilation.
10
+
11
+The basic form of the rules are.
12
+
13
+  [audit] [deny] mount [conds]* [device] [ -> [conds] path],
14
+  [audit] [deny] remount [conds]* [path],
15
+  [audit] [deny] umount [conds]* [path],
16
+  [audit] [deny] pivotroot [oldroot=<value>] <path>
17
+
18
+  remount is just a short cut for mount options=remount
19
+
20
+  where [conds] can be
21
+    fstype=<expr>
22
+    options=<expr>
23
+
24
+Example mount commands
25
+  mount,		# allow all mounts, but not umount or pivotroot
26
+
27
+  mount fstype=procfs,  # allow mounting procfs anywhere
28
+
29
+  mount options=(bind, ro) /foo -> /bar,  # readonly bind mount
30
+
31
+  mount /dev/sda -> /mnt,
32
+
33
+  mount /dev/sd** -> /mnt/**,
34
+
35
+  mount fstype=overlayfs options=(rw,upperdir=/tmp/upper/,lowerdir=/) -> /mnt/
36
+
37
+  umount,
38
+
39
+  umount /m*,
40
+
41
+See the apparmor userspace for full documentation
42
+
43
+Signed-off-by: John Johansen <john.johansen@canonical.com>
44
+Acked-by: Kees Cook <kees@ubuntu.com>
45
+Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu>
46
+---
47
+ security/apparmor/Makefile           |   2 +-
48
+ security/apparmor/apparmorfs.c       |  15 +-
49
+ security/apparmor/audit.c            |   4 +
50
+ security/apparmor/domain.c           |   2 +-
51
+ security/apparmor/include/apparmor.h |   3 +-
52
+ security/apparmor/include/audit.h    |  11 +
53
+ security/apparmor/include/domain.h   |   2 +
54
+ security/apparmor/include/mount.h    |  54 +++
55
+ security/apparmor/lsm.c              |  60 ++++
56
+ security/apparmor/mount.c            | 620 +++++++++++++++++++++++++++++++++++
57
+ 10 files changed, 769 insertions(+), 4 deletions(-)
58
+ create mode 100644 security/apparmor/include/mount.h
59
+ create mode 100644 security/apparmor/mount.c
60
+
61
+diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
62
+index 5dbb72f..89b3445 100644
63
+--- a/security/apparmor/Makefile
64
+@@ -4,7 +4,7 @@ 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 sid.o file.o net.o
69
++              resource.o sid.o file.o net.o mount.o
70
+ apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
71
+ 
72
+ clean-files := capability_names.h rlim_names.h net_names.h
73
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
74
+index bd558db..fa61086 100644
75
+--- a/security/apparmor/apparmorfs.c
76
+@@ -800,7 +800,18 @@ static struct aa_fs_entry aa_fs_entry_domain[] = {
77
+ 
78
+ static struct aa_fs_entry aa_fs_entry_policy[] = {
79
+ 	AA_FS_FILE_BOOLEAN("set_load",          1),
80
+-	{}
81
++	{ }
82
++};
83
++
84
++static struct aa_fs_entry aa_fs_entry_mount[] = {
85
++	AA_FS_FILE_STRING("mask", "mount umount"),
86
++	{ }
87
++};
88
++
89
++static struct aa_fs_entry aa_fs_entry_namespaces[] = {
90
++	AA_FS_FILE_BOOLEAN("profile",           1),
91
++	AA_FS_FILE_BOOLEAN("pivot_root",        1),
92
++	{ }
93
+ };
94
+ 
95
+ static struct aa_fs_entry aa_fs_entry_features[] = {
96
+@@ -808,6 +819,8 @@ static struct aa_fs_entry aa_fs_entry_features[] = {
97
+ 	AA_FS_DIR("domain",			aa_fs_entry_domain),
98
+ 	AA_FS_DIR("file",			aa_fs_entry_file),
99
+ 	AA_FS_DIR("network",                    aa_fs_entry_network),
100
++	AA_FS_DIR("mount",                      aa_fs_entry_mount),
101
++	AA_FS_DIR("namespaces",                 aa_fs_entry_namespaces),
102
+ 	AA_FS_FILE_U64("capability",		VFS_CAP_FLAGS_MASK),
103
+ 	AA_FS_DIR("rlimit",			aa_fs_entry_rlimit),
104
+ 	AA_FS_DIR("caps",			aa_fs_entry_caps),
105
+diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
106
+index 3a7f1da..c2a8b8a 100644
107
+--- a/security/apparmor/audit.c
108
+@@ -44,6 +44,10 @@ const char *const op_table[] = {
109
+ 	"file_mmap",
110
+ 	"file_mprotect",
111
+ 
112
++	"pivotroot",
113
++	"mount",
114
++	"umount",
115
++
116
+ 	"create",
117
+ 	"post_create",
118
+ 	"bind",
119
+diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
120
+index a4d90aa..dbd68f2 100644
121
+--- a/security/apparmor/domain.c
122
+@@ -236,7 +236,7 @@ static const char *next_name(int xtype, const char *name)
123
+  *
124
+  * Returns: refcounted profile, or NULL on failure (MAYBE NULL)
125
+  */
126
+-static struct aa_profile *x_table_lookup(struct aa_profile *profile, u32 xindex)
127
++struct aa_profile *x_table_lookup(struct aa_profile *profile, u32 xindex)
128
+ {
129
+ 	struct aa_profile *new_profile = NULL;
130
+ 	struct aa_namespace *ns = profile->ns;
131
+diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
132
+index 5d721e9..b57da7b 100644
133
+--- a/security/apparmor/include/apparmor.h
134
+@@ -30,8 +30,9 @@
135
+ #define AA_CLASS_NET		4
136
+ #define AA_CLASS_RLIMITS	5
137
+ #define AA_CLASS_DOMAIN		6
138
++#define AA_CLASS_MOUNT		7
139
+ 
140
+-#define AA_CLASS_LAST		AA_CLASS_DOMAIN
141
++#define AA_CLASS_LAST		AA_CLASS_MOUNT
142
+ 
143
+ /* Control parameters settable through module/boot flags */
144
+ extern enum audit_mode aa_g_audit;
145
+diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
146
+index 5d3c419..b9f1d57 100644
147
+--- a/security/apparmor/include/audit.h
148
+@@ -72,6 +72,10 @@ enum aa_ops {
149
+ 	OP_FMMAP,
150
+ 	OP_FMPROT,
151
+ 
152
++	OP_PIVOTROOT,
153
++	OP_MOUNT,
154
++	OP_UMOUNT,
155
++
156
+ 	OP_CREATE,
157
+ 	OP_POST_CREATE,
158
+ 	OP_BIND,
159
+@@ -120,6 +124,13 @@ struct apparmor_audit_data {
160
+ 			unsigned long max;
161
+ 		} rlim;
162
+ 		struct {
163
++			const char *src_name;
164
++			const char *type;
165
++			const char *trans;
166
++			const char *data;
167
++			unsigned long flags;
168
++		} mnt;
169
++		struct {
170
+ 			const char *target;
171
+ 			u32 request;
172
+ 			u32 denied;
173
+diff --git a/security/apparmor/include/domain.h b/security/apparmor/include/domain.h
174
+index de04464..a3f70c5 100644
175
+--- a/security/apparmor/include/domain.h
176
+@@ -23,6 +23,8 @@ struct aa_domain {
177
+ 	char **table;
178
+ };
179
+ 
180
++struct aa_profile *x_table_lookup(struct aa_profile *profile, u32 xindex);
181
++
182
+ int apparmor_bprm_set_creds(struct linux_binprm *bprm);
183
+ int apparmor_bprm_secureexec(struct linux_binprm *bprm);
184
+ void apparmor_bprm_committing_creds(struct linux_binprm *bprm);
185
+diff --git a/security/apparmor/include/mount.h b/security/apparmor/include/mount.h
186
+new file mode 100644
187
+index 0000000..a43b1d6
188
+--- /dev/null
189
+@@ -0,0 +1,54 @@
190
++/*
191
++ * AppArmor security module
192
++ *
193
++ * This file contains AppArmor file mediation function definitions.
194
++ *
195
++ * Copyright 2012 Canonical Ltd.
196
++ *
197
++ * This program is free software; you can redistribute it and/or
198
++ * modify it under the terms of the GNU General Public License as
199
++ * published by the Free Software Foundation, version 2 of the
200
++ * License.
201
++ */
202
++
203
++#ifndef __AA_MOUNT_H
204
++#define __AA_MOUNT_H
205
++
206
++#include <linux/fs.h>
207
++#include <linux/path.h>
208
++
209
++#include "domain.h"
210
++#include "policy.h"
211
++
212
++/* mount perms */
213
++#define AA_MAY_PIVOTROOT	0x01
214
++#define AA_MAY_MOUNT		0x02
215
++#define AA_MAY_UMOUNT		0x04
216
++#define AA_AUDIT_DATA		0x40
217
++#define AA_CONT_MATCH		0x40
218
++
219
++#define AA_MS_IGNORE_MASK (MS_KERNMOUNT | MS_NOSEC | MS_ACTIVE | MS_BORN)
220
++
221
++int aa_remount(struct aa_profile *profile, const struct path *path,
222
++	       unsigned long flags, void *data);
223
++
224
++int aa_bind_mount(struct aa_profile *profile, const struct path *path,
225
++		  const char *old_name, unsigned long flags);
226
++
227
++
228
++int aa_mount_change_type(struct aa_profile *profile, const struct path *path,
229
++			 unsigned long flags);
230
++
231
++int aa_move_mount(struct aa_profile *profile, const struct path *path,
232
++		  const char *old_name);
233
++
234
++int aa_new_mount(struct aa_profile *profile, const char *dev_name,
235
++		 const struct path *path, const char *type, unsigned long flags,
236
++		 void *data);
237
++
238
++int aa_umount(struct aa_profile *profile, struct vfsmount *mnt, int flags);
239
++
240
++int aa_pivotroot(struct aa_profile *profile, const struct path *old_path,
241
++		 const struct path *new_path);
242
++
243
++#endif /* __AA_MOUNT_H */
244
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
245
+index de3b68a..40c9fda 100644
246
+--- a/security/apparmor/lsm.c
247
+@@ -36,6 +36,7 @@
248
+ #include "include/path.h"
249
+ #include "include/policy.h"
250
+ #include "include/procattr.h"
251
++#include "include/mount.h"
252
+ 
253
+ /* Flag indicating whether initialization completed */
254
+ int apparmor_initialized __initdata;
255
+@@ -469,6 +470,61 @@ static int apparmor_file_mprotect(struct vm_area_struct *vma,
256
+ 			   !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
257
+ }
258
+ 
259
++static int apparmor_sb_mount(const char *dev_name, const struct path *path,
260
++			     const char *type, unsigned long flags, void *data)
261
++{
262
++	struct aa_profile *profile;
263
++	int error = 0;
264
++
265
++	/* Discard magic */
266
++	if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
267
++		flags &= ~MS_MGC_MSK;
268
++
269
++	flags &= ~AA_MS_IGNORE_MASK;
270
++
271
++	profile = __aa_current_profile();
272
++	if (!unconfined(profile)) {
273
++		if (flags & MS_REMOUNT)
274
++			error = aa_remount(profile, path, flags, data);
275
++		else if (flags & MS_BIND)
276
++			error = aa_bind_mount(profile, path, dev_name, flags);
277
++		else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE |
278
++				  MS_UNBINDABLE))
279
++			error = aa_mount_change_type(profile, path, flags);
280
++		else if (flags & MS_MOVE)
281
++			error = aa_move_mount(profile, path, dev_name);
282
++		else
283
++			error = aa_new_mount(profile, dev_name, path, type,
284
++					     flags, data);
285
++	}
286
++	return error;
287
++}
288
++
289
++static int apparmor_sb_umount(struct vfsmount *mnt, int flags)
290
++{
291
++	struct aa_profile *profile;
292
++	int error = 0;
293
++
294
++	profile = __aa_current_profile();
295
++	if (!unconfined(profile))
296
++		error = aa_umount(profile, mnt, flags);
297
++
298
++	return error;
299
++}
300
++
301
++static int apparmor_sb_pivotroot(const struct path *old_path,
302
++				 const struct path *new_path)
303
++{
304
++	struct aa_profile *profile;
305
++	int error = 0;
306
++
307
++	profile = __aa_current_profile();
308
++	if (!unconfined(profile))
309
++		error = aa_pivotroot(profile, old_path, new_path);
310
++
311
++	return error;
312
++}
313
++
314
+ static int apparmor_getprocattr(struct task_struct *task, char *name,
315
+ 				char **value)
316
+ {
317
+@@ -689,6 +745,10 @@ static struct security_hook_list apparmor_hooks[] = {
318
+ 	LSM_HOOK_INIT(capget, apparmor_capget),
319
+ 	LSM_HOOK_INIT(capable, apparmor_capable),
320
+ 
321
++	LSM_HOOK_INIT(sb_mount, apparmor_sb_mount),
322
++	LSM_HOOK_INIT(sb_umount, apparmor_sb_umount),
323
++	LSM_HOOK_INIT(sb_pivotroot, apparmor_sb_pivotroot),
324
++
325
+ 	LSM_HOOK_INIT(path_link, apparmor_path_link),
326
+ 	LSM_HOOK_INIT(path_unlink, apparmor_path_unlink),
327
+ 	LSM_HOOK_INIT(path_symlink, apparmor_path_symlink),
328
+diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
329
+new file mode 100644
330
+index 0000000..9cf9170
331
+--- /dev/null
332
+@@ -0,0 +1,620 @@
333
++/*
334
++ * AppArmor security module
335
++ *
336
++ * This file contains AppArmor mediation of files
337
++ *
338
++ * Copyright (C) 1998-2008 Novell/SUSE
339
++ * Copyright 2009-2012 Canonical Ltd.
340
++ *
341
++ * This program is free software; you can redistribute it and/or
342
++ * modify it under the terms of the GNU General Public License as
343
++ * published by the Free Software Foundation, version 2 of the
344
++ * License.
345
++ */
346
++
347
++#include <linux/fs.h>
348
++#include <linux/mount.h>
349
++#include <linux/namei.h>
350
++
351
++#include "include/apparmor.h"
352
++#include "include/audit.h"
353
++#include "include/context.h"
354
++#include "include/domain.h"
355
++#include "include/file.h"
356
++#include "include/match.h"
357
++#include "include/mount.h"
358
++#include "include/path.h"
359
++#include "include/policy.h"
360
++
361
++
362
++static void audit_mnt_flags(struct audit_buffer *ab, unsigned long flags)
363
++{
364
++	if (flags & MS_RDONLY)
365
++		audit_log_format(ab, "ro");
366
++	else
367
++		audit_log_format(ab, "rw");
368
++	if (flags & MS_NOSUID)
369
++		audit_log_format(ab, ", nosuid");
370
++	if (flags & MS_NODEV)
371
++		audit_log_format(ab, ", nodev");
372
++	if (flags & MS_NOEXEC)
373
++		audit_log_format(ab, ", noexec");
374
++	if (flags & MS_SYNCHRONOUS)
375
++		audit_log_format(ab, ", sync");
376
++	if (flags & MS_REMOUNT)
377
++		audit_log_format(ab, ", remount");
378
++	if (flags & MS_MANDLOCK)
379
++		audit_log_format(ab, ", mand");
380
++	if (flags & MS_DIRSYNC)
381
++		audit_log_format(ab, ", dirsync");
382
++	if (flags & MS_NOATIME)
383
++		audit_log_format(ab, ", noatime");
384
++	if (flags & MS_NODIRATIME)
385
++		audit_log_format(ab, ", nodiratime");
386
++	if (flags & MS_BIND)
387
++		audit_log_format(ab, flags & MS_REC ? ", rbind" : ", bind");
388
++	if (flags & MS_MOVE)
389
++		audit_log_format(ab, ", move");
390
++	if (flags & MS_SILENT)
391
++		audit_log_format(ab, ", silent");
392
++	if (flags & MS_POSIXACL)
393
++		audit_log_format(ab, ", acl");
394
++	if (flags & MS_UNBINDABLE)
395
++		audit_log_format(ab, flags & MS_REC ? ", runbindable" :
396
++				 ", unbindable");
397
++	if (flags & MS_PRIVATE)
398
++		audit_log_format(ab, flags & MS_REC ? ", rprivate" :
399
++				 ", private");
400
++	if (flags & MS_SLAVE)
401
++		audit_log_format(ab, flags & MS_REC ? ", rslave" :
402
++				 ", slave");
403
++	if (flags & MS_SHARED)
404
++		audit_log_format(ab, flags & MS_REC ? ", rshared" :
405
++				 ", shared");
406
++	if (flags & MS_RELATIME)
407
++		audit_log_format(ab, ", relatime");
408
++	if (flags & MS_I_VERSION)
409
++		audit_log_format(ab, ", iversion");
410
++	if (flags & MS_STRICTATIME)
411
++		audit_log_format(ab, ", strictatime");
412
++	if (flags & MS_NOUSER)
413
++		audit_log_format(ab, ", nouser");
414
++}
415
++
416
++/**
417
++ * audit_cb - call back for mount specific audit fields
418
++ * @ab: audit_buffer  (NOT NULL)
419
++ * @va: audit struct to audit values of  (NOT NULL)
420
++ */
421
++static void audit_cb(struct audit_buffer *ab, void *va)
422
++{
423
++	struct common_audit_data *sa = va;
424
++
425
++	if (sa->aad->mnt.type) {
426
++		audit_log_format(ab, " fstype=");
427
++		audit_log_untrustedstring(ab, sa->aad->mnt.type);
428
++	}
429
++	if (sa->aad->mnt.src_name) {
430
++		audit_log_format(ab, " srcname=");
431
++		audit_log_untrustedstring(ab, sa->aad->mnt.src_name);
432
++	}
433
++	if (sa->aad->mnt.trans) {
434
++		audit_log_format(ab, " trans=");
435
++		audit_log_untrustedstring(ab, sa->aad->mnt.trans);
436
++	}
437
++	if (sa->aad->mnt.flags || sa->aad->op == OP_MOUNT) {
438
++		audit_log_format(ab, " flags=\"");
439
++		audit_mnt_flags(ab, sa->aad->mnt.flags);
440
++		audit_log_format(ab, "\"");
441
++	}
442
++	if (sa->aad->mnt.data) {
443
++		audit_log_format(ab, " options=");
444
++		audit_log_untrustedstring(ab, sa->aad->mnt.data);
445
++	}
446
++}
447
++
448
++/**
449
++ * audit_mount - handle the auditing of mount operations
450
++ * @profile: the profile being enforced  (NOT NULL)
451
++ * @gfp: allocation flags
452
++ * @op: operation being mediated (NOT NULL)
453
++ * @name: name of object being mediated (MAYBE NULL)
454
++ * @src_name: src_name of object being mediated (MAYBE_NULL)
455
++ * @type: type of filesystem (MAYBE_NULL)
456
++ * @trans: name of trans (MAYBE NULL)
457
++ * @flags: filesystem idependent mount flags
458
++ * @data: filesystem mount flags
459
++ * @request: permissions requested
460
++ * @perms: the permissions computed for the request (NOT NULL)
461
++ * @info: extra information message (MAYBE NULL)
462
++ * @error: 0 if operation allowed else failure error code
463
++ *
464
++ * Returns: %0 or error on failure
465
++ */
466
++static int audit_mount(struct aa_profile *profile, gfp_t gfp, int op,
467
++		       const char *name, const char *src_name,
468
++		       const char *type, const char *trans,
469
++		       unsigned long flags, const void *data, u32 request,
470
++		       struct file_perms *perms, const char *info, int error)
471
++{
472
++	int audit_type = AUDIT_APPARMOR_AUTO;
473
++	struct common_audit_data sa = { };
474
++	struct apparmor_audit_data aad = { };
475
++
476
++	if (likely(!error)) {
477
++		u32 mask = perms->audit;
478
++
479
++		if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
480
++			mask = 0xffff;
481
++
482
++		/* mask off perms that are not being force audited */
483
++		request &= mask;
484
++
485
++		if (likely(!request))
486
++			return 0;
487
++		audit_type = AUDIT_APPARMOR_AUDIT;
488
++	} else {
489
++		/* only report permissions that were denied */
490
++		request = request & ~perms->allow;
491
++
492
++		if (request & perms->kill)
493
++			audit_type = AUDIT_APPARMOR_KILL;
494
++
495
++		/* quiet known rejects, assumes quiet and kill do not overlap */
496
++		if ((request & perms->quiet) &&
497
++		    AUDIT_MODE(profile) != AUDIT_NOQUIET &&
498
++		    AUDIT_MODE(profile) != AUDIT_ALL)
499
++			request &= ~perms->quiet;
500
++
501
++		if (!request)
502
++			return COMPLAIN_MODE(profile) ?
503
++				complain_error(error) : error;
504
++	}
505
++
506
++	sa.type = LSM_AUDIT_DATA_NONE;
507
++	sa.aad = &aad;
508
++	sa.aad->op = op;
509
++	sa.aad->name = name;
510
++	sa.aad->mnt.src_name = src_name;
511
++	sa.aad->mnt.type = type;
512
++	sa.aad->mnt.trans = trans;
513
++	sa.aad->mnt.flags = flags;
514
++	if (data && (perms->audit & AA_AUDIT_DATA))
515
++		sa.aad->mnt.data = data;
516
++	sa.aad->info = info;
517
++	sa.aad->error = error;
518
++
519
++	return aa_audit(audit_type, profile, gfp, &sa, audit_cb);
520
++}
521
++
522
++/**
523
++ * match_mnt_flags - Do an ordered match on mount flags
524
++ * @dfa: dfa to match against
525
++ * @state: state to start in
526
++ * @flags: mount flags to match against
527
++ *
528
++ * Mount flags are encoded as an ordered match. This is done instead of
529
++ * checking against a simple bitmask, to allow for logical operations
530
++ * on the flags.
531
++ *
532
++ * Returns: next state after flags match
533
++ */
534
++static unsigned int match_mnt_flags(struct aa_dfa *dfa, unsigned int state,
535
++				    unsigned long flags)
536
++{
537
++	unsigned int i;
538
++
539
++	for (i = 0; i <= 31 ; ++i) {
540
++		if ((1 << i) & flags)
541
++			state = aa_dfa_next(dfa, state, i + 1);
542
++	}
543
++
544
++	return state;
545
++}
546
++
547
++/**
548
++ * compute_mnt_perms - compute mount permission associated with @state
549
++ * @dfa: dfa to match against (NOT NULL)
550
++ * @state: state match finished in
551
++ *
552
++ * Returns: mount permissions
553
++ */
554
++static struct file_perms compute_mnt_perms(struct aa_dfa *dfa,
555
++					   unsigned int state)
556
++{
557
++	struct file_perms perms;
558
++
559
++	perms.kill = 0;
560
++	perms.allow = dfa_user_allow(dfa, state);
561
++	perms.audit = dfa_user_audit(dfa, state);
562
++	perms.quiet = dfa_user_quiet(dfa, state);
563
++	perms.xindex = dfa_user_xindex(dfa, state);
564
++
565
++	return perms;
566
++}
567
++
568
++static const char const *mnt_info_table[] = {
569
++	"match succeeded",
570
++	"failed mntpnt match",
571
++	"failed srcname match",
572
++	"failed type match",
573
++	"failed flags match",
574
++	"failed data match"
575
++};
576
++
577
++/*
578
++ * Returns 0 on success else element that match failed in, this is the
579
++ * index into the mnt_info_table above
580
++ */
581
++static int do_match_mnt(struct aa_dfa *dfa, unsigned int start,
582
++			const char *mntpnt, const char *devname,
583
++			const char *type, unsigned long flags,
584
++			void *data, bool binary, struct file_perms *perms)
585
++{
586
++	unsigned int state;
587
++
588
++	state = aa_dfa_match(dfa, start, mntpnt);
589
++	state = aa_dfa_null_transition(dfa, state);
590
++	if (!state)
591
++		return 1;
592
++
593
++	if (devname)
594
++		state = aa_dfa_match(dfa, state, devname);
595
++	state = aa_dfa_null_transition(dfa, state);
596
++	if (!state)
597
++		return 2;
598
++
599
++	if (type)
600
++		state = aa_dfa_match(dfa, state, type);
601
++	state = aa_dfa_null_transition(dfa, state);
602
++	if (!state)
603
++		return 3;
604
++
605
++	state = match_mnt_flags(dfa, state, flags);
606
++	if (!state)
607
++		return 4;
608
++	*perms = compute_mnt_perms(dfa, state);
609
++	if (perms->allow & AA_MAY_MOUNT)
610
++		return 0;
611
++
612
++	/* only match data if not binary and the DFA flags data is expected */
613
++	if (data && !binary && (perms->allow & AA_CONT_MATCH)) {
614
++		state = aa_dfa_null_transition(dfa, state);
615
++		if (!state)
616
++			return 4;
617
++
618
++		state = aa_dfa_match(dfa, state, data);
619
++		if (!state)
620
++			return 5;
621
++		*perms = compute_mnt_perms(dfa, state);
622
++		if (perms->allow & AA_MAY_MOUNT)
623
++			return 0;
624
++	}
625
++
626
++	/* failed at end of flags match */
627
++	return 4;
628
++}
629
++
630
++/**
631
++ * match_mnt - handle path matching for mount
632
++ * @profile: the confining profile
633
++ * @mntpnt: string for the mntpnt (NOT NULL)
634
++ * @devname: string for the devname/src_name (MAYBE NULL)
635
++ * @type: string for the dev type (MAYBE NULL)
636
++ * @flags: mount flags to match
637
++ * @data: fs mount data (MAYBE NULL)
638
++ * @binary: whether @data is binary
639
++ * @perms: Returns: permission found by the match
640
++ * @info: Returns: infomation string about the match for logging
641
++ *
642
++ * Returns: 0 on success else error
643
++ */
644
++static int match_mnt(struct aa_profile *profile, const char *mntpnt,
645
++		     const char *devname, const char *type,
646
++		     unsigned long flags, void *data, bool binary,
647
++		     struct file_perms *perms, const char **info)
648
++{
649
++	int pos;
650
++
651
++	if (!profile->policy.dfa)
652
++		return -EACCES;
653
++
654
++	pos = do_match_mnt(profile->policy.dfa,
655
++			   profile->policy.start[AA_CLASS_MOUNT],
656
++			   mntpnt, devname, type, flags, data, binary, perms);
657
++	if (pos) {
658
++		*info = mnt_info_table[pos];
659
++		return -EACCES;
660
++	}
661
++
662
++	return 0;
663
++}
664
++
665
++static int path_flags(struct aa_profile *profile, const struct path *path)
666
++{
667
++	return profile->path_flags |
668
++		S_ISDIR(path->dentry->d_inode->i_mode) ? PATH_IS_DIR : 0;
669
++}
670
++
671
++int aa_remount(struct aa_profile *profile, const struct path *path,
672
++	       unsigned long flags, void *data)
673
++{
674
++	struct file_perms perms = { };
675
++	const char *name, *info = NULL;
676
++	char *buffer = NULL;
677
++	int binary, error;
678
++
679
++	binary = path->dentry->d_sb->s_type->fs_flags & FS_BINARY_MOUNTDATA;
680
++
681
++	error = aa_path_name(path, path_flags(profile, path), &buffer, &name,
682
++			     &info);
683
++	if (error)
684
++		goto audit;
685
++
686
++	error = match_mnt(profile, name, NULL, NULL, flags, data, binary,
687
++			  &perms, &info);
688
++
689
++audit:
690
++	error = audit_mount(profile, GFP_KERNEL, OP_MOUNT, name, NULL, NULL,
691
++			    NULL, flags, data, AA_MAY_MOUNT, &perms, info,
692
++			    error);
693
++	kfree(buffer);
694
++
695
++	return error;
696
++}
697
++
698
++int aa_bind_mount(struct aa_profile *profile, const struct path *path,
699
++		  const char *dev_name, unsigned long flags)
700
++{
701
++	struct file_perms perms = { };
702
++	char *buffer = NULL, *old_buffer = NULL;
703
++	const char *name, *old_name = NULL, *info = NULL;
704
++	struct path old_path;
705
++	int error;
706
++
707
++	if (!dev_name || !*dev_name)
708
++		return -EINVAL;
709
++
710
++	flags &= MS_REC | MS_BIND;
711
++
712
++	error = aa_path_name(path, path_flags(profile, path), &buffer, &name,
713
++			     &info);
714
++	if (error)
715
++		goto audit;
716
++
717
++	error = kern_path(dev_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
718
++	if (error)
719
++		goto audit;
720
++
721
++	error = aa_path_name(&old_path, path_flags(profile, &old_path),
722
++			     &old_buffer, &old_name, &info);
723
++	path_put(&old_path);
724
++	if (error)
725
++		goto audit;
726
++
727
++	error = match_mnt(profile, name, old_name, NULL, flags, NULL, 0,
728
++			  &perms, &info);
729
++
730
++audit:
731
++	error = audit_mount(profile, GFP_KERNEL, OP_MOUNT, name, old_name,
732
++			    NULL, NULL, flags, NULL, AA_MAY_MOUNT, &perms,
733
++			    info, error);
734
++	kfree(buffer);
735
++	kfree(old_buffer);
736
++
737
++	return error;
738
++}
739
++
740
++int aa_mount_change_type(struct aa_profile *profile, const struct path *path,
741
++			 unsigned long flags)
742
++{
743
++	struct file_perms perms = { };
744
++	char *buffer = NULL;
745
++	const char *name, *info = NULL;
746
++	int error;
747
++
748
++	/* These are the flags allowed by do_change_type() */
749
++	flags &= (MS_REC | MS_SILENT | MS_SHARED | MS_PRIVATE | MS_SLAVE |
750
++		  MS_UNBINDABLE);
751
++
752
++	error = aa_path_name(path, path_flags(profile, path), &buffer, &name,
753
++			     &info);
754
++	if (error)
755
++		goto audit;
756
++
757
++	error = match_mnt(profile, name, NULL, NULL, flags, NULL, 0, &perms,
758
++			  &info);
759
++
760
++audit:
761
++	error = audit_mount(profile, GFP_KERNEL, OP_MOUNT, name, NULL, NULL,
762
++			    NULL, flags, NULL, AA_MAY_MOUNT, &perms, info,
763
++			    error);
764
++	kfree(buffer);
765
++
766
++	return error;
767
++}
768
++
769
++int aa_move_mount(struct aa_profile *profile, const struct path *path,
770
++		  const char *orig_name)
771
++{
772
++	struct file_perms perms = { };
773
++	char *buffer = NULL, *old_buffer = NULL;
774
++	const char *name, *old_name = NULL, *info = NULL;
775
++	struct path old_path;
776
++	int error;
777
++
778
++	if (!orig_name || !*orig_name)
779
++		return -EINVAL;
780
++
781
++	error = aa_path_name(path, path_flags(profile, path), &buffer, &name,
782
++			     &info);
783
++	if (error)
784
++		goto audit;
785
++
786
++	error = kern_path(orig_name, LOOKUP_FOLLOW, &old_path);
787
++	if (error)
788
++		goto audit;
789
++
790
++	error = aa_path_name(&old_path, path_flags(profile, &old_path),
791
++			     &old_buffer, &old_name, &info);
792
++	path_put(&old_path);
793
++	if (error)
794
++		goto audit;
795
++
796
++	error = match_mnt(profile, name, old_name, NULL, MS_MOVE, NULL, 0,
797
++			  &perms, &info);
798
++
799
++audit:
800
++	error = audit_mount(profile, GFP_KERNEL, OP_MOUNT, name, old_name,
801
++			    NULL, NULL, MS_MOVE, NULL, AA_MAY_MOUNT, &perms,
802
++			    info, error);
803
++	kfree(buffer);
804
++	kfree(old_buffer);
805
++
806
++	return error;
807
++}
808
++
809
++int aa_new_mount(struct aa_profile *profile, const char *orig_dev_name,
810
++		 const struct path *path, const char *type, unsigned long flags,
811
++		 void *data)
812
++{
813
++	struct file_perms perms = { };
814
++	char *buffer = NULL, *dev_buffer = NULL;
815
++	const char *name = NULL, *dev_name = NULL, *info = NULL;
816
++	int binary = 1;
817
++	int error;
818
++
819
++	dev_name = orig_dev_name;
820
++	if (type) {
821
++		int requires_dev;
822
++		struct file_system_type *fstype = get_fs_type(type);
823
++		if (!fstype)
824
++			return -ENODEV;
825
++
826
++		binary = fstype->fs_flags & FS_BINARY_MOUNTDATA;
827
++		requires_dev = fstype->fs_flags & FS_REQUIRES_DEV;
828
++		put_filesystem(fstype);
829
++
830
++		if (requires_dev) {
831
++			struct path dev_path;
832
++
833
++			if (!dev_name || !*dev_name) {
834
++				error = -ENOENT;
835
++				goto out;
836
++			}
837
++
838
++			error = kern_path(dev_name, LOOKUP_FOLLOW, &dev_path);
839
++			if (error)
840
++				goto audit;
841
++
842
++			error = aa_path_name(&dev_path,
843
++					     path_flags(profile, &dev_path),
844
++					     &dev_buffer, &dev_name, &info);
845
++			path_put(&dev_path);
846
++			if (error)
847
++				goto audit;
848
++		}
849
++	}
850
++
851
++	error = aa_path_name(path, path_flags(profile, path), &buffer, &name,
852
++			     &info);
853
++	if (error)
854
++		goto audit;
855
++
856
++	error = match_mnt(profile, name, dev_name, type, flags, data, binary,
857
++			  &perms, &info);
858
++
859
++audit:
860
++	error = audit_mount(profile, GFP_KERNEL, OP_MOUNT, name,  dev_name,
861
++			    type, NULL, flags, data, AA_MAY_MOUNT, &perms, info,
862
++			    error);
863
++	kfree(buffer);
864
++	kfree(dev_buffer);
865
++
866
++out:
867
++	return error;
868
++
869
++}
870
++
871
++int aa_umount(struct aa_profile *profile, struct vfsmount *mnt, int flags)
872
++{
873
++	struct file_perms perms = { };
874
++	char *buffer = NULL;
875
++	const char *name, *info = NULL;
876
++	int error;
877
++
878
++	struct path path = { mnt, mnt->mnt_root };
879
++	error = aa_path_name(&path, path_flags(profile, &path), &buffer, &name,
880
++			     &info);
881
++	if (error)
882
++		goto audit;
883
++
884
++	if (!error && profile->policy.dfa) {
885
++		unsigned int state;
886
++		state = aa_dfa_match(profile->policy.dfa,
887
++				     profile->policy.start[AA_CLASS_MOUNT],
888
++				     name);
889
++		perms = compute_mnt_perms(profile->policy.dfa, state);
890
++	}
891
++
892
++	if (AA_MAY_UMOUNT & ~perms.allow)
893
++		error = -EACCES;
894
++
895
++audit:
896
++	error = audit_mount(profile, GFP_KERNEL, OP_UMOUNT, name, NULL, NULL,
897
++			    NULL, 0, NULL, AA_MAY_UMOUNT, &perms, info, error);
898
++	kfree(buffer);
899
++
900
++	return error;
901
++}
902
++
903
++int aa_pivotroot(struct aa_profile *profile, const struct path *old_path,
904
++		 const struct path *new_path)
905
++{
906
++	struct file_perms perms = { };
907
++	struct aa_profile *target = NULL;
908
++	char *old_buffer = NULL, *new_buffer = NULL;
909
++	const char *old_name, *new_name = NULL, *info = NULL;
910
++	int error;
911
++
912
++	error = aa_path_name(old_path, path_flags(profile, old_path),
913
++			     &old_buffer, &old_name, &info);
914
++	if (error)
915
++		goto audit;
916
++
917
++	error = aa_path_name(new_path, path_flags(profile, new_path),
918
++			     &new_buffer, &new_name, &info);
919
++	if (error)
920
++		goto audit;
921
++
922
++	if (profile->policy.dfa) {
923
++		unsigned int state;
924
++		state = aa_dfa_match(profile->policy.dfa,
925
++				     profile->policy.start[AA_CLASS_MOUNT],
926
++				     new_name);
927
++		state = aa_dfa_null_transition(profile->policy.dfa, state);
928
++		state = aa_dfa_match(profile->policy.dfa, state, old_name);
929
++		perms = compute_mnt_perms(profile->policy.dfa, state);
930
++	}
931
++
932
++	if (AA_MAY_PIVOTROOT & perms.allow) {
933
++		if ((perms.xindex & AA_X_TYPE_MASK) == AA_X_TABLE) {
934
++			target = x_table_lookup(profile, perms.xindex);
935
++			if (!target)
936
++				error = -ENOENT;
937
++			else
938
++				error = aa_replace_current_profile(target);
939
++		}
940
++	} else
941
++		error = -EACCES;
942
++
943
++audit:
944
++	error = audit_mount(profile, GFP_KERNEL, OP_PIVOTROOT, new_name,
945
++			    old_name, NULL, target ? target->base.name : NULL,
946
++			    0, NULL,  AA_MAY_PIVOTROOT, &perms, info, error);
947
++	aa_put_profile(target);
948
++	kfree(old_buffer);
949
++	kfree(new_buffer);
950
++
951
++	return error;
952
++}
953
+-- 
954
+2.7.4
955
+
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:        Kernel
3 3
 Name:           linux-aws
4 4
 Version:        4.9.111
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
... ...
@@ -85,6 +85,12 @@ Patch62: 0151-ipv6-prevent-speculative-execution.patch
85 85
 Patch64: 0153-net-mpls-prevent-speculative-execution.patch
86 86
 Patch65: 0154-udf-prevent-speculative-execution.patch
87 87
 Patch66: 0155-userns-prevent-speculative-execution.patch
88
+
89
+# Out-of-tree patches from AppArmor:
90
+Patch71: 0001-UBUNTU-SAUCE-AppArmor-basic-networking-rules.patch
91
+Patch72: 0002-apparmor-Fix-quieting-of-audit-messages-for-network-.patch
92
+Patch73: 0003-UBUNTU-SAUCE-apparmor-Add-the-ability-to-mediate-mou.patch
93
+
88 94
 # Amazon AWS
89 95
 Patch101: 0002-lib-cpumask-Make-CPUMASK_OFFSTACK-usable-without-deb.patch
90 96
 Patch102: 0009-bump-the-default-TTL-to-255.patch
... ...
@@ -263,6 +269,10 @@ This package contains the 'perf' performance analysis tools for Linux kernel.
263 263
 %patch65 -p1
264 264
 %patch66 -p1
265 265
 
266
+%patch71 -p1
267
+%patch72 -p1
268
+%patch73 -p1
269
+
266 270
 %patch101 -p1
267 271
 %patch102 -p1
268 272
 %patch103 -p1
... ...
@@ -467,6 +477,8 @@ ln -sf %{name}-%{uname_r}.cfg /boot/photon.cfg
467 467
 /usr/share/doc/*
468 468
 
469 469
 %changelog
470
+*   Thu Jul 19 2018 Srivatsa S. Bhat <srivatsa@csail.mit.edu> 4.9.111-5
471
+-   Apply out-of-tree patches needed for AppArmor.
470 472
 *   Thu Jul 17 2018 Srinidhi Rao <srinidhir@vmware.com> 4.9.111-4
471 473
 -   Fix CVE-2018-10322
472 474
 *   Thu Jul 12 2018 Srinidhi Rao <srinidhir@vmware.com> 4.9.111-3
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:        Kernel
3 3
 Name:           linux-secure
4 4
 Version:        4.9.111
5
-Release:        3%{?kat_build:.%kat_build}%{?dist}
5
+Release:        4%{?kat_build:.%kat_build}%{?dist}
6 6
 License:        GPLv2
7 7
 URL:            http://www.kernel.org/
8 8
 Group:          System Environment/Kernel
... ...
@@ -92,6 +92,10 @@ Patch64: 0153-net-mpls-prevent-speculative-execution.patch
92 92
 Patch65: 0154-udf-prevent-speculative-execution.patch
93 93
 Patch66: 0155-userns-prevent-speculative-execution.patch
94 94
 
95
+# Out-of-tree patches from AppArmor:
96
+Patch71: 0001-UBUNTU-SAUCE-AppArmor-basic-networking-rules.patch
97
+Patch72: 0002-apparmor-Fix-quieting-of-audit-messages-for-network-.patch
98
+Patch73: 0003-UBUNTU-SAUCE-apparmor-Add-the-ability-to-mediate-mou.patch
95 99
 
96 100
 # NSX requirements (should be removed)
97 101
 Patch99:        LKCM.patch
... ...
@@ -232,6 +236,10 @@ EOF
232 232
 %patch65 -p1
233 233
 %patch66 -p1
234 234
 
235
+%patch71 -p1
236
+%patch72 -p1
237
+%patch73 -p1
238
+
235 239
 # secure
236 240
 %patch13 -p1
237 241
 %patch14 -p1
... ...
@@ -362,6 +370,8 @@ ln -sf linux-%{uname_r}.cfg /boot/photon.cfg
362 362
 /usr/src/linux-headers-%{uname_r}
363 363
 
364 364
 %changelog
365
+*   Thu Jul 19 2018 Srivatsa S. Bhat <srivatsa@csail.mit.edu> 4.9.111-4
366
+-   Apply out-of-tree patches needed for AppArmor.
365 367
 *   Thu Jul 17 2018 Srinidhi Rao <srinidhir@vmware.com> 4.9.111-3
366 368
 -   Fix CVE-2018-10322
367 369
 *   Thu Jul 12 2018 Srinidhi Rao <srinidhir@vmware.com> 4.9.111-2
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:        Kernel
3 3
 Name:           linux
4 4
 Version:        4.9.111
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
... ...
@@ -91,6 +91,10 @@ Patch64: 0153-net-mpls-prevent-speculative-execution.patch
91 91
 Patch65: 0154-udf-prevent-speculative-execution.patch
92 92
 Patch66: 0155-userns-prevent-speculative-execution.patch
93 93
 
94
+# Out-of-tree patches from AppArmor:
95
+Patch71: 0001-UBUNTU-SAUCE-AppArmor-basic-networking-rules.patch
96
+Patch72: 0002-apparmor-Fix-quieting-of-audit-messages-for-network-.patch
97
+Patch73: 0003-UBUNTU-SAUCE-apparmor-Add-the-ability-to-mediate-mou.patch
94 98
 
95 99
 %if 0%{?kat_build:1}
96 100
 Patch1000:	%{kat_build}.patch
... ...
@@ -223,6 +227,9 @@ This package contains the 'perf' performance analysis tools for Linux kernel.
223 223
 %patch65 -p1
224 224
 %patch66 -p1
225 225
 
226
+%patch71 -p1
227
+%patch72 -p1
228
+%patch73 -p1
226 229
 
227 230
 %if 0%{?kat_build:1}
228 231
 %patch1000 -p1
... ...
@@ -390,6 +397,8 @@ ln -sf %{name}-%{uname_r}.cfg /boot/photon.cfg
390 390
 /usr/share/doc/*
391 391
 
392 392
 %changelog
393
+*   Thu Jul 19 2018 Srivatsa S. Bhat <srivatsa@csail.mit.edu> 4.9.111-5
394
+-   Apply out-of-tree patches needed for AppArmor.
393 395
 *   Thu Jul 17 2018 Srinidhi Rao <srinidhir@vmware.com> 4.9.111-4
394 396
 -   Fix CVE-2018-10322
395 397
 *   Thu Jul 12 2018 Srinidhi Rao <srinidhir@vmware.com> 4.9.111-3