bluetooth: rfcomm_init bug fix
rfcomm tty may be used before rfcomm_tty_driver initilized, The problem is that now socket layer init before tty layer, if userspace program do socket callback right here then oops will happen. reporting in: http://marc.info/?l=linux-bluetooth&m=124404919324542&w=2 make 3 changes: 1. remove #ifdef in rfcomm/core.c, make it blank function when rfcomm tty not selected in rfcomm.h 2. tune the rfcomm_init error patch to ensure tty driver initilized before rfcomm socket usage. 3. remove __exit for rfcomm_cleanup_sockets because above change need call it in a __init function. Reported-by: Oliver Hartkopp <oliver@hartkopp.net> Tested-by: Oliver Hartkopp <oliver@hartkopp.net> Signed-off-by: Dave Young <hidave.darkstar@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
eb4ad82641
commit
af0d3b103b
|
@ -355,7 +355,17 @@ struct rfcomm_dev_list_req {
|
|||
};
|
||||
|
||||
int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
|
||||
|
||||
#ifdef CONFIG_BT_RFCOMM_TTY
|
||||
int rfcomm_init_ttys(void);
|
||||
void rfcomm_cleanup_ttys(void);
|
||||
|
||||
#else
|
||||
static inline int rfcomm_init_ttys(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void rfcomm_cleanup_ttys(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif /* __RFCOMM_H */
|
||||
|
|
|
@ -2080,28 +2080,41 @@ static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL);
|
|||
/* ---- Initialization ---- */
|
||||
static int __init rfcomm_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
l2cap_load();
|
||||
|
||||
hci_register_cb(&rfcomm_cb);
|
||||
|
||||
rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd");
|
||||
if (IS_ERR(rfcomm_thread)) {
|
||||
hci_unregister_cb(&rfcomm_cb);
|
||||
return PTR_ERR(rfcomm_thread);
|
||||
ret = PTR_ERR(rfcomm_thread);
|
||||
goto out_thread;
|
||||
}
|
||||
|
||||
if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0)
|
||||
BT_ERR("Failed to create RFCOMM info file");
|
||||
|
||||
rfcomm_init_sockets();
|
||||
ret = rfcomm_init_ttys();
|
||||
if (ret)
|
||||
goto out_tty;
|
||||
|
||||
#ifdef CONFIG_BT_RFCOMM_TTY
|
||||
rfcomm_init_ttys();
|
||||
#endif
|
||||
ret = rfcomm_init_sockets();
|
||||
if (ret)
|
||||
goto out_sock;
|
||||
|
||||
BT_INFO("RFCOMM ver %s", VERSION);
|
||||
|
||||
return 0;
|
||||
|
||||
out_sock:
|
||||
rfcomm_cleanup_ttys();
|
||||
out_tty:
|
||||
kthread_stop(rfcomm_thread);
|
||||
out_thread:
|
||||
hci_unregister_cb(&rfcomm_cb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit rfcomm_exit(void)
|
||||
|
@ -2112,9 +2125,7 @@ static void __exit rfcomm_exit(void)
|
|||
|
||||
kthread_stop(rfcomm_thread);
|
||||
|
||||
#ifdef CONFIG_BT_RFCOMM_TTY
|
||||
rfcomm_cleanup_ttys();
|
||||
#endif
|
||||
|
||||
rfcomm_cleanup_sockets();
|
||||
}
|
||||
|
|
|
@ -1132,7 +1132,7 @@ int __init rfcomm_init_sockets(void)
|
|||
return err;
|
||||
}
|
||||
|
||||
void __exit rfcomm_cleanup_sockets(void)
|
||||
void rfcomm_cleanup_sockets(void)
|
||||
{
|
||||
class_remove_file(bt_class, &class_attr_rfcomm);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user