On 2024-11-14 18:50, Luiz Augusto von Dentz wrote: > Hi David, > > On Thu, Nov 14, 2024 at 9:30 PM David Wei <dw@xxxxxxxxxxx> wrote: >> >> On 2024-11-14 18:15, Luiz Augusto von Dentz wrote: >>> Hi David, >>> >>> On Thu, Nov 14, 2024 at 7:42 PM David Wei <dw@xxxxxxxxxxx> wrote: >>>> >>>> On 2024-11-14 15:27, Michal Luczaj wrote: >>>>> 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") >>>>> Signed-off-by: Michal Luczaj <mhal@xxxxxxx> >>>>> --- >>>>> include/net/bluetooth/bluetooth.h | 9 --------- >>>>> net/bluetooth/hci_sock.c | 14 +++++++------- >>>>> net/bluetooth/iso.c | 10 +++++----- >>>>> net/bluetooth/l2cap_sock.c | 20 +++++++++++--------- >>>>> net/bluetooth/rfcomm/sock.c | 9 ++++----- >>>>> net/bluetooth/sco.c | 11 ++++++----- >>>>> 6 files changed, 33 insertions(+), 40 deletions(-) >>>>> >>>> ... >>>>> diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c >>>>> index f48250e3f2e103c75d5937e1608e43c123aa3297..1001fb4cc21c0ecc7bcdd3ea9041770ede4f27b8 100644 >>>>> --- a/net/bluetooth/rfcomm/sock.c >>>>> +++ b/net/bluetooth/rfcomm/sock.c >>>>> @@ -629,10 +629,9 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, >>>>> >>>>> switch (optname) { >>>>> case RFCOMM_LM: >>>>> - if (bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen)) { >>>>> - err = -EFAULT; >>>>> + err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen); >>>>> + if (err) >>>>> break; >>>>> - } >>>> >>>> This will return a positive integer if copy_safe_from_sockptr() fails. >>> >>> What are you talking about copy_safe_from_sockptr never returns a >>> positive value: >>> >>> * Returns: >>> * * -EINVAL: @optlen < @ksize >>> * * -EFAULT: access to userspace failed. >>> * * 0 : @ksize bytes were copied >> >> Isn't this what this series is about? copy_from_sockptr() returns 0 on >> success, or a positive integer for number of bytes NOT copied on error. >> Patch 4 even updates the docs for copy_from_sockptr(). >> >> copy_safe_from_sockptr() >> -> copy_from_sockptr() >> -> copy_from_sockptr_offset() >> -> memcpy() for kernel to kernel OR >> -> copy_from_user() otherwise > > Well except the safe version does check what would otherwise cause a > positive return by the likes of copy_from_user and returns -EINVAL > instead, otherwise the documentation of copy_safe_from_sockptr is just > wrong and shall state that it could return positive as well but I > guess that would just make it as inconvenient so we might as well > detect when a positive value would be returned just return -EFAULT > instead. Yes it checks and returns EINVAL, but not EFAULT which is what my comment on the original patch is about. Most of the calls to bt_copy_from_sockptr() that Michal replaced with copy_safe_from_sockptr() remain incorrect because it is assumed that EFAULT is returned. Only rfcomm_sock_setsockopt_old() was vaguely doing the right thing and the patch changed it back to the incorrect pattern: err = copy_safe_from_sockptr(...); if (err) break; But I do agree that making copy_safe_from_sockptr() do the right thing and EFAULT will be easier and prevent future problems given that copy_from_sockptr() is meant to be deprecated anyhow. > >> And copy_from_user() follows the same 0 for success or N > 0 for >> failure. It does not EFAULT on its own AFAIK. >> >> The docs for copy_safe_from_sockptr() that you've linked contains the >> exact misunderstanding that Michal is correcting. >> >>> >>>> Shouldn't this be: >>>> >>>> err = -EFAULT; >>>> if (copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen)) >>>> break; >>> >>> >>> > > >