Search Linux Wireless

[PATCH] rfkill: keep rfkill event compatibility with old userspace applications

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Old userspace applications (for example bluez version before c939747f543a),
that still use the original format for rfkill events (with 8 bytes size /
RFKILL_EVENT_SIZE_V1) and are not requesting any specific size but a large
one, are broken because they are checking the received size.

The reason is the new extended rfkill event format that is used by kernel, if
requested size is big enough.
Detailed operation of commented bluez versions, by means of strace output:
read(11, "\0\0\0\0\2\2\1\0\0", 32)      = 9
That is, as the new rfkill event size is 9, it will be rejected by commented
bluez versions (expected size 8).

In order to avoid this compatibility issue, we can try to adapt by checking
specific unusual requested sizes:
- bluez: 32
- gnome-settings-daemon: 1024
If this is the case, we will consider that we have to use the original size
(RFKILL_EVENT_SIZE_V1) and old applications will be able to work as ever.
For other values, we will follow the new behavior with extended events.
No other applications have been identified that behave in this way, so
reserved event sizes are defined.

Fixes: 71826654ce40 ("rfkill: revert back to old userspace API by default")
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@xxxxxxxxxx>
---
 include/uapi/linux/rfkill.h | 6 ++++++
 net/rfkill/core.c           | 8 +++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/rfkill.h b/include/uapi/linux/rfkill.h
index 9b77cfc42efa..821e304a1d8e 100644
--- a/include/uapi/linux/rfkill.h
+++ b/include/uapi/linux/rfkill.h
@@ -168,8 +168,14 @@ struct rfkill_event_ext {
  *    older kernel;
  * 3. treat reads that are as long as requested as acceptable, not
  *    checking against RFKILL_EVENT_SIZE_V1 or such.
+ * 4. in order to avoid compatibilities issues with older application
+ *    versions specifying unusual event size requests, those unusual
+ *    request event sizes will be considered reserved. If requested size
+ *    is reserved, the event size will be RFKILL_EVENT_SIZE_V1.
  */
 #define RFKILL_EVENT_SIZE_V1	sizeof(struct rfkill_event)
+#define RESERVED_RFKILL_EVENT_SIZE_1	32
+#define RESERVED_RFKILL_EVENT_SIZE_2	1024
 
 /* ioctl for turning off rfkill-input (if present) */
 #define RFKILL_IOC_MAGIC	'R'
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index b73a741a7923..494335d4f5f7 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -1231,7 +1231,13 @@ static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
 	ev = list_first_entry(&data->events, struct rfkill_int_event,
 				list);
 
-	sz = min_t(unsigned long, sizeof(ev->ev), count);
+	BUILD_BUG_ON(sizeof(ev->ev) == RESERVED_RFKILL_EVENT_SIZE_1 ||
+		sizeof(ev->ev) == RESERVED_RFKILL_EVENT_SIZE_2);
+	if (count == RESERVED_RFKILL_EVENT_SIZE_1 ||
+		count == RESERVED_RFKILL_EVENT_SIZE_2)
+		sz = RFKILL_EVENT_SIZE_V1;
+	else
+		sz = min_t(unsigned long, sizeof(ev->ev), count);
 	ret = sz;
 	if (copy_to_user(buf, &ev->ev, sz))
 		ret = -EFAULT;
-- 
2.27.0




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux