summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-qoriq-3.12/ipc-CVE-2015-7613.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-qoriq-3.12/ipc-CVE-2015-7613.patch')
-rw-r--r--recipes-kernel/linux/linux-qoriq-3.12/ipc-CVE-2015-7613.patch122
1 files changed, 122 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-qoriq-3.12/ipc-CVE-2015-7613.patch b/recipes-kernel/linux/linux-qoriq-3.12/ipc-CVE-2015-7613.patch
new file mode 100644
index 0000000..4f071cf
--- /dev/null
+++ b/recipes-kernel/linux/linux-qoriq-3.12/ipc-CVE-2015-7613.patch
@@ -0,0 +1,122 @@
1From 89c7ab1494f614bf8323490c79d4a562e90db61b Mon Sep 17 00:00:00 2001
2From: Linus Torvalds <torvalds@linux-foundation.org>
3Date: Wed, 30 Sep 2015 12:48:40 -0400
4Subject: Initialize msg/shm IPC objects before doing ipc_addid()
5
6commit b9a532277938798b53178d5a66af6e2915cb27cf upstream.
7
8As reported by Dmitry Vyukov, we really shouldn't do ipc_addid() before
9having initialized the IPC object state. Yes, we initialize the IPC
10object in a locked state, but with all the lockless RCU lookup work,
11that IPC object lock no longer means that the state cannot be seen.
12
13We already did this for the IPC semaphore code (see commit e8577d1f0329:
14"ipc/sem.c: fully initialize sem_array before making it visible") but we
15clearly forgot about msg and shm.
16
17Fixes CVE-2015-7613.
18Upstream-Status: Backport
19
20Reported-by: Dmitry Vyukov <dvyukov@google.com>
21Cc: Manfred Spraul <manfred@colorfullife.com>
22Cc: Davidlohr Bueso <dbueso@suse.de>
23Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
24Signed-off-by: Jiri Slaby <jslaby@suse.cz>
25Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
26---
27 ipc/msg.c | 14 +++++++-------
28 ipc/shm.c | 12 ++++++------
29 ipc/util.c | 8 ++++----
30 3 files changed, 17 insertions(+), 17 deletions(-)
31
32diff --git a/ipc/msg.c b/ipc/msg.c
33index 52770bf..32aaaab 100644
34--- a/ipc/msg.c
35+++ b/ipc/msg.c
36@@ -202,13 +202,6 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params)
37 return retval;
38 }
39
40- /* ipc_addid() locks msq upon success. */
41- id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni);
42- if (id < 0) {
43- ipc_rcu_putref(msq, msg_rcu_free);
44- return id;
45- }
46-
47 msq->q_stime = msq->q_rtime = 0;
48 msq->q_ctime = get_seconds();
49 msq->q_cbytes = msq->q_qnum = 0;
50@@ -218,6 +211,13 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params)
51 INIT_LIST_HEAD(&msq->q_receivers);
52 INIT_LIST_HEAD(&msq->q_senders);
53
54+ /* ipc_addid() locks msq upon success. */
55+ id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni);
56+ if (id < 0) {
57+ ipc_rcu_putref(msq, msg_rcu_free);
58+ return id;
59+ }
60+
61 ipc_unlock_object(&msq->q_perm);
62 rcu_read_unlock();
63
64diff --git a/ipc/shm.c b/ipc/shm.c
65index 623bc38..02f7125 100644
66--- a/ipc/shm.c
67+++ b/ipc/shm.c
68@@ -545,12 +545,6 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
69 if (IS_ERR(file))
70 goto no_file;
71
72- id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);
73- if (id < 0) {
74- error = id;
75- goto no_id;
76- }
77-
78 shp->shm_cprid = task_tgid_vnr(current);
79 shp->shm_lprid = 0;
80 shp->shm_atim = shp->shm_dtim = 0;
81@@ -560,6 +554,12 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
82 shp->shm_file = file;
83 shp->shm_creator = current;
84
85+ id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);
86+ if (id < 0) {
87+ error = id;
88+ goto no_id;
89+ }
90+
91 /*
92 * shmid gets reported as "inode#" in /proc/pid/maps.
93 * proc-ps tools use this. Changing this will break them.
94diff --git a/ipc/util.c b/ipc/util.c
95index 7684f41..7353425 100644
96--- a/ipc/util.c
97+++ b/ipc/util.c
98@@ -292,6 +292,10 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
99 rcu_read_lock();
100 spin_lock(&new->lock);
101
102+ current_euid_egid(&euid, &egid);
103+ new->cuid = new->uid = euid;
104+ new->gid = new->cgid = egid;
105+
106 id = idr_alloc(&ids->ipcs_idr, new,
107 (next_id < 0) ? 0 : ipcid_to_idx(next_id), 0,
108 GFP_NOWAIT);
109@@ -304,10 +308,6 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
110
111 ids->in_use++;
112
113- current_euid_egid(&euid, &egid);
114- new->cuid = new->uid = euid;
115- new->gid = new->cgid = egid;
116-
117 if (next_id < 0) {
118 new->seq = ids->seq++;
119 if (ids->seq > ids->seq_max)
120--
121cgit v0.12
122