From 233c3f2ce017fb4a6ea0a4a243c0b984e45ffa1e Mon Sep 17 00:00:00 2001 From: Tedd Ho-Jeong An Date: Wed, 4 Nov 2020 21:09:48 -0800 Subject: [PATCH 1/6] workflow: Add workflow files for ci This patch adds workflow files for ci: [sync.yml] - The workflow file for scheduled work - Sync the repo with upstream repo and rebase the workflow branch - Review the patches in the patchwork and creates the PR if needed [ci.yml] - The workflow file for CI tasks - Run CI tests when PR is created Signed-off-by: Tedd Ho-Jeong An --- .github/workflows/ci.yml | 25 ++++++++++++++++++++++ .github/workflows/sync.yml | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/sync.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000000..3a2c45c37553c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,25 @@ +name: CI + +on: [pull_request] + +jobs: + ci: + runs-on: ubuntu-latest + name: CI for Pull Request + steps: + - name: Checkout the source code + uses: actions/checkout@v3 + with: + path: src/src + + - name: CI + uses: tedd-an/bzcafe@main + with: + task: ci + base_folder: src + space: kernel + github_token: ${{ secrets.GITHUB_TOKEN }} + email_token: ${{ secrets.EMAIL_TOKEN }} + patchwork_token: ${{ secrets.PATCHWORK_TOKEN }} + patchwork_user: ${{ secrets.PATCHWORK_USER }} + diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml new file mode 100644 index 0000000000000..3883d55a23267 --- /dev/null +++ b/.github/workflows/sync.yml @@ -0,0 +1,43 @@ +name: Sync + +on: + schedule: + - cron: "*/30 * * * *" + +jobs: + sync_repo: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: master + + - name: Sync Repo + uses: tedd-an/bzcafe@main + with: + task: sync + upstream_repo: 'https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git' + github_token: ${{ secrets.GITHUB_TOKEN }} + + - name: Cleanup PR + uses: tedd-an/bzcafe@main + with: + task: cleanup + github_token: ${{ secrets.ACTION_TOKEN }} + + sync_patchwork: + needs: sync_repo + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Sync Patchwork + uses: tedd-an/bzcafe@main + with: + task: patchwork + space: kernel + github_token: ${{ secrets.ACTION_TOKEN }} + email_token: ${{ secrets.EMAIL_TOKEN }} + patchwork_token: ${{ secrets.PATCHWORK_TOKEN }} + patchwork_user: ${{ secrets.PATCHWORK_USER }} + From e8329bdf76f9a99c012ff40a4fa246f2801e25a6 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 9 Apr 2026 12:57:28 -0400 Subject: [PATCH 2/6] workflows: Make use bluez/action-ci action This replaces the bzcafe action with bluez/action-ci so we can maintain everything in the github bluez organization Signed-off-by: Luiz Augusto von Dentz --- .github/workflows/ci.yml | 2 +- .github/workflows/sync.yml | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a2c45c37553c..58bd27096c3cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: path: src/src - name: CI - uses: tedd-an/bzcafe@main + uses: bluez/action-ci@main with: task: ci base_folder: src diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index 3883d55a23267..6fb956309caa0 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -13,14 +13,14 @@ jobs: ref: master - name: Sync Repo - uses: tedd-an/bzcafe@main + uses: bluez/action-ci@main with: task: sync upstream_repo: 'https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git' github_token: ${{ secrets.GITHUB_TOKEN }} - name: Cleanup PR - uses: tedd-an/bzcafe@main + uses: bluez/action-ci@main with: task: cleanup github_token: ${{ secrets.ACTION_TOKEN }} @@ -32,7 +32,7 @@ jobs: - uses: actions/checkout@v3 - name: Sync Patchwork - uses: tedd-an/bzcafe@main + uses: bluez/action-ci@main with: task: patchwork space: kernel @@ -40,4 +40,3 @@ jobs: email_token: ${{ secrets.EMAIL_TOKEN }} patchwork_token: ${{ secrets.PATCHWORK_TOKEN }} patchwork_user: ${{ secrets.PATCHWORK_USER }} - From 21607feeca15674ffe82e26e09d885719eac6449 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 9 Apr 2026 13:18:58 -0400 Subject: [PATCH 3/6] workflow/sync: Attempt to sync every 5 minutes This attempts to sync every 5 minutes instead of 30. Signed-off-by: Luiz Augusto von Dentz --- .github/workflows/sync.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index 6fb956309caa0..92164bde28cef 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -2,7 +2,7 @@ name: Sync on: schedule: - - cron: "*/30 * * * *" + - cron: "*/5 * * * *" jobs: sync_repo: From cc49aeea99315dc27e2ec23331084d3dfcf529f3 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 9 Apr 2026 15:21:22 -0400 Subject: [PATCH 4/6] workflow/sync: Set workflow to use worflow branch bluez/action-ci uses master as default branch for workflow which is incorrect for kernel Signed-off-by: Luiz Augusto von Dentz --- .github/workflows/sync.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index 92164bde28cef..5e95af92ab1ab 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -16,6 +16,7 @@ jobs: uses: bluez/action-ci@main with: task: sync + workflow: workflow upstream_repo: 'https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git' github_token: ${{ secrets.GITHUB_TOKEN }} @@ -35,6 +36,7 @@ jobs: uses: bluez/action-ci@main with: task: patchwork + workflow: workflow space: kernel github_token: ${{ secrets.ACTION_TOKEN }} email_token: ${{ secrets.EMAIL_TOKEN }} From b22743727efce194435bb91a3a45cc67cca238bf Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 13 Apr 2026 16:41:33 -0400 Subject: [PATCH 5/6] workflow/ci: Add checks:write permission and explicit reopened trigger The CI action now creates individual GitHub Check Runs per test, which requires 'checks: write' permission on the GITHUB_TOKEN. Also make the pull_request trigger types explicit to include 'reopened', allowing CI to be retriggered by closing and reopening a PR. --- .github/workflows/ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58bd27096c3cf..60d318f805ff1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,12 @@ name: CI -on: [pull_request] +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + checks: write + pull-requests: write jobs: ci: From 0d0a5759bef62d46c3b7495f46119b364d007df1 Mon Sep 17 00:00:00 2001 From: Siwei Zhang Date: Wed, 20 May 2026 12:38:17 -0400 Subject: [PATCH 6/6] Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_sock_cleanup_listen() l2cap_sock_cleanup_listen() calls l2cap_chan_close() without holding conn->lock. A concurrent task iterating conn->chan_l under conn->lock can access a channel that has been removed from the list and freed. That can result in a slab-use-after-free. Split cleanup into two phases. Drain the accept queue under the parent's sk_lock onto a local list, taking a sock reference on each child so it survives the lock drop. Then release the parent and close every drained child under conn->lock + chan_lock, using l2cap_chan_hold_unless_zero()/l2cap_conn_hold_unless_zero() to cope with a teardown that has already started, and skipping any chan whose ->data has been cleared. Reacquire the parent's sk_lock at the end so the caller's contract is preserved. Noted that commit ab4eedb790ca ("Bluetooth: L2CAP: Fix corrupted list in hci_chan_del") renamed chan_lock to lock in l2cap_conn. Fixes: 3df91ea20e74 ("Bluetooth: Revert to mutexes from RCU list") Cc: stable@kernel.org Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Siwei Zhang --- net/bluetooth/l2cap_sock.c | 57 ++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index dede550d60319..961a96628640e 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1484,27 +1484,68 @@ static int l2cap_sock_release(struct socket *sock) static void l2cap_sock_cleanup_listen(struct sock *parent) { struct sock *sk; + struct bt_sock *bs, *tmp; + LIST_HEAD(killable); BT_DBG("parent %p state %s", parent, state_to_string(parent->sk_state)); - /* Close not yet accepted channels */ + /* Drain unaccepted children to a local list, pinning each so it + * survives the parent lock-drop below. + */ while ((sk = bt_accept_dequeue(parent, NULL))) { - struct l2cap_chan *chan = l2cap_pi(sk)->chan; + sock_hold(sk); + list_add_tail(&bt_sk(sk)->accept_q, &killable); + } - BT_DBG("child chan %p state %s", chan, - state_to_string(chan->state)); + /* l2cap_chan_close() must run under conn->lock, but the rx path + * (l2cap_sock_new_connection_cb) takes conn->lock then lock_sock(parent), + * so parent must be released before we close. Draining the queue + * first means a concurrent cleanup_listen() on the same parent finds + * it empty and is a no-op. + */ + release_sock(parent); + + list_for_each_entry_safe(bs, tmp, &killable, accept_q) { + struct l2cap_chan *chan; + struct l2cap_conn *conn; + + sk = (struct sock *)bs; + list_del_init(&bs->accept_q); + + chan = l2cap_chan_hold_unless_zero(l2cap_pi(sk)->chan); + if (!chan) { + sock_put(sk); + continue; + } - l2cap_chan_hold(chan); + l2cap_chan_lock(chan); + conn = l2cap_conn_hold_unless_zero(chan->conn); + l2cap_chan_unlock(chan); + + if (conn) + mutex_lock(&conn->lock); l2cap_chan_lock(chan); - __clear_chan_timer(chan); - l2cap_chan_close(chan, ECONNRESET); - l2cap_sock_kill(sk); + BT_DBG("child chan %p state %s", chan, + state_to_string(chan->state)); + + if (chan->data) { + __clear_chan_timer(chan); + l2cap_chan_close(chan, ECONNRESET); + l2cap_sock_kill(sk); + } l2cap_chan_unlock(chan); + if (conn) { + mutex_unlock(&conn->lock); + l2cap_conn_put(conn); + } l2cap_chan_put(chan); + sock_put(sk); } + + lock_sock_nested(parent, L2CAP_NESTING_PARENT); } static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)