diff options
author | dann frazier <dannf@debian.org> | 2010-02-05 03:30:28 +0000 |
---|---|---|
committer | dann frazier <dannf@debian.org> | 2010-02-05 03:30:28 +0000 |
commit | df44b845c3bbd752f6bd47367c62a41ac7eed5af (patch) | |
tree | 5692f51a77e9355a411ceee82d943ab50cd95039 | |
parent | 5071700ff1205091bb0a5980379c1fda555269a3 (diff) | |
download | kernel_replicant_linux-df44b845c3bbd752f6bd47367c62a41ac7eed5af.tar.gz kernel_replicant_linux-df44b845c3bbd752f6bd47367c62a41ac7eed5af.tar.bz2 kernel_replicant_linux-df44b845c3bbd752f6bd47367c62a41ac7eed5af.zip |
connector: Delete buggy notification code. (CVE-2010-0410)
svn path=/dists/trunk/linux-2.6/; revision=15128
-rw-r--r-- | debian/changelog | 1 | ||||
-rw-r--r-- | debian/patches/bugfix/all/connector-delete-buggy-notification-code.patch | 326 | ||||
-rw-r--r-- | debian/patches/series/8 | 1 |
3 files changed, 328 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog index c93006f4e9b2..def4c1a9d96b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,6 +7,7 @@ linux-2.6 (2.6.32-8) UNRELEASED; urgency=low * Remove TIF_ABI_PENDING bit from x86, sparc & powerpc, fixing 32-bit userland/64-bit kernel breakage (Closes: #568416) * KVM: PIT: control word is write-only (CVE-2010-0309) + * connector: Delete buggy notification code. (CVE-2010-0410) [ Ben Hutchings ] * Build lgs8gxx driver along with cxusb (Closes: #568414) diff --git a/debian/patches/bugfix/all/connector-delete-buggy-notification-code.patch b/debian/patches/bugfix/all/connector-delete-buggy-notification-code.patch new file mode 100644 index 000000000000..55b07939b7cf --- /dev/null +++ b/debian/patches/bugfix/all/connector-delete-buggy-notification-code.patch @@ -0,0 +1,326 @@ +From f98bfbd78c37c5946cc53089da32a5f741efdeb7 Mon Sep 17 00:00:00 2001 +From: Evgeniy Polyakov <zbr@ioremap.net> +Date: Tue, 2 Feb 2010 15:58:48 -0800 +Subject: connector: Delete buggy notification code. + +From: Evgeniy Polyakov <zbr@ioremap.net> + +commit f98bfbd78c37c5946cc53089da32a5f741efdeb7 upstream. + +On Tue, Feb 02, 2010 at 02:57:14PM -0800, Greg KH (gregkh@suse.de) wrote: +> > There are at least two ways to fix it: using a big cannon and a small +> > one. The former way is to disable notification registration, since it is +> > not used by anyone at all. Second way is to check whether calling +> > process is root and its destination group is -1 (kind of priveledged +> > one) before command is dispatched to workqueue. +> +> Well if no one is using it, removing it makes the most sense, right? +> +> No objection from me, care to make up a patch either way for this? + +Getting it is not used, let's drop support for notifications about +(un)registered events from connector. +Another option was to check credentials on receiving, but we can always +restore it without bugs if needed, but genetlink has a wider code base +and none complained, that userspace can not get notification when some +other clients were (un)registered. + +Kudos for Sebastian Krahmer <krahmer@suse.de>, who found a bug in the +code. + +Signed-off-by: Evgeniy Polyakov <zbr@ioremap.net> +Acked-by: Greg Kroah-Hartman <gregkh@suse.de> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/connector/connector.c | 175 ------------------------------------------ + include/linux/connector.h | 32 ------- + 2 files changed, 207 deletions(-) + +--- a/drivers/connector/connector.c ++++ b/drivers/connector/connector.c +@@ -36,17 +36,6 @@ MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); + MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); + +-static u32 cn_idx = CN_IDX_CONNECTOR; +-static u32 cn_val = CN_VAL_CONNECTOR; +- +-module_param(cn_idx, uint, 0); +-module_param(cn_val, uint, 0); +-MODULE_PARM_DESC(cn_idx, "Connector's main device idx."); +-MODULE_PARM_DESC(cn_val, "Connector's main device val."); +- +-static DEFINE_MUTEX(notify_lock); +-static LIST_HEAD(notify_list); +- + static struct cn_dev cdev; + + static int cn_already_initialized; +@@ -210,54 +199,6 @@ static void cn_rx_skb(struct sk_buff *__ + } + + /* +- * Notification routing. +- * +- * Gets id and checks if there are notification request for it's idx +- * and val. If there are such requests notify the listeners with the +- * given notify event. +- * +- */ +-static void cn_notify(struct cb_id *id, u32 notify_event) +-{ +- struct cn_ctl_entry *ent; +- +- mutex_lock(¬ify_lock); +- list_for_each_entry(ent, ¬ify_list, notify_entry) { +- int i; +- struct cn_notify_req *req; +- struct cn_ctl_msg *ctl = ent->msg; +- int idx_found, val_found; +- +- idx_found = val_found = 0; +- +- req = (struct cn_notify_req *)ctl->data; +- for (i = 0; i < ctl->idx_notify_num; ++i, ++req) { +- if (id->idx >= req->first && +- id->idx < req->first + req->range) { +- idx_found = 1; +- break; +- } +- } +- +- for (i = 0; i < ctl->val_notify_num; ++i, ++req) { +- if (id->val >= req->first && +- id->val < req->first + req->range) { +- val_found = 1; +- break; +- } +- } +- +- if (idx_found && val_found) { +- struct cn_msg m = { .ack = notify_event, }; +- +- memcpy(&m.id, id, sizeof(m.id)); +- cn_netlink_send(&m, ctl->group, GFP_KERNEL); +- } +- } +- mutex_unlock(¬ify_lock); +-} +- +-/* + * Callback add routing - adds callback with given ID and name. + * If there is registered callback with the same ID it will not be added. + * +@@ -276,8 +217,6 @@ int cn_add_callback(struct cb_id *id, ch + if (err) + return err; + +- cn_notify(id, 0); +- + return 0; + } + EXPORT_SYMBOL_GPL(cn_add_callback); +@@ -295,111 +234,9 @@ void cn_del_callback(struct cb_id *id) + struct cn_dev *dev = &cdev; + + cn_queue_del_callback(dev->cbdev, id); +- cn_notify(id, 1); + } + EXPORT_SYMBOL_GPL(cn_del_callback); + +-/* +- * Checks two connector's control messages to be the same. +- * Returns 1 if they are the same or if the first one is corrupted. +- */ +-static int cn_ctl_msg_equals(struct cn_ctl_msg *m1, struct cn_ctl_msg *m2) +-{ +- int i; +- struct cn_notify_req *req1, *req2; +- +- if (m1->idx_notify_num != m2->idx_notify_num) +- return 0; +- +- if (m1->val_notify_num != m2->val_notify_num) +- return 0; +- +- if (m1->len != m2->len) +- return 0; +- +- if ((m1->idx_notify_num + m1->val_notify_num) * sizeof(*req1) != +- m1->len) +- return 1; +- +- req1 = (struct cn_notify_req *)m1->data; +- req2 = (struct cn_notify_req *)m2->data; +- +- for (i = 0; i < m1->idx_notify_num; ++i) { +- if (req1->first != req2->first || req1->range != req2->range) +- return 0; +- req1++; +- req2++; +- } +- +- for (i = 0; i < m1->val_notify_num; ++i) { +- if (req1->first != req2->first || req1->range != req2->range) +- return 0; +- req1++; +- req2++; +- } +- +- return 1; +-} +- +-/* +- * Main connector device's callback. +- * +- * Used for notification of a request's processing. +- */ +-static void cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) +-{ +- struct cn_ctl_msg *ctl; +- struct cn_ctl_entry *ent; +- u32 size; +- +- if (msg->len < sizeof(*ctl)) +- return; +- +- ctl = (struct cn_ctl_msg *)msg->data; +- +- size = (sizeof(*ctl) + ((ctl->idx_notify_num + +- ctl->val_notify_num) * +- sizeof(struct cn_notify_req))); +- +- if (msg->len != size) +- return; +- +- if (ctl->len + sizeof(*ctl) != msg->len) +- return; +- +- /* +- * Remove notification. +- */ +- if (ctl->group == 0) { +- struct cn_ctl_entry *n; +- +- mutex_lock(¬ify_lock); +- list_for_each_entry_safe(ent, n, ¬ify_list, notify_entry) { +- if (cn_ctl_msg_equals(ent->msg, ctl)) { +- list_del(&ent->notify_entry); +- kfree(ent); +- } +- } +- mutex_unlock(¬ify_lock); +- +- return; +- } +- +- size += sizeof(*ent); +- +- ent = kzalloc(size, GFP_KERNEL); +- if (!ent) +- return; +- +- ent->msg = (struct cn_ctl_msg *)(ent + 1); +- +- memcpy(ent->msg, ctl, size - sizeof(*ent)); +- +- mutex_lock(¬ify_lock); +- list_add(&ent->notify_entry, ¬ify_list); +- mutex_unlock(¬ify_lock); +-} +- + static int cn_proc_show(struct seq_file *m, void *v) + { + struct cn_queue_dev *dev = cdev.cbdev; +@@ -437,11 +274,8 @@ static const struct file_operations cn_f + static int __devinit cn_init(void) + { + struct cn_dev *dev = &cdev; +- int err; + + dev->input = cn_rx_skb; +- dev->id.idx = cn_idx; +- dev->id.val = cn_val; + + dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR, + CN_NETLINK_USERS + 0xf, +@@ -457,14 +291,6 @@ static int __devinit cn_init(void) + + cn_already_initialized = 1; + +- err = cn_add_callback(&dev->id, "connector", &cn_callback); +- if (err) { +- cn_already_initialized = 0; +- cn_queue_free_dev(dev->cbdev); +- netlink_kernel_release(dev->nls); +- return -EINVAL; +- } +- + proc_net_fops_create(&init_net, "connector", S_IRUGO, &cn_file_ops); + + return 0; +@@ -478,7 +304,6 @@ static void __devexit cn_fini(void) + + proc_net_remove(&init_net, "connector"); + +- cn_del_callback(&dev->id); + cn_queue_free_dev(dev->cbdev); + netlink_kernel_release(dev->nls); + } +--- a/include/linux/connector.h ++++ b/include/linux/connector.h +@@ -24,9 +24,6 @@ + + #include <linux/types.h> + +-#define CN_IDX_CONNECTOR 0xffffffff +-#define CN_VAL_CONNECTOR 0xffffffff +- + /* + * Process Events connector unique ids -- used for message routing + */ +@@ -73,30 +70,6 @@ struct cn_msg { + __u8 data[0]; + }; + +-/* +- * Notify structure - requests notification about +- * registering/unregistering idx/val in range [first, first+range]. +- */ +-struct cn_notify_req { +- __u32 first; +- __u32 range; +-}; +- +-/* +- * Main notification control message +- * *_notify_num - number of appropriate cn_notify_req structures after +- * this struct. +- * group - notification receiver's idx. +- * len - total length of the attached data. +- */ +-struct cn_ctl_msg { +- __u32 idx_notify_num; +- __u32 val_notify_num; +- __u32 group; +- __u32 len; +- __u8 data[0]; +-}; +- + #ifdef __KERNEL__ + + #include <asm/atomic.h> +@@ -149,11 +122,6 @@ struct cn_callback_entry { + u32 seq, group; + }; + +-struct cn_ctl_entry { +- struct list_head notify_entry; +- struct cn_ctl_msg *msg; +-}; +- + struct cn_dev { + struct cb_id id; + diff --git a/debian/patches/series/8 b/debian/patches/series/8 index a95236f4b37d..4c09d5792044 100644 --- a/debian/patches/series/8 +++ b/debian/patches/series/8 @@ -5,3 +5,4 @@ - bugfix/all/clocksource-events-Fix-fallout-of-generic-code-changes.patch + bugfix/all/clocksource-always-define-clocksource_max_deferment.patch + bugfix/x86/kvm-pit-control-word-is-write-only.patch ++ bugfix/all/connector-delete-buggy-notification-code.patch |