aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordann frazier <dannf@debian.org>2010-02-05 03:30:28 +0000
committerdann frazier <dannf@debian.org>2010-02-05 03:30:28 +0000
commitdf44b845c3bbd752f6bd47367c62a41ac7eed5af (patch)
tree5692f51a77e9355a411ceee82d943ab50cd95039
parent5071700ff1205091bb0a5980379c1fda555269a3 (diff)
downloadkernel_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/changelog1
-rw-r--r--debian/patches/bugfix/all/connector-delete-buggy-notification-code.patch326
-rw-r--r--debian/patches/series/81
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(&notify_lock);
+- list_for_each_entry(ent, &notify_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(&notify_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(&notify_lock);
+- list_for_each_entry_safe(ent, n, &notify_list, notify_entry) {
+- if (cn_ctl_msg_equals(ent->msg, ctl)) {
+- list_del(&ent->notify_entry);
+- kfree(ent);
+- }
+- }
+- mutex_unlock(&notify_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(&notify_lock);
+- list_add(&ent->notify_entry, &notify_list);
+- mutex_unlock(&notify_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