)]}'
{
  "commit": "6911f19876fbf65116c61ae93a47e2316b41d5a4",
  "tree": "06f9acd4ca4919eb617f866d6b3d0da908418dfa",
  "parents": [
    "fa0ad6bc56675ed47f59b82616865a398565cbb7"
  ],
  "author": {
    "name": "Michael Bommarito",
    "email": "michael.bommarito@gmail.com",
    "time": "Sat May 02 12:43:03 2026 -0400"
  },
  "committer": {
    "name": "Luiz Augusto von Dentz",
    "email": "luiz.von.dentz@intel.com",
    "time": "Wed May 06 15:53:00 2026 -0400"
  },
  "message": "Bluetooth: HIDP: serialise l2cap_unregister_user via hidp_session_sem\n\nCommit dbf666e4fc9b (\"Bluetooth: HIDP: Fix possible UAF\") made\nhidp_session_remove() drop the L2CAP reference and set\nsession-\u003econn \u003d NULL once the session is considered removed, and\nadded a bare if (session-\u003econn) guard around the kthread-exit\nl2cap_unregister_user() call in hidp_session_thread().  The sibling\nioctl site in hidp_connection_del() still reads session-\u003econn\nunlocked and unguarded, and the kthread-exit guard itself is a\nlockless double-read.\n\nhidp_session_find() drops hidp_session_sem before returning, so\nhidp_session_remove() can null session-\u003econn between the lookup and\nthe call in hidp_connection_del().  Worse, since commit 752a6c9596dd\n(\"Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user\")\ntakes mutex_lock(\u0026conn-\u003elock) inside l2cap_unregister_user(), a\nstale non-NULL snapshot also UAFs on conn-\u003elock.  v1 only added an\nif (session-\u003econn) guard at the ioctl site, which doesn\u0027t address\neither race; Luiz suggested snapshotting session-\u003econn under the\nsem and clearing it before the call.\n\nTaking hidp_session_sem across l2cap_unregister_user() would be\nwrong: l2cap_conn_del() already establishes the lock order\n\n  conn-\u003elock -\u003e hidp_session_sem\n\nvia l2cap_unregister_all_users() -\u003e user-\u003eremove \u003d\u003d\nhidp_session_remove(), so taking hidp_session_sem before conn-\u003elock\nwould AB/BA deadlock.\n\nFactor a helper hidp_session_unregister_conn() that under\ndown_write(\u0026hidp_session_sem) snapshots session-\u003econn and clears\nthe member, then outside the sem calls l2cap_unregister_user() and\nl2cap_conn_put() on the snapshot.  Call it from both\nhidp_connection_del() and hidp_session_thread()\u0027s exit path.  At\nmost one consumer wins the write-sem; later callers observe\nsession-\u003econn \u003d\u003d NULL and skip the unregister and put, so the\nreference hidp_session_new() took via l2cap_conn_get() is consumed\nexactly once.  session_free() already tolerates a NULL session-\u003econn.\n\nFixes: dbf666e4fc9b (\"Bluetooth: HIDP: Fix possible UAF\")\nSuggested-by: Luiz Augusto von Dentz \u003cluiz.dentz@gmail.com\u003e\nLink: https://lore.kernel.org/all/20260422011437.176643-1-michael.bommarito@gmail.com/\nSigned-off-by: Michael Bommarito \u003cmichael.bommarito@gmail.com\u003e\nAssisted-by: Claude:claude-opus-4-7\nSigned-off-by: Luiz Augusto von Dentz \u003cluiz.von.dentz@intel.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "7bcf8c5ceaeedc837bdbcf562a9a9a2f30ebb2f3",
      "old_mode": 33188,
      "old_path": "net/bluetooth/hidp/core.c",
      "new_id": "976f91eeb745e4925f2c5c2da6c318eb0bfa308d",
      "new_mode": 33188,
      "new_path": "net/bluetooth/hidp/core.c"
    }
  ]
}
