All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] rfkill: Fix reading from rfkill socket
@ 2021-05-03 13:12 Benjamin Berg
  2021-05-03 13:45 ` bluez.test.bot
  2021-06-10 12:45 ` [PATCH] " Bastien Nocera
  0 siblings, 2 replies; 5+ messages in thread
From: Benjamin Berg @ 2021-05-03 13:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Benjamin Berg

From: Benjamin Berg <bberg@redhat.com>

The kernel will always send exactly one event, but the size of the
passed struct will depend on the length of the submitted read() and the
kernel version. i.e. the interface can be extended and we need to expect
for a read to be longer than expected if we ask for it.

Fix this by only requesting the needed length and explicitly check the
length against the V1 version of the structure to make the code a bit
more future proof in case the internal copy of the struct is updated to
contain new fields.
---
 src/rfkill.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/src/rfkill.c b/src/rfkill.c
index ec9fcdfdd..2099c5ac5 100644
--- a/src/rfkill.c
+++ b/src/rfkill.c
@@ -53,12 +53,12 @@ struct rfkill_event {
 	uint8_t  soft;
 	uint8_t  hard;
 };
+#define RFKILL_EVENT_SIZE_V1    8
 
 static gboolean rfkill_event(GIOChannel *chan,
 				GIOCondition cond, gpointer data)
 {
-	unsigned char buf[32];
-	struct rfkill_event *event = (void *) buf;
+	struct rfkill_event event = { 0 };
 	struct btd_adapter *adapter;
 	char sysname[PATH_MAX];
 	ssize_t len;
@@ -69,34 +69,32 @@ static gboolean rfkill_event(GIOChannel *chan,
 
 	fd = g_io_channel_unix_get_fd(chan);
 
-	memset(buf, 0, sizeof(buf));
-
-	len = read(fd, buf, sizeof(buf));
+	len = read(fd, &event, sizeof(event));
 	if (len < 0) {
 		if (errno == EAGAIN)
 			return TRUE;
 		return FALSE;
 	}
 
-	if (len != sizeof(struct rfkill_event))
+	if (len < RFKILL_EVENT_SIZE_V1)
 		return TRUE;
 
 	DBG("RFKILL event idx %u type %u op %u soft %u hard %u",
-					event->idx, event->type, event->op,
-						event->soft, event->hard);
+					event.idx, event.type, event.op,
+						event.soft, event.hard);
 
-	if (event->soft || event->hard)
+	if (event.soft || event.hard)
 		return TRUE;
 
-	if (event->op != RFKILL_OP_CHANGE)
+	if (event.op != RFKILL_OP_CHANGE)
 		return TRUE;
 
-	if (event->type != RFKILL_TYPE_BLUETOOTH &&
-					event->type != RFKILL_TYPE_ALL)
+	if (event.type != RFKILL_TYPE_BLUETOOTH &&
+					event.type != RFKILL_TYPE_ALL)
 		return TRUE;
 
 	snprintf(sysname, sizeof(sysname) - 1,
-			"/sys/class/rfkill/rfkill%u/name", event->idx);
+			"/sys/class/rfkill/rfkill%u/name", event.idx);
 
 	fd = open(sysname, O_RDONLY);
 	if (fd < 0)
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-06-23 22:35 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-03 13:12 [PATCH] rfkill: Fix reading from rfkill socket Benjamin Berg
2021-05-03 13:45 ` bluez.test.bot
2021-06-10 12:45 ` [PATCH] " Bastien Nocera
2021-06-10 12:51   ` Bastien Nocera
2021-06-23 22:35     ` Luiz Augusto von Dentz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.