From: Breno Leitao Date: Tue, 12 May 2026 11:12:20 +0000 (-0700) Subject: Bluetooth: L2CAP: convert to getsockopt_iter X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bf01627cc04b70c04a6d68eda06f836fed3078bc;p=thirdparty%2Flinux.git Bluetooth: L2CAP: convert to getsockopt_iter Convert L2CAP socket's getsockopt implementation to use the new getsockopt_iter callback with sockopt_t. Key changes: - Replace (char __user *optval, int __user *optlen) with sockopt_t *sopt - Use sopt->optlen for buffer length (input) - Use copy_to_iter() instead of put_user()/copy_to_user() - Add linux/uio.h for copy_to_iter() The sockopt_t parameter is named sopt rather than opt to avoid collision with the existing local u32 opt used by L2CAP_LM. The same naming is reused for the new u32 helper in l2cap_sock_getsockopt(), with mtu and mval helpers covering the u16 and u8 cases. Signed-off-by: Breno Leitao Signed-off-by: Luiz Augusto von Dentz --- diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index c138aa4ae266..025329636353 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -438,7 +439,7 @@ static int l2cap_get_mode(struct l2cap_chan *chan) } static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, - char __user *optval, int __user *optlen) + sockopt_t *sopt) { struct sock *sk = sock->sk; struct l2cap_chan *chan = l2cap_pi(sk)->chan; @@ -450,8 +451,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, BT_DBG("sk %p", sk); - if (get_user(len, optlen)) - return -EFAULT; + len = sopt->optlen; lock_sock(sk); @@ -493,7 +493,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, BT_DBG("mode 0x%2.2x", chan->mode); len = min(len, sizeof(opts)); - if (copy_to_user(optval, (char *) &opts, len)) + if (copy_to_iter(&opts, len, &sopt->iter_out) != len) err = -EFAULT; break; @@ -525,7 +525,8 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) opt |= L2CAP_LM_RELIABLE; - if (put_user(opt, (u32 __user *) optval)) + if (copy_to_iter(&opt, sizeof(opt), &sopt->iter_out) != + sizeof(opt)) err = -EFAULT; break; @@ -543,7 +544,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, memcpy(cinfo.dev_class, chan->conn->hcon->dev_class, 3); len = min(len, sizeof(cinfo)); - if (copy_to_user(optval, (char *) &cinfo, len)) + if (copy_to_iter(&cinfo, len, &sopt->iter_out) != len) err = -EFAULT; break; @@ -558,25 +559,26 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, } static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, - char __user *optval, int __user *optlen) + sockopt_t *sopt) { struct sock *sk = sock->sk; struct l2cap_chan *chan = l2cap_pi(sk)->chan; struct bt_security sec; struct bt_power pwr; - u32 phys; int len, mode, err = 0; + u32 opt; + u16 mtu; + u8 mval; BT_DBG("sk %p", sk); if (level == SOL_L2CAP) - return l2cap_sock_getsockopt_old(sock, optname, optval, optlen); + return l2cap_sock_getsockopt_old(sock, optname, sopt); if (level != SOL_BLUETOOTH) return -ENOPROTOOPT; - if (get_user(len, optlen)) - return -EFAULT; + len = sopt->optlen; lock_sock(sk); @@ -600,7 +602,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, } len = min_t(unsigned int, len, sizeof(sec)); - if (copy_to_user(optval, (char *) &sec, len)) + if (copy_to_iter(&sec, len, &sopt->iter_out) != len) err = -EFAULT; break; @@ -611,15 +613,17 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, break; } - if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags), - (u32 __user *) optval)) + opt = test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); + if (copy_to_iter(&opt, sizeof(opt), &sopt->iter_out) != + sizeof(opt)) err = -EFAULT; break; case BT_FLUSHABLE: - if (put_user(test_bit(FLAG_FLUSHABLE, &chan->flags), - (u32 __user *) optval)) + opt = test_bit(FLAG_FLUSHABLE, &chan->flags); + if (copy_to_iter(&opt, sizeof(opt), &sopt->iter_out) != + sizeof(opt)) err = -EFAULT; break; @@ -634,13 +638,15 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, pwr.force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags); len = min_t(unsigned int, len, sizeof(pwr)); - if (copy_to_user(optval, (char *) &pwr, len)) + if (copy_to_iter(&pwr, len, &sopt->iter_out) != len) err = -EFAULT; break; case BT_CHANNEL_POLICY: - if (put_user(chan->chan_policy, (u32 __user *) optval)) + opt = chan->chan_policy; + if (copy_to_iter(&opt, sizeof(opt), &sopt->iter_out) != + sizeof(opt)) err = -EFAULT; break; @@ -655,7 +661,9 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, break; } - if (put_user(chan->omtu, (u16 __user *) optval)) + mtu = chan->omtu; + if (copy_to_iter(&mtu, sizeof(mtu), &sopt->iter_out) != + sizeof(mtu)) err = -EFAULT; break; @@ -665,7 +673,9 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, break; } - if (put_user(chan->imtu, (u16 __user *) optval)) + mtu = chan->imtu; + if (copy_to_iter(&mtu, sizeof(mtu), &sopt->iter_out) != + sizeof(mtu)) err = -EFAULT; break; @@ -675,9 +685,10 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, break; } - phys = hci_conn_get_phy(chan->conn->hcon); + opt = hci_conn_get_phy(chan->conn->hcon); - if (put_user(phys, (u32 __user *) optval)) + if (copy_to_iter(&opt, sizeof(opt), &sopt->iter_out) != + sizeof(opt)) err = -EFAULT; break; @@ -698,7 +709,9 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, break; } - if (put_user(mode, (u8 __user *) optval)) + mval = mode; + if (copy_to_iter(&mval, sizeof(mval), &sopt->iter_out) != + sizeof(mval)) err = -EFAULT; break; @@ -2039,7 +2052,7 @@ static const struct proto_ops l2cap_sock_ops = { .socketpair = sock_no_socketpair, .shutdown = l2cap_sock_shutdown, .setsockopt = l2cap_sock_setsockopt, - .getsockopt = l2cap_sock_getsockopt + .getsockopt_iter = l2cap_sock_getsockopt }; static const struct net_proto_family l2cap_sock_family_ops = {