diff options
Diffstat (limited to 'recipes-kernel/linux/linux-qoriq-3.12')
-rw-r--r-- | recipes-kernel/linux/linux-qoriq-3.12/ipc-CVE-2015-7613.patch | 122 |
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 @@ | |||
1 | From 89c7ab1494f614bf8323490c79d4a562e90db61b Mon Sep 17 00:00:00 2001 | ||
2 | From: Linus Torvalds <torvalds@linux-foundation.org> | ||
3 | Date: Wed, 30 Sep 2015 12:48:40 -0400 | ||
4 | Subject: Initialize msg/shm IPC objects before doing ipc_addid() | ||
5 | |||
6 | commit b9a532277938798b53178d5a66af6e2915cb27cf upstream. | ||
7 | |||
8 | As reported by Dmitry Vyukov, we really shouldn't do ipc_addid() before | ||
9 | having initialized the IPC object state. Yes, we initialize the IPC | ||
10 | object in a locked state, but with all the lockless RCU lookup work, | ||
11 | that IPC object lock no longer means that the state cannot be seen. | ||
12 | |||
13 | We 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 | ||
15 | clearly forgot about msg and shm. | ||
16 | |||
17 | Fixes CVE-2015-7613. | ||
18 | Upstream-Status: Backport | ||
19 | |||
20 | Reported-by: Dmitry Vyukov <dvyukov@google.com> | ||
21 | Cc: Manfred Spraul <manfred@colorfullife.com> | ||
22 | Cc: Davidlohr Bueso <dbueso@suse.de> | ||
23 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | ||
24 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | ||
25 | Signed-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 | |||
32 | diff --git a/ipc/msg.c b/ipc/msg.c | ||
33 | index 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 | |||
64 | diff --git a/ipc/shm.c b/ipc/shm.c | ||
65 | index 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. | ||
94 | diff --git a/ipc/util.c b/ipc/util.c | ||
95 | index 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 | -- | ||
121 | cgit v0.12 | ||
122 | |||