The patch titled bloetooth: guard bt_proto with rwlock has been added to the -mm tree. Its filename is bluetooth-guard-bt_proto-with-rwlock.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: bloetooth: guard bt_proto with rwlock From: Masatake YAMATO <jet@xxxxxxxx> I found that bt_proto manipulated in bt_sock_register is not guarded from race condition. Look at net/bluetooth/af_bluetooth.c: static struct net_proto_family *bt_proto[BT_MAX_PROTO]; int bt_sock_register(int proto, struct net_proto_family *ops) { if (proto < 0 || proto >= BT_MAX_PROTO) return -EINVAL; if (bt_proto[proto]) return -EEXIST; bt_proto[proto] = ops; return 0; } Here bt_proto[proto] is set. In other hand, static int bt_sock_create(struct socket *sock, int proto) { int err = 0; if (proto < 0 || proto >= BT_MAX_PROTO) return -EINVAL; #if defined(CONFIG_KMOD) if (!bt_proto[proto]) { request_module("bt-proto-%d", proto); } #endif err = -EPROTONOSUPPORT; if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { err = bt_proto[proto]->create(sock, proto); module_put(bt_proto[proto]->owner); } return err; } bt_proto[proto] is referred. So I wrote a patch which guards bt_proto with rwlock. Signed-off-by: Masatake YAMATO <jet@xxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- net/bluetooth/af_bluetooth.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff -puN net/bluetooth/af_bluetooth.c~bluetooth-guard-bt_proto-with-rwlock net/bluetooth/af_bluetooth.c --- a/net/bluetooth/af_bluetooth.c~bluetooth-guard-bt_proto-with-rwlock +++ a/net/bluetooth/af_bluetooth.c @@ -26,6 +26,7 @@ #include <linux/module.h> +#include <linux/spinlock.h> #include <linux/types.h> #include <linux/list.h> #include <linux/errno.h> @@ -53,30 +54,44 @@ /* Bluetooth sockets */ #define BT_MAX_PROTO 8 static struct net_proto_family *bt_proto[BT_MAX_PROTO]; +static DEFINE_RWLOCK(bt_proto_rwlock); int bt_sock_register(int proto, struct net_proto_family *ops) { + int err; + if (proto < 0 || proto >= BT_MAX_PROTO) return -EINVAL; - if (bt_proto[proto]) - return -EEXIST; + err = -EEXIST; - bt_proto[proto] = ops; - return 0; + write_lock(&bt_proto_rwlock); + if (bt_proto[proto] == NULL) { + err = 0; + bt_proto[proto] = ops; + } + write_unlock(&bt_proto_rwlock); + + return err; } EXPORT_SYMBOL(bt_sock_register); int bt_sock_unregister(int proto) { + int err; + if (proto < 0 || proto >= BT_MAX_PROTO) return -EINVAL; - if (!bt_proto[proto]) - return -ENOENT; + err = -ENOENT; + write_lock(&bt_proto_rwlock); + if (bt_proto[proto]) { + err = 0; + bt_proto[proto] = NULL; + } + write_unlock(&bt_proto_rwlock); - bt_proto[proto] = NULL; - return 0; + return err; } EXPORT_SYMBOL(bt_sock_unregister); @@ -93,10 +108,12 @@ static int bt_sock_create(struct socket } #endif err = -EPROTONOSUPPORT; + read_lock(&bt_proto_rwlock); if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { err = bt_proto[proto]->create(sock, proto); module_put(bt_proto[proto]->owner); } + read_unlock(&bt_proto_rwlock); return err; } _ Patches currently in -mm which might be from jet@xxxxxxxx are bluetooth-guard-bt_proto-with-rwlock.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html