summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/sco.c
diff options
context:
space:
mode:
authorMichal Luczaj <mhal@rbox.co>2024-11-19 14:31:40 +0100
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2024-12-11 17:54:57 +0100
commit3e643e4efa1e87432204b62f9cfdea3b2508c830 (patch)
tree439d381352145d854ba9632f0f93e41455527a90 /net/bluetooth/sco.c
parentnet: renesas: rswitch: handle stop vs interrupt race (diff)
downloadlinux-3e643e4efa1e87432204b62f9cfdea3b2508c830.tar.xz
linux-3e643e4efa1e87432204b62f9cfdea3b2508c830.zip
Bluetooth: Improve setsockopt() handling of malformed user input
The bt_copy_from_sockptr() return value is being misinterpreted by most users: a non-zero result is mistakenly assumed to represent an error code, but actually indicates the number of bytes that could not be copied. Remove bt_copy_from_sockptr() and adapt callers to use copy_safe_from_sockptr(). For sco_sock_setsockopt() (case BT_CODEC) use copy_struct_from_sockptr() to scrub parts of uninitialized buffer. Opportunistically, rename `len` to `optlen` in hci_sock_setsockopt_old() and hci_sock_setsockopt(). Fixes: 51eda36d33e4 ("Bluetooth: SCO: Fix not validating setsockopt user input") Fixes: a97de7bff13b ("Bluetooth: RFCOMM: Fix not validating setsockopt user input") Fixes: 4f3951242ace ("Bluetooth: L2CAP: Fix not validating setsockopt user input") Fixes: 9e8742cdfc4b ("Bluetooth: ISO: Fix not validating setsockopt user input") Fixes: b2186061d604 ("Bluetooth: hci_sock: Fix not validating setsockopt user input") Reviewed-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Reviewed-by: David Wei <dw@davidwei.uk> Signed-off-by: Michal Luczaj <mhal@rbox.co> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to '')
-rw-r--r--net/bluetooth/sco.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 78f7bca24487..7eb8d3e04ec4 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -896,7 +896,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
break;
}
- err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
+ err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
if (err)
break;
@@ -915,8 +915,8 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
voice.setting = sco_pi(sk)->setting;
- err = bt_copy_from_sockptr(&voice, sizeof(voice), optval,
- optlen);
+ err = copy_safe_from_sockptr(&voice, sizeof(voice), optval,
+ optlen);
if (err)
break;
@@ -941,7 +941,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
break;
case BT_PKT_STATUS:
- err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
+ err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
if (err)
break;
@@ -984,7 +984,8 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
break;
}
- err = bt_copy_from_sockptr(buffer, optlen, optval, optlen);
+ err = copy_struct_from_sockptr(buffer, sizeof(buffer), optval,
+ optlen);
if (err) {
hci_dev_put(hdev);
break;