From: Greg Kroah-Hartman Date: Tue, 7 Aug 2007 16:50:29 +0000 (-0700) Subject: 2 more 2.6.22 patches added X-Git-Tag: v2.6.22.2~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=55c3731b7df0697dc5ec6718eb6a34dd733c75ed;p=thirdparty%2Fkernel%2Fstable-queue.git 2 more 2.6.22 patches added --- diff --git a/queue-2.6.22/hangup-tty-before-releasing-rfcomm_dev.patch b/queue-2.6.22/hangup-tty-before-releasing-rfcomm_dev.patch new file mode 100644 index 00000000000..4a91ca7a6de --- /dev/null +++ b/queue-2.6.22/hangup-tty-before-releasing-rfcomm_dev.patch @@ -0,0 +1,35 @@ +From 84950cf0ba02fd6a5defe2511bc41f9aa2237632 Mon Sep 17 00:00:00 2001 +From: Mikko Rapeli +Date: Wed, 11 Jul 2007 09:18:15 +0200 +Subject: [PATCH] [Bluetooth] Hangup TTY before releasing rfcomm_dev + +From: Mikko Rapeli + +The core problem is that RFCOMM socket layer ioctl can release +rfcomm_dev struct while RFCOMM TTY layer is still actively using +it. Calling tty_vhangup() is needed for a synchronous hangup before +rfcomm_dev is freed. + +Addresses the oops at http://bugzilla.kernel.org/show_bug.cgi?id=7509 + +Acked-by: Alan Cox +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + net/bluetooth/rfcomm/tty.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/bluetooth/rfcomm/tty.c ++++ b/net/bluetooth/rfcomm/tty.c +@@ -383,6 +383,10 @@ static int rfcomm_release_dev(void __use + if (req.flags & (1 << RFCOMM_HANGUP_NOW)) + rfcomm_dlc_close(dev->dlc, 0); + ++ /* Shut down TTY synchronously before freeing rfcomm_dev */ ++ if (dev->tty) ++ tty_vhangup(dev->tty); ++ + rfcomm_dev_del(dev); + rfcomm_dev_put(dev); + return 0; diff --git a/queue-2.6.22/keep-rfcomm_dev-on-the-list-until-it-is-freed.patch b/queue-2.6.22/keep-rfcomm_dev-on-the-list-until-it-is-freed.patch new file mode 100644 index 00000000000..2264cc31e7a --- /dev/null +++ b/queue-2.6.22/keep-rfcomm_dev-on-the-list-until-it-is-freed.patch @@ -0,0 +1,111 @@ +From 8de0a15483b357d0f0b821330ec84d1660cadc4e Mon Sep 17 00:00:00 2001 +From: Ville Tervo +Date: Wed, 11 Jul 2007 09:23:41 +0200 +Subject: [PATCH] [Bluetooth] Keep rfcomm_dev on the list until it is freed + +From: Ville Tervo + +This patch changes the RFCOMM TTY release process so that the TTY is kept +on the list until it is really freed. A new device flag is used to keep +track of released TTYs. + +Signed-off-by: Ville Tervo +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/bluetooth/rfcomm.h | 1 + + net/bluetooth/rfcomm/tty.c | 30 ++++++++++++++++++++++-------- + 2 files changed, 23 insertions(+), 8 deletions(-) + +--- a/include/net/bluetooth/rfcomm.h ++++ b/include/net/bluetooth/rfcomm.h +@@ -323,6 +323,7 @@ int rfcomm_connect_ind(struct rfcomm_se + #define RFCOMM_RELEASE_ONHUP 1 + #define RFCOMM_HANGUP_NOW 2 + #define RFCOMM_TTY_ATTACHED 3 ++#define RFCOMM_TTY_RELEASED 4 + + struct rfcomm_dev_req { + s16 dev_id; +--- a/net/bluetooth/rfcomm/tty.c ++++ b/net/bluetooth/rfcomm/tty.c +@@ -95,6 +95,10 @@ static void rfcomm_dev_destruct(struct r + + BT_DBG("dev %p dlc %p", dev, dlc); + ++ write_lock_bh(&rfcomm_dev_lock); ++ list_del_init(&dev->list); ++ write_unlock_bh(&rfcomm_dev_lock); ++ + rfcomm_dlc_lock(dlc); + /* Detach DLC if it's owned by this dev */ + if (dlc->owner == dev) +@@ -156,8 +160,13 @@ static inline struct rfcomm_dev *rfcomm_ + read_lock(&rfcomm_dev_lock); + + dev = __rfcomm_dev_get(id); +- if (dev) +- rfcomm_dev_hold(dev); ++ ++ if (dev) { ++ if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) ++ dev = NULL; ++ else ++ rfcomm_dev_hold(dev); ++ } + + read_unlock(&rfcomm_dev_lock); + +@@ -265,6 +274,12 @@ out: + + dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL); + ++ if (IS_ERR(dev->tty_dev)) { ++ list_del(&dev->list); ++ kfree(dev); ++ return PTR_ERR(dev->tty_dev); ++ } ++ + return dev->id; + } + +@@ -272,10 +287,7 @@ static void rfcomm_dev_del(struct rfcomm + { + BT_DBG("dev %p", dev); + +- write_lock_bh(&rfcomm_dev_lock); +- list_del_init(&dev->list); +- write_unlock_bh(&rfcomm_dev_lock); +- ++ set_bit(RFCOMM_TTY_RELEASED, &dev->flags); + rfcomm_dev_put(dev); + } + +@@ -329,7 +341,7 @@ static int rfcomm_create_dev(struct sock + if (copy_from_user(&req, arg, sizeof(req))) + return -EFAULT; + +- BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags); ++ BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags); + + if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) + return -EPERM; +@@ -370,7 +382,7 @@ static int rfcomm_release_dev(void __use + if (copy_from_user(&req, arg, sizeof(req))) + return -EFAULT; + +- BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags); ++ BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags); + + if (!(dev = rfcomm_dev_get(req.dev_id))) + return -ENODEV; +@@ -419,6 +431,8 @@ static int rfcomm_get_dev_list(void __us + + list_for_each(p, &rfcomm_dev_list) { + struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list); ++ if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) ++ continue; + (di + n)->id = dev->id; + (di + n)->flags = dev->flags; + (di + n)->state = dev->dlc->state; diff --git a/queue-2.6.22/series b/queue-2.6.22/series index 63e29895106..31132a01a90 100644 --- a/queue-2.6.22/series +++ b/queue-2.6.22/series @@ -73,3 +73,5 @@ dm-snapshot-permit-invalid-activation.patch dm-disable-barriers.patch cr_backlight_probe-allocates-too-little-storage-for-struct-cr_panel.patch acpi-dock-fix-opps-after-dock-driver-fails-to-initialize.patch +hangup-tty-before-releasing-rfcomm_dev.patch +keep-rfcomm_dev-on-the-list-until-it-is-freed.patch