Message ID | 20231204070243.GA16386@ubuntu (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Bluetooth: af_bluetooth: Fix Use-After-Free in bt_sock_recvmsg | expand |
Context | Check | Description |
---|---|---|
tedd_an/pre-ci_am | success | Success |
tedd_an/CheckPatch | success | CheckPatch PASS |
tedd_an/GitLint | success | Gitlint PASS |
tedd_an/SubjectPrefix | success | Gitlint PASS |
tedd_an/BuildKernel | success | BuildKernel PASS |
tedd_an/CheckAllWarning | success | CheckAllWarning PASS |
tedd_an/CheckSparse | warning | CheckSparse WARNING net/bluetooth/af_bluetooth.c:223:25: warning: context imbalance in 'bt_accept_enqueue' - different lock contexts for basic block |
tedd_an/CheckSmatch | success | CheckSparse PASS |
tedd_an/BuildKernel32 | success | BuildKernel32 PASS |
tedd_an/TestRunnerSetup | success | TestRunnerSetup PASS |
tedd_an/TestRunner_l2cap-tester | success | TestRunner PASS |
tedd_an/TestRunner_iso-tester | success | TestRunner PASS |
tedd_an/TestRunner_bnep-tester | success | TestRunner PASS |
tedd_an/TestRunner_mgmt-tester | success | TestRunner PASS |
tedd_an/TestRunner_rfcomm-tester | success | TestRunner PASS |
tedd_an/TestRunner_sco-tester | success | TestRunner PASS |
tedd_an/TestRunner_ioctl-tester | success | TestRunner PASS |
tedd_an/TestRunner_mesh-tester | success | TestRunner PASS |
tedd_an/TestRunner_smp-tester | success | TestRunner PASS |
tedd_an/TestRunner_userchan-tester | success | TestRunner PASS |
tedd_an/IncrementalBuild | success | Incremental Build PASS |
This is automated email and please do not reply to this email! Dear submitter, Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series: PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=806468 ---Test result--- Test Summary: CheckPatch PASS 0.48 seconds GitLint PASS 0.22 seconds SubjectPrefix PASS 0.07 seconds BuildKernel PASS 28.01 seconds CheckAllWarning PASS 31.13 seconds CheckSparse WARNING 36.27 seconds CheckSmatch PASS 100.31 seconds BuildKernel32 PASS 27.37 seconds TestRunnerSetup PASS 423.62 seconds TestRunner_l2cap-tester PASS 23.57 seconds TestRunner_iso-tester PASS 46.96 seconds TestRunner_bnep-tester PASS 6.88 seconds TestRunner_mgmt-tester PASS 164.14 seconds TestRunner_rfcomm-tester PASS 11.08 seconds TestRunner_sco-tester PASS 14.63 seconds TestRunner_ioctl-tester PASS 12.31 seconds TestRunner_mesh-tester PASS 9.04 seconds TestRunner_smp-tester PASS 10.05 seconds TestRunner_userchan-tester PASS 7.49 seconds IncrementalBuild PASS 26.74 seconds Details ############################## Test: CheckSparse - WARNING Desc: Run sparse tool with linux kernel Output: net/bluetooth/af_bluetooth.c:223:25: warning: context imbalance in 'bt_accept_enqueue' - different lock contexts for basic block --- Regards, Linux Bluetooth
Hi Kim, On Mon, Dec 4, 2023 at 2:02 AM Hyunwoo Kim <v4bel@theori.io> wrote: > > This can cause a race with bt_sock_ioctl() because > bt_sock_recvmsg() gets the skb from sk->sk_receive_queue > and then frees it without holding lock_sock. > A use-after-free for a skb occurs with the following flow. > ``` > bt_sock_recvmsg() -> skb_recv_datagram() -> skb_free_datagram() > bt_sock_ioctl() -> skb_peek() > ``` > Add lock_sock to bt_sock_recvmsg() to fix this issue. > > Signed-off-by: Hyunwoo Kim <v4bel@theori.io> > --- > net/bluetooth/af_bluetooth.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c > index 336a76165454..9def13ac816e 100644 > --- a/net/bluetooth/af_bluetooth.c > +++ b/net/bluetooth/af_bluetooth.c > @@ -309,11 +309,16 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, > if (flags & MSG_OOB) > return -EOPNOTSUPP; > > + lock_sock(sk); > + > skb = skb_recv_datagram(sk, flags, &err); > if (!skb) { > - if (sk->sk_shutdown & RCV_SHUTDOWN) > + if (sk->sk_shutdown & RCV_SHUTDOWN) { > + release_sock(sk); We could just reset the with err = 0 then we don't need to duplicate the release_sock line. > return 0; > + } > > + release_sock(sk); > return err; > } > > @@ -343,6 +348,8 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, > > skb_free_datagram(sk, skb); > > + release_sock(sk); > + > if (flags & MSG_TRUNC) > copied = skblen; > > -- > 2.25.1 >
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 336a76165454..9def13ac816e 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -309,11 +309,16 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, if (flags & MSG_OOB) return -EOPNOTSUPP; + lock_sock(sk); + skb = skb_recv_datagram(sk, flags, &err); if (!skb) { - if (sk->sk_shutdown & RCV_SHUTDOWN) + if (sk->sk_shutdown & RCV_SHUTDOWN) { + release_sock(sk); return 0; + } + release_sock(sk); return err; } @@ -343,6 +348,8 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, skb_free_datagram(sk, skb); + release_sock(sk); + if (flags & MSG_TRUNC) copied = skblen;
This can cause a race with bt_sock_ioctl() because bt_sock_recvmsg() gets the skb from sk->sk_receive_queue and then frees it without holding lock_sock. A use-after-free for a skb occurs with the following flow. ``` bt_sock_recvmsg() -> skb_recv_datagram() -> skb_free_datagram() bt_sock_ioctl() -> skb_peek() ``` Add lock_sock to bt_sock_recvmsg() to fix this issue. Signed-off-by: Hyunwoo Kim <v4bel@theori.io> --- net/bluetooth/af_bluetooth.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)