Merge ~vicamo/avila/+git/kernel-3.10:bug-1641549/support-lxd into ~phablet-team/avila/+git/kernel-3.10:xenial

Proposed by You-Sheng Yang
Status: Merged
Approved by: Alfonso Sanchez-Beato
Approved revision: 5332b1cfd1b0493c7d697b9ac7a8edbb5d5cf2bf
Merged at revision: 5332b1cfd1b0493c7d697b9ac7a8edbb5d5cf2bf
Proposed branch: ~vicamo/avila/+git/kernel-3.10:bug-1641549/support-lxd
Merge into: ~phablet-team/avila/+git/kernel-3.10:xenial
Diff against target: 353 lines (+90/-39)
5 files modified
include/linux/audit.h (+1/-1)
kernel/audit.c (+68/-25)
kernel/audit.h (+9/-4)
kernel/auditfilter.c (+11/-8)
security/commoncap.c (+1/-1)
Reviewer Review Type Date Requested Status
Alfonso Sanchez-Beato Approve
Review via email: mp+310849@code.launchpad.net
To post a comment you must log in.
Revision history for this message
You-Sheng Yang (vicamo) wrote :

[push 5332b1c] cherry picked two more changes from upstream to resolve logd kernel audit netlink connection issue as described in https://bugs.launchpad.net/ubuntu/+source/lxc-android-config/+bug/1641549/comments/9

Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/include/linux/audit.h b/include/linux/audit.h
2index 4fb28b2..7082dbf 100644
3--- a/include/linux/audit.h
4+++ b/include/linux/audit.h
5@@ -462,7 +462,7 @@ extern int audit_update_lsm_rules(void);
6 /* Private API (for audit.c only) */
7 extern int audit_filter_user(int type);
8 extern int audit_filter_type(int type);
9-extern int audit_receive_filter(int type, int pid, int seq,
10+extern int audit_receive_filter(int type, __u32 portid, int seq,
11 void *data, size_t datasz);
12 extern int audit_enabled;
13 #else /* CONFIG_AUDIT */
14diff --git a/kernel/audit.c b/kernel/audit.c
15index 6c874e5..b990398 100644
16--- a/kernel/audit.c
17+++ b/kernel/audit.c
18@@ -64,6 +64,7 @@
19 #include <linux/freezer.h>
20 #include <linux/tty.h>
21 #include <linux/pid_namespace.h>
22+#include <net/netns/generic.h>
23
24 #include "audit.h"
25
26@@ -94,7 +95,7 @@ static int audit_failure = AUDIT_FAIL_PRINTK;
27 * the portid to use to send netlink messages to that process.
28 */
29 int audit_pid;
30-static int audit_nlk_portid;
31+static __u32 audit_nlk_portid;
32
33 /* If audit_rate_limit is non-zero, limit the rate of sending audit records
34 * to that number per second. This prevents DoS attacks, but results in
35@@ -123,6 +124,7 @@ static atomic_t audit_lost = ATOMIC_INIT(0);
36
37 /* The netlink socket. */
38 static struct sock *audit_sock;
39+int audit_net_id;
40
41 /* Hash for inode-based rules */
42 struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
43@@ -166,15 +168,16 @@ struct audit_buffer {
44 };
45
46 struct audit_reply {
47- int pid;
48+ __u32 portid;
49+ pid_t pid;
50 struct sk_buff *skb;
51 };
52
53-static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
54+static void audit_set_portid(struct audit_buffer *ab, __u32 portid)
55 {
56 if (ab) {
57 struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
58- nlh->nlmsg_pid = pid;
59+ nlh->nlmsg_pid = portid;
60 }
61 }
62
63@@ -407,6 +410,7 @@ static void kauditd_send_skb(struct sk_buff *skb)
64 printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid);
65 audit_log_lost("auditd disappeared\n");
66 audit_pid = 0;
67+ audit_sock = NULL;
68 /* we might get lucky and get this in the next auditd */
69 audit_hold_skb(skb);
70 } else
71@@ -488,22 +492,23 @@ static int kauditd_thread(void *dummy)
72 int audit_send_list(void *_dest)
73 {
74 struct audit_netlink_list *dest = _dest;
75- int pid = dest->pid;
76 struct sk_buff *skb;
77+ struct net *net = get_net_ns_by_pid(dest->pid);
78+ struct audit_net *aunet = net_generic(net, audit_net_id);
79
80 /* wait for parent to finish and send an ACK */
81 mutex_lock(&audit_cmd_mutex);
82 mutex_unlock(&audit_cmd_mutex);
83
84 while ((skb = __skb_dequeue(&dest->q)) != NULL)
85- netlink_unicast(audit_sock, skb, pid, 0);
86+ netlink_unicast(aunet->nlsk, skb, dest->portid, 0);
87
88 kfree(dest);
89
90 return 0;
91 }
92
93-struct sk_buff *audit_make_reply(int pid, int seq, int type, int done,
94+struct sk_buff *audit_make_reply(__u32 portid, int seq, int type, int done,
95 int multi, const void *payload, int size)
96 {
97 struct sk_buff *skb;
98@@ -516,7 +521,7 @@ struct sk_buff *audit_make_reply(int pid, int seq, int type, int done,
99 if (!skb)
100 return NULL;
101
102- nlh = nlmsg_put(skb, pid, seq, t, size, flags);
103+ nlh = nlmsg_put(skb, portid, seq, t, size, flags);
104 if (!nlh)
105 goto out_kfree_skb;
106 data = nlmsg_data(nlh);
107@@ -531,19 +536,21 @@ out_kfree_skb:
108 static int audit_send_reply_thread(void *arg)
109 {
110 struct audit_reply *reply = (struct audit_reply *)arg;
111+ struct net *net = get_net_ns_by_pid(reply->pid);
112+ struct audit_net *aunet = net_generic(net, audit_net_id);
113
114 mutex_lock(&audit_cmd_mutex);
115 mutex_unlock(&audit_cmd_mutex);
116
117 /* Ignore failure. It'll only happen if the sender goes away,
118 because our timeout is set to infinite. */
119- netlink_unicast(audit_sock, reply->skb, reply->pid, 0);
120+ netlink_unicast(aunet->nlsk , reply->skb, reply->portid, 0);
121 kfree(reply);
122 return 0;
123 }
124 /**
125 * audit_send_reply - send an audit reply message via netlink
126- * @pid: process id to send reply to
127+ * @portid: netlink port to which to send reply
128 * @seq: sequence number
129 * @type: audit message type
130 * @done: done (last) flag
131@@ -551,11 +558,11 @@ static int audit_send_reply_thread(void *arg)
132 * @payload: payload data
133 * @size: payload size
134 *
135- * Allocates an skb, builds the netlink message, and sends it to the pid.
136+ * Allocates an skb, builds the netlink message, and sends it to the port id.
137 * No failure notifications.
138 */
139-static void audit_send_reply(int pid, int seq, int type, int done, int multi,
140- const void *payload, int size)
141+static void audit_send_reply(__u32 portid, int seq, int type, int done,
142+ int multi, const void *payload, int size)
143 {
144 struct sk_buff *skb;
145 struct task_struct *tsk;
146@@ -565,11 +572,12 @@ static void audit_send_reply(int pid, int seq, int type, int done, int multi,
147 if (!reply)
148 return;
149
150- skb = audit_make_reply(pid, seq, type, done, multi, payload, size);
151+ skb = audit_make_reply(portid, seq, type, done, multi, payload, size);
152 if (!skb)
153 goto out;
154
155- reply->pid = pid;
156+ reply->portid = portid;
157+ reply->pid = task_pid_vnr(current);
158 reply->skb = skb;
159
160 tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply");
161@@ -707,6 +715,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
162 audit_log_config_change("audit_pid", new_pid, audit_pid, 1);
163 audit_pid = new_pid;
164 audit_nlk_portid = NETLINK_CB(skb).portid;
165+ audit_sock = NETLINK_CB(skb).sk;
166 }
167 if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) {
168 err = audit_set_rate_limit(status_get->rate_limit);
169@@ -744,7 +753,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
170 size--;
171 audit_log_n_untrustedstring(ab, data, size);
172 }
173- audit_set_pid(ab, NETLINK_CB(skb).portid);
174+ audit_set_portid(ab, NETLINK_CB(skb).portid);
175 audit_log_end(ab);
176 }
177 break;
178@@ -903,24 +912,58 @@ static void audit_receive(struct sk_buff *skb)
179 mutex_unlock(&audit_cmd_mutex);
180 }
181
182-/* Initialize audit support at boot time. */
183-static int __init audit_init(void)
184+static int __net_init audit_net_init(struct net *net)
185 {
186- int i;
187 struct netlink_kernel_cfg cfg = {
188 .input = audit_receive,
189 };
190
191+ struct audit_net *aunet = net_generic(net, audit_net_id);
192+
193+ pr_info("audit: initializing netlink socket in namespace\n");
194+
195+ aunet->nlsk = netlink_kernel_create(net, NETLINK_AUDIT, &cfg);
196+ if (aunet->nlsk == NULL)
197+ return -ENOMEM;
198+ if (!aunet->nlsk)
199+ audit_panic("cannot initialize netlink socket in namespace");
200+ else
201+ aunet->nlsk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
202+ return 0;
203+}
204+
205+static void __net_exit audit_net_exit(struct net *net)
206+{
207+ struct audit_net *aunet = net_generic(net, audit_net_id);
208+ struct sock *sock = aunet->nlsk;
209+ if (sock == audit_sock) {
210+ audit_pid = 0;
211+ audit_sock = NULL;
212+ }
213+
214+ rcu_assign_pointer(aunet->nlsk, NULL);
215+ synchronize_net();
216+ netlink_kernel_release(sock);
217+}
218+
219+static struct pernet_operations __net_initdata audit_net_ops = {
220+ .init = audit_net_init,
221+ .exit = audit_net_exit,
222+ .id = &audit_net_id,
223+ .size = sizeof(struct audit_net),
224+};
225+
226+/* Initialize audit support at boot time. */
227+static int __init audit_init(void)
228+{
229+ int i;
230+
231 if (audit_initialized == AUDIT_DISABLED)
232 return 0;
233
234- printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
235+ pr_info("audit: initializing netlink subsys (%s)\n",
236 audit_default ? "enabled" : "disabled");
237- audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, &cfg);
238- if (!audit_sock)
239- audit_panic("cannot initialize netlink socket");
240- else
241- audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
242+ register_pernet_subsys(&audit_net_ops);
243
244 skb_queue_head_init(&audit_skb_queue);
245 skb_queue_head_init(&audit_skb_hold_queue);
246diff --git a/kernel/audit.h b/kernel/audit.h
247index 123c9b7..efb4833 100644
248--- a/kernel/audit.h
249+++ b/kernel/audit.h
250@@ -237,18 +237,23 @@ extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right);
251 extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right);
252 extern int parent_len(const char *path);
253 extern int audit_compare_dname_path(const char *dname, const char *path, int plen);
254-extern struct sk_buff * audit_make_reply(int pid, int seq, int type,
255- int done, int multi,
256- const void *payload, int size);
257+extern struct sk_buff *audit_make_reply(__u32 portid, int seq, int type,
258+ int done, int multi,
259+ const void *payload, int size);
260 extern void audit_panic(const char *message);
261
262 struct audit_netlink_list {
263- int pid;
264+ __u32 portid;
265+ pid_t pid;
266 struct sk_buff_head q;
267 };
268
269 int audit_send_list(void *);
270
271+struct audit_net {
272+ struct sock *nlsk;
273+};
274+
275 extern int selinux_audit_rule_update(void);
276
277 extern struct mutex audit_filter_mutex;
278diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
279index 0ee9eff..6857c8b 100644
280--- a/kernel/auditfilter.c
281+++ b/kernel/auditfilter.c
282@@ -965,7 +965,7 @@ out:
283 }
284
285 /* List rules using struct audit_rule_data. */
286-static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
287+static void audit_list_rules(__u32 portid, int seq, struct sk_buff_head *q)
288 {
289 struct sk_buff *skb;
290 struct audit_krule *r;
291@@ -980,14 +980,15 @@ static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
292 data = audit_krule_to_data(r);
293 if (unlikely(!data))
294 break;
295- skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1,
296- data, sizeof(*data) + data->buflen);
297+ skb = audit_make_reply(portid, seq, AUDIT_LIST_RULES,
298+ 0, 1, data,
299+ sizeof(*data) + data->buflen);
300 if (skb)
301 skb_queue_tail(q, skb);
302 kfree(data);
303 }
304 }
305- skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0);
306+ skb = audit_make_reply(portid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0);
307 if (skb)
308 skb_queue_tail(q, skb);
309 }
310@@ -1017,12 +1018,13 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re
311 /**
312 * audit_receive_filter - apply all rules to the specified message type
313 * @type: audit message type
314- * @pid: target pid for netlink audit messages
315+ * @portid: target port id for netlink audit messages
316 * @seq: netlink audit message sequence (serial) number
317 * @data: payload data
318 * @datasz: size of payload data
319 */
320-int audit_receive_filter(int type, int pid, int seq, void *data, size_t datasz)
321+int audit_receive_filter(int type, __u32 portid, int seq, void *data,
322+ size_t datasz)
323 {
324 struct task_struct *tsk;
325 struct audit_netlink_list *dest;
326@@ -1040,11 +1042,12 @@ int audit_receive_filter(int type, int pid, int seq, void *data, size_t datasz)
327 dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
328 if (!dest)
329 return -ENOMEM;
330- dest->pid = pid;
331+ dest->portid = portid;
332+ dest->pid = task_pid_vnr(current);
333 skb_queue_head_init(&dest->q);
334
335 mutex_lock(&audit_filter_mutex);
336- audit_list_rules(pid, seq, &dest->q);
337+ audit_list_rules(portid, seq, &dest->q);
338 mutex_unlock(&audit_filter_mutex);
339
340 tsk = kthread_run(audit_send_list, dest, "audit_send_list");
341diff --git a/security/commoncap.c b/security/commoncap.c
342index 0405522..0178c12 100644
343--- a/security/commoncap.c
344+++ b/security/commoncap.c
345@@ -838,7 +838,7 @@ int cap_task_setnice(struct task_struct *p, int nice)
346 */
347 static long cap_prctl_drop(struct cred *new, unsigned long cap)
348 {
349- if (!capable(CAP_SETPCAP))
350+ if (!ns_capable(current_user_ns(), CAP_SETPCAP))
351 return -EPERM;
352 if (!cap_valid(cap))
353 return -EINVAL;

Subscribers

People subscribed via source and target branches