diff options
Diffstat (limited to 'recipes-kernel/linux/linux-hierofalcon-3.19/ipc-CVE-2015-7613.patch')
-rw-r--r-- | recipes-kernel/linux/linux-hierofalcon-3.19/ipc-CVE-2015-7613.patch | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-hierofalcon-3.19/ipc-CVE-2015-7613.patch b/recipes-kernel/linux/linux-hierofalcon-3.19/ipc-CVE-2015-7613.patch new file mode 100644 index 0000000..e9b94ad --- /dev/null +++ b/recipes-kernel/linux/linux-hierofalcon-3.19/ipc-CVE-2015-7613.patch | |||
@@ -0,0 +1,124 @@ | |||
1 | From b5495ddce4659122180b5fee6fc52dc5196e0918 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 | [ Upstream commit b9a532277938798b53178d5a66af6e2915cb27cf ] | ||
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 | Cc: stable@vger.kernel.org | ||
24 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | ||
25 | Signed-off-by: Sasha Levin <sasha.levin@oracle.com> | ||
26 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
27 | --- | ||
28 | ipc/msg.c | 14 +++++++------- | ||
29 | ipc/shm.c | 13 +++++++------ | ||
30 | ipc/util.c | 8 ++++---- | ||
31 | 3 files changed, 18 insertions(+), 17 deletions(-) | ||
32 | |||
33 | diff --git a/ipc/msg.c b/ipc/msg.c | ||
34 | index c5d8e37..cfc8b38 100644 | ||
35 | --- a/ipc/msg.c | ||
36 | +++ b/ipc/msg.c | ||
37 | @@ -137,13 +137,6 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) | ||
38 | return retval; | ||
39 | } | ||
40 | |||
41 | - /* ipc_addid() locks msq upon success. */ | ||
42 | - id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni); | ||
43 | - if (id < 0) { | ||
44 | - ipc_rcu_putref(msq, msg_rcu_free); | ||
45 | - return id; | ||
46 | - } | ||
47 | - | ||
48 | msq->q_stime = msq->q_rtime = 0; | ||
49 | msq->q_ctime = get_seconds(); | ||
50 | msq->q_cbytes = msq->q_qnum = 0; | ||
51 | @@ -153,6 +146,13 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) | ||
52 | INIT_LIST_HEAD(&msq->q_receivers); | ||
53 | INIT_LIST_HEAD(&msq->q_senders); | ||
54 | |||
55 | + /* ipc_addid() locks msq upon success. */ | ||
56 | + id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni); | ||
57 | + if (id < 0) { | ||
58 | + ipc_rcu_putref(msq, msg_rcu_free); | ||
59 | + return id; | ||
60 | + } | ||
61 | + | ||
62 | ipc_unlock_object(&msq->q_perm); | ||
63 | rcu_read_unlock(); | ||
64 | |||
65 | diff --git a/ipc/shm.c b/ipc/shm.c | ||
66 | index 0145479..2511771 100644 | ||
67 | --- a/ipc/shm.c | ||
68 | +++ b/ipc/shm.c | ||
69 | @@ -549,12 +549,6 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) | ||
70 | if (IS_ERR(file)) | ||
71 | goto no_file; | ||
72 | |||
73 | - id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni); | ||
74 | - if (id < 0) { | ||
75 | - error = id; | ||
76 | - goto no_id; | ||
77 | - } | ||
78 | - | ||
79 | shp->shm_cprid = task_tgid_vnr(current); | ||
80 | shp->shm_lprid = 0; | ||
81 | shp->shm_atim = shp->shm_dtim = 0; | ||
82 | @@ -563,6 +557,13 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) | ||
83 | shp->shm_nattch = 0; | ||
84 | shp->shm_file = file; | ||
85 | shp->shm_creator = current; | ||
86 | + | ||
87 | + id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni); | ||
88 | + if (id < 0) { | ||
89 | + error = id; | ||
90 | + goto no_id; | ||
91 | + } | ||
92 | + | ||
93 | list_add(&shp->shm_clist, ¤t->sysvshm.shm_clist); | ||
94 | |||
95 | /* | ||
96 | diff --git a/ipc/util.c b/ipc/util.c | ||
97 | index 88adc32..bc72cbf 100644 | ||
98 | --- a/ipc/util.c | ||
99 | +++ b/ipc/util.c | ||
100 | @@ -277,6 +277,10 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size) | ||
101 | rcu_read_lock(); | ||
102 | spin_lock(&new->lock); | ||
103 | |||
104 | + current_euid_egid(&euid, &egid); | ||
105 | + new->cuid = new->uid = euid; | ||
106 | + new->gid = new->cgid = egid; | ||
107 | + | ||
108 | id = idr_alloc(&ids->ipcs_idr, new, | ||
109 | (next_id < 0) ? 0 : ipcid_to_idx(next_id), 0, | ||
110 | GFP_NOWAIT); | ||
111 | @@ -289,10 +293,6 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size) | ||
112 | |||
113 | ids->in_use++; | ||
114 | |||
115 | - current_euid_egid(&euid, &egid); | ||
116 | - new->cuid = new->uid = euid; | ||
117 | - new->gid = new->cgid = egid; | ||
118 | - | ||
119 | if (next_id < 0) { | ||
120 | new->seq = ids->seq++; | ||
121 | if (ids->seq > IPCID_SEQ_MAX) | ||
122 | -- | ||
123 | cgit v0.12 | ||
124 | |||