mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-28 17:41:50 +00:00
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
3 changed files with 31 additions and 10 deletions
|
@ -355,7 +355,17 @@ struct rfcomm_dev_list_req {
|
||||||
};
|
};
|
||||||
|
|
||||||
int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
|
int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
|
||||||
|
|
||||||
|
#ifdef CONFIG_BT_RFCOMM_TTY
|
||||||
int rfcomm_init_ttys(void);
|
int rfcomm_init_ttys(void);
|
||||||
void rfcomm_cleanup_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 */
|
#endif /* __RFCOMM_H */
|
||||||
|
|
|
@ -2080,28 +2080,41 @@ static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL);
|
||||||
/* ---- Initialization ---- */
|
/* ---- Initialization ---- */
|
||||||
static int __init rfcomm_init(void)
|
static int __init rfcomm_init(void)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
l2cap_load();
|
l2cap_load();
|
||||||
|
|
||||||
hci_register_cb(&rfcomm_cb);
|
hci_register_cb(&rfcomm_cb);
|
||||||
|
|
||||||
rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd");
|
rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd");
|
||||||
if (IS_ERR(rfcomm_thread)) {
|
if (IS_ERR(rfcomm_thread)) {
|
||||||
hci_unregister_cb(&rfcomm_cb);
|
ret = PTR_ERR(rfcomm_thread);
|
||||||
return PTR_ERR(rfcomm_thread);
|
goto out_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0)
|
if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0)
|
||||||
BT_ERR("Failed to create RFCOMM info file");
|
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
|
ret = rfcomm_init_sockets();
|
||||||
rfcomm_init_ttys();
|
if (ret)
|
||||||
#endif
|
goto out_sock;
|
||||||
|
|
||||||
BT_INFO("RFCOMM ver %s", VERSION);
|
BT_INFO("RFCOMM ver %s", VERSION);
|
||||||
|
|
||||||
return 0;
|
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)
|
static void __exit rfcomm_exit(void)
|
||||||
|
@ -2112,9 +2125,7 @@ static void __exit rfcomm_exit(void)
|
||||||
|
|
||||||
kthread_stop(rfcomm_thread);
|
kthread_stop(rfcomm_thread);
|
||||||
|
|
||||||
#ifdef CONFIG_BT_RFCOMM_TTY
|
|
||||||
rfcomm_cleanup_ttys();
|
rfcomm_cleanup_ttys();
|
||||||
#endif
|
|
||||||
|
|
||||||
rfcomm_cleanup_sockets();
|
rfcomm_cleanup_sockets();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1132,7 +1132,7 @@ error:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __exit rfcomm_cleanup_sockets(void)
|
void rfcomm_cleanup_sockets(void)
|
||||||
{
|
{
|
||||||
class_remove_file(bt_class, &class_attr_rfcomm);
|
class_remove_file(bt_class, &class_attr_rfcomm);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue