diff mbox series

[BlueZ] mesh: Fix segfault caused by re-enabling of HCI controller

Message ID 20200515061530.4983-1-inga.stotland@intel.com (mailing list archive)
State Superseded
Headers show
Series [BlueZ] mesh: Fix segfault caused by re-enabling of HCI controller | expand

Commit Message

Stotland, Inga May 15, 2020, 6:15 a.m. UTC
This fixes a crash incase when a controller used by bluetooth-meshd
is removed and then added back again.

Add a "restart" operation to mesh-io API to deal with a distinct case
of re-adding a previously used controller.

Backtrace:
0x00005618e754d040 in ?? ()
0x00005618e6e12d9a in io_ready_callback (user_data=0x5618e75538a0, result=<optimized out>) at mesh/mesh.c:174
0x00005618e6e3d2c8 in l_queue_foreach (queue=<optimized out>, function=0x5618e6e158e0 <process_read_info_req>, user_data=0x0)
    at ell/queue.c:441
0x00005618e6e37927 in request_complete (mgmt=mgmt@entry=0x5618e754ad50, status=<optimized out>, opcode=opcode@entry=4,
    index=index@entry=0, length=length@entry=280, param=0x5618e754b389) at src/shared/mgmt.c:261
---
 mesh/mesh-io-api.h     |  2 ++
 mesh/mesh-io-generic.c | 21 +++++++++++++++++++++
 mesh/mesh-io.c         |  8 ++++++++
 mesh/mesh-io.h         |  1 +
 mesh/mesh.c            | 12 +++++++++++-
 5 files changed, 43 insertions(+), 1 deletion(-)

Comments

bluez.test.bot@gmail.com May 15, 2020, 6:36 a.m. UTC | #1
This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
While we are preparing for reviewing the patches, we found the following
issue/warning.

Test Result:
checkpatch Failed

Outputs:
WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#14: 
0x00005618e6e12d9a in io_ready_callback (user_data=0x5618e75538a0, result=<optimized out>) at mesh/mesh.c:174

- total: 0 errors, 1 warnings, 101 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

Your patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPLIT_STRING

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.



---
Regards,
Linux Bluetooth
bluez.test.bot@gmail.com May 15, 2020, 6:36 a.m. UTC | #2
This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
While we are preparing for reviewing the patches, we found the following
issue/warning.

Test Result:
checkgitlint Failed

Outputs:
11: B1 Line exceeds max length (109>80): "0x00005618e6e12d9a in io_ready_callback (user_data=0x5618e75538a0, result=<optimized out>) at mesh/mesh.c:174"
12: B1 Line exceeds max length (125>80): "0x00005618e6e3d2c8 in l_queue_foreach (queue=<optimized out>, function=0x5618e6e158e0 <process_read_info_req>, user_data=0x0)"
14: B1 Line exceeds max length (118>80): "0x00005618e6e37927 in request_complete (mgmt=mgmt@entry=0x5618e754ad50, status=<optimized out>, opcode=opcode@entry=4,"
15: B1 Line exceeds max length (96>80): "    index=index@entry=0, length=length@entry=280, param=0x5618e754b389) at src/shared/mgmt.c:261"



---
Regards,
Linux Bluetooth
diff mbox series

Patch

diff --git a/mesh/mesh-io-api.h b/mesh/mesh-io-api.h
index 7a5b49c60..f6ca59833 100644
--- a/mesh/mesh-io-api.h
+++ b/mesh/mesh-io-api.h
@@ -22,6 +22,7 @@  struct mesh_io_private;
 typedef bool (*mesh_io_init_t)(struct mesh_io *io, void *opts,
 				mesh_io_ready_func_t cb, void *user_data);
 typedef bool (*mesh_io_destroy_t)(struct mesh_io *io);
+typedef bool (*mesh_io_restart_t)(struct mesh_io *io);
 typedef bool (*mesh_io_caps_t)(struct mesh_io *io, struct mesh_io_caps *caps);
 typedef bool (*mesh_io_send_t)(struct mesh_io *io,
 					struct mesh_io_send_info *info,
@@ -37,6 +38,7 @@  typedef bool (*mesh_io_tx_cancel_t)(struct mesh_io *io, const uint8_t *pattern,
 struct mesh_io_api {
 	mesh_io_init_t		init;
 	mesh_io_destroy_t	destroy;
+	mesh_io_restart_t	restart;
 	mesh_io_caps_t		caps;
 	mesh_io_send_t		send;
 	mesh_io_register_t	reg;
diff --git a/mesh/mesh-io-generic.c b/mesh/mesh-io-generic.c
index 2efd32f12..36aebc44f 100644
--- a/mesh/mesh-io-generic.c
+++ b/mesh/mesh-io-generic.c
@@ -769,6 +769,26 @@  static bool find_active(const void *a, const void *b)
 	return false;
 }
 
+static bool dev_restart(struct mesh_io *io)
+{
+	struct bt_hci_cmd_le_set_scan_enable cmd;
+	struct mesh_io_private *pvt = io->pvt;
+
+	if (!pvt)
+		return false;
+
+	if (l_queue_isempty(pvt->rx_regs))
+		return true;
+
+	pvt->active = l_queue_find(pvt->rx_regs, find_active, NULL);
+	cmd.enable = 0x00;	/* Disable scanning */
+	cmd.filter_dup = 0x00;	/* Report duplicates */
+	bt_hci_send(pvt->hci, BT_HCI_CMD_LE_SET_SCAN_ENABLE,
+				&cmd, sizeof(cmd), scan_disable_rsp, pvt, NULL);
+
+	return true;
+}
+
 static bool recv_register(struct mesh_io *io, const uint8_t *filter,
 			uint8_t len, mesh_io_recv_func_t cb, void *user_data)
 {
@@ -845,6 +865,7 @@  static bool recv_deregister(struct mesh_io *io, const uint8_t *filter,
 const struct mesh_io_api mesh_io_generic = {
 	.init = dev_init,
 	.destroy = dev_destroy,
+	.restart = dev_restart,
 	.caps = dev_caps,
 	.send = send_tx,
 	.reg = recv_register,
diff --git a/mesh/mesh-io.c b/mesh/mesh-io.c
index c4eaecefd..3cf5b0d67 100644
--- a/mesh/mesh-io.c
+++ b/mesh/mesh-io.c
@@ -96,6 +96,14 @@  fail:
 	return NULL;
 }
 
+void mesh_io_restart(struct mesh_io *io)
+{
+	io = l_queue_find(io_list, match_by_io, io);
+
+	if (io && io->api)
+		io->api->restart(io);
+}
+
 void mesh_io_destroy(struct mesh_io *io)
 {
 	io = l_queue_remove_if(io_list, match_by_io, io);
diff --git a/mesh/mesh-io.h b/mesh/mesh-io.h
index fc0422020..2af713d2c 100644
--- a/mesh/mesh-io.h
+++ b/mesh/mesh-io.h
@@ -83,6 +83,7 @@  typedef void (*mesh_io_ready_func_t)(void *user_data, bool result);
 
 struct mesh_io *mesh_io_new(enum mesh_io_type type, void *opts,
 				mesh_io_ready_func_t cb, void *user_data);
+void mesh_io_restart(struct mesh_io *io);
 void mesh_io_destroy(struct mesh_io *io);
 
 bool mesh_io_get_caps(struct mesh_io *io, struct mesh_io_caps *caps);
diff --git a/mesh/mesh.c b/mesh/mesh.c
index 890a3aa8f..e47587f43 100644
--- a/mesh/mesh.c
+++ b/mesh/mesh.c
@@ -66,6 +66,7 @@  struct bt_mesh {
 	uint16_t req_index;
 	uint8_t friend_queue_sz;
 	uint8_t max_filters;
+	bool initialized;
 };
 
 struct join_data{
@@ -91,7 +92,8 @@  static struct bt_mesh mesh = {
 	.lpn_support = false,
 	.proxy_support = false,
 	.crpl = DEFAULT_CRPL,
-	.friend_queue_sz = DEFAULT_FRIEND_QUEUE_SZ
+	.friend_queue_sz = DEFAULT_FRIEND_QUEUE_SZ,
+	.initialized = false
 };
 
 /* We allow only one outstanding Join request */
@@ -168,9 +170,17 @@  static void io_ready_callback(void *user_data, bool result)
 {
 	struct mesh_init_request *req = user_data;
 
+	if (mesh.initialized) {
+		if (result)
+			mesh_io_restart(mesh.io);
+		return;
+	}
+
 	if (result)
 		node_attach_io_all(mesh.io);
 
+	mesh.initialized = true;
+
 	req->cb(req->user_data, result);
 
 	l_free(req);