From 4e4e1a7e09245239a18e484c946cf94f5563a391 Mon Sep 17 00:00:00 2001 From: Sona Sarmadi Date: Thu, 28 Jan 2016 11:19:37 +0100 Subject: ipc: CVE-2015-7613 Fixes a race condition flaw in the Linux kernel's IPC subsystem. Upstream patch: https://github.com/torvalds/linux/commit/b9a532277938 References: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-7613 http://seclists.org/oss-sec/2015/q4/7 Signed-off-by: Sona Sarmadi Signed-off-by: Paul Vaduva --- .../linux/linux-qoriq-3.12/ipc-CVE-2015-7613.patch | 122 +++++++++++++++++++++ recipes-kernel/linux/linux-qoriq-common.inc | 1 + .../linux/linux-yocto-3.14/ipc-CVE-2015-7613.patch | 122 +++++++++++++++++++++ recipes-kernel/linux/linux-yocto_3.14.bbappend | 1 + 4 files changed, 246 insertions(+) create mode 100644 recipes-kernel/linux/linux-qoriq-3.12/ipc-CVE-2015-7613.patch create mode 100644 recipes-kernel/linux/linux-yocto-3.14/ipc-CVE-2015-7613.patch 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 @@ +From 89c7ab1494f614bf8323490c79d4a562e90db61b Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Wed, 30 Sep 2015 12:48:40 -0400 +Subject: Initialize msg/shm IPC objects before doing ipc_addid() + +commit b9a532277938798b53178d5a66af6e2915cb27cf upstream. + +As reported by Dmitry Vyukov, we really shouldn't do ipc_addid() before +having initialized the IPC object state. Yes, we initialize the IPC +object in a locked state, but with all the lockless RCU lookup work, +that IPC object lock no longer means that the state cannot be seen. + +We already did this for the IPC semaphore code (see commit e8577d1f0329: +"ipc/sem.c: fully initialize sem_array before making it visible") but we +clearly forgot about msg and shm. + +Fixes CVE-2015-7613. +Upstream-Status: Backport + +Reported-by: Dmitry Vyukov +Cc: Manfred Spraul +Cc: Davidlohr Bueso +Signed-off-by: Linus Torvalds +Signed-off-by: Jiri Slaby +Signed-off-by: Sona Sarmadi +--- + ipc/msg.c | 14 +++++++------- + ipc/shm.c | 12 ++++++------ + ipc/util.c | 8 ++++---- + 3 files changed, 17 insertions(+), 17 deletions(-) + +diff --git a/ipc/msg.c b/ipc/msg.c +index 52770bf..32aaaab 100644 +--- a/ipc/msg.c ++++ b/ipc/msg.c +@@ -202,13 +202,6 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) + return retval; + } + +- /* ipc_addid() locks msq upon success. */ +- id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni); +- if (id < 0) { +- ipc_rcu_putref(msq, msg_rcu_free); +- return id; +- } +- + msq->q_stime = msq->q_rtime = 0; + msq->q_ctime = get_seconds(); + msq->q_cbytes = msq->q_qnum = 0; +@@ -218,6 +211,13 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) + INIT_LIST_HEAD(&msq->q_receivers); + INIT_LIST_HEAD(&msq->q_senders); + ++ /* ipc_addid() locks msq upon success. */ ++ id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni); ++ if (id < 0) { ++ ipc_rcu_putref(msq, msg_rcu_free); ++ return id; ++ } ++ + ipc_unlock_object(&msq->q_perm); + rcu_read_unlock(); + +diff --git a/ipc/shm.c b/ipc/shm.c +index 623bc38..02f7125 100644 +--- a/ipc/shm.c ++++ b/ipc/shm.c +@@ -545,12 +545,6 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) + if (IS_ERR(file)) + goto no_file; + +- id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni); +- if (id < 0) { +- error = id; +- goto no_id; +- } +- + shp->shm_cprid = task_tgid_vnr(current); + shp->shm_lprid = 0; + shp->shm_atim = shp->shm_dtim = 0; +@@ -560,6 +554,12 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) + shp->shm_file = file; + shp->shm_creator = current; + ++ id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni); ++ if (id < 0) { ++ error = id; ++ goto no_id; ++ } ++ + /* + * shmid gets reported as "inode#" in /proc/pid/maps. + * proc-ps tools use this. Changing this will break them. +diff --git a/ipc/util.c b/ipc/util.c +index 7684f41..7353425 100644 +--- a/ipc/util.c ++++ b/ipc/util.c +@@ -292,6 +292,10 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) + rcu_read_lock(); + spin_lock(&new->lock); + ++ current_euid_egid(&euid, &egid); ++ new->cuid = new->uid = euid; ++ new->gid = new->cgid = egid; ++ + id = idr_alloc(&ids->ipcs_idr, new, + (next_id < 0) ? 0 : ipcid_to_idx(next_id), 0, + GFP_NOWAIT); +@@ -304,10 +308,6 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) + + ids->in_use++; + +- current_euid_egid(&euid, &egid); +- new->cuid = new->uid = euid; +- new->gid = new->cgid = egid; +- + if (next_id < 0) { + new->seq = ids->seq++; + if (ids->seq > ids->seq_max) +-- +cgit v0.12 + diff --git a/recipes-kernel/linux/linux-qoriq-common.inc b/recipes-kernel/linux/linux-qoriq-common.inc index 3abe78d..90cae6d 100644 --- a/recipes-kernel/linux/linux-qoriq-common.inc +++ b/recipes-kernel/linux/linux-qoriq-common.inc @@ -19,6 +19,7 @@ SRC_URI += "file://b4860-hard_irq_disable-bug.patch \ file://vfs-CVE-2015-2925.patch \ file://dcache-CVE-2015-2925.patch \ file://virtio-net-CVE-2015-5156.patch \ + file://ipc-CVE-2015-7613.patch \ " SRC_URI += "file://cfg/00013-localversion.cfg \ diff --git a/recipes-kernel/linux/linux-yocto-3.14/ipc-CVE-2015-7613.patch b/recipes-kernel/linux/linux-yocto-3.14/ipc-CVE-2015-7613.patch new file mode 100644 index 0000000..f727419 --- /dev/null +++ b/recipes-kernel/linux/linux-yocto-3.14/ipc-CVE-2015-7613.patch @@ -0,0 +1,122 @@ +From 58c01a5074bc551a151b6b44f56ed40debd6b99d Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Wed, 30 Sep 2015 12:48:40 -0400 +Subject: Initialize msg/shm IPC objects before doing ipc_addid() + +commit b9a532277938798b53178d5a66af6e2915cb27cf upstream. + +As reported by Dmitry Vyukov, we really shouldn't do ipc_addid() before +having initialized the IPC object state. Yes, we initialize the IPC +object in a locked state, but with all the lockless RCU lookup work, +that IPC object lock no longer means that the state cannot be seen. + +We already did this for the IPC semaphore code (see commit e8577d1f0329: +"ipc/sem.c: fully initialize sem_array before making it visible") but we +clearly forgot about msg and shm. + +Fixes CVE-2015-7613. +Upstream-Status: Backport + +Reported-by: Dmitry Vyukov +Cc: Manfred Spraul +Cc: Davidlohr Bueso +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sona Sarmadi +--- + ipc/msg.c | 14 +++++++------- + ipc/shm.c | 12 ++++++------ + ipc/util.c | 8 ++++---- + 3 files changed, 17 insertions(+), 17 deletions(-) + +diff --git a/ipc/msg.c b/ipc/msg.c +index 6498531..4a036c6 100644 +--- a/ipc/msg.c ++++ b/ipc/msg.c +@@ -202,13 +202,6 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) + return retval; + } + +- /* ipc_addid() locks msq upon success. */ +- id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni); +- if (id < 0) { +- ipc_rcu_putref(msq, msg_rcu_free); +- return id; +- } +- + msq->q_stime = msq->q_rtime = 0; + msq->q_ctime = get_seconds(); + msq->q_cbytes = msq->q_qnum = 0; +@@ -218,6 +211,13 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) + INIT_LIST_HEAD(&msq->q_receivers); + INIT_LIST_HEAD(&msq->q_senders); + ++ /* ipc_addid() locks msq upon success. */ ++ id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni); ++ if (id < 0) { ++ ipc_rcu_putref(msq, msg_rcu_free); ++ return id; ++ } ++ + ipc_unlock_object(&msq->q_perm); + rcu_read_unlock(); + +diff --git a/ipc/shm.c b/ipc/shm.c +index 7645961..ada866d 100644 +--- a/ipc/shm.c ++++ b/ipc/shm.c +@@ -543,12 +543,6 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) + if (IS_ERR(file)) + goto no_file; + +- id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni); +- if (id < 0) { +- error = id; +- goto no_id; +- } +- + shp->shm_cprid = task_tgid_vnr(current); + shp->shm_lprid = 0; + shp->shm_atim = shp->shm_dtim = 0; +@@ -558,6 +552,12 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) + shp->shm_file = file; + shp->shm_creator = current; + ++ id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni); ++ if (id < 0) { ++ error = id; ++ goto no_id; ++ } ++ + /* + * shmid gets reported as "inode#" in /proc/pid/maps. + * proc-ps tools use this. Changing this will break them. +diff --git a/ipc/util.c b/ipc/util.c +index e1b4c6d..cdb19ce 100644 +--- a/ipc/util.c ++++ b/ipc/util.c +@@ -277,6 +277,10 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size) + rcu_read_lock(); + spin_lock(&new->lock); + ++ current_euid_egid(&euid, &egid); ++ new->cuid = new->uid = euid; ++ new->gid = new->cgid = egid; ++ + id = idr_alloc(&ids->ipcs_idr, new, + (next_id < 0) ? 0 : ipcid_to_idx(next_id), 0, + GFP_NOWAIT); +@@ -289,10 +293,6 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size) + + ids->in_use++; + +- current_euid_egid(&euid, &egid); +- new->cuid = new->uid = euid; +- new->gid = new->cgid = egid; +- + if (next_id < 0) { + new->seq = ids->seq++; + if (ids->seq > IPCID_SEQ_MAX) +-- +cgit v0.12 + diff --git a/recipes-kernel/linux/linux-yocto_3.14.bbappend b/recipes-kernel/linux/linux-yocto_3.14.bbappend index 2f32b56..9eb4365 100644 --- a/recipes-kernel/linux/linux-yocto_3.14.bbappend +++ b/recipes-kernel/linux/linux-yocto_3.14.bbappend @@ -24,4 +24,5 @@ SRC_URI += "file://HID_CVE_patches/0005-HID-steelseries-validate-output-report-d file://vfs-CVE-2015-2925.patch \ file://dcache-CVE-2015-2925.patch \ file://virtio-net-CVE-2015-5156.patch \ + file://ipc-CVE-2015-7613.patch \ " -- cgit v1.2.3-54-g00ecf