From 79cf74d870603939183760888ea1cf0ff787d6b1 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Tue, 12 May 2026 04:12:16 -0700 Subject: [PATCH] Bluetooth: hci_sock: write the full optval for getsockopt In hci_sock_getsockopt_old(), HCI_DATA_DIR and HCI_TIME_STAMP both store their value into a local int and then call put_user(opt, optval). Because optval is the function parameter typed char __user *, put_user sizes the write from sizeof(*optval), so only the low byte of the int is copied to userspace. The matching setsockopt path reads sizeof(int) via copy_safe_from_sockptr, so userspace passes a 4-byte buffer in both directions but previously got back only one initialized byte on the read side. Not sending this through 'net' tree given this bug is mostly invisble, given opt is 0/1, and the last byte is being properly copied. With this change, the upcoming translation to .getsockopt_iter becomes mechanical. FWIW: This behavior appeared in commit 1da177e4c3f4 ("Linux-2.6.12-rc2"). Signed-off-by: Breno Leitao Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/hci_sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 0290dea081f6..1823c06ba894 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -2088,7 +2088,7 @@ static int hci_sock_getsockopt_old(struct socket *sock, int level, int optname, else opt = 0; - if (put_user(opt, optval)) + if (put_user(opt, (int __user *)optval)) err = -EFAULT; break; @@ -2098,7 +2098,7 @@ static int hci_sock_getsockopt_old(struct socket *sock, int level, int optname, else opt = 0; - if (put_user(opt, optval)) + if (put_user(opt, (int __user *)optval)) err = -EFAULT; break;