)]}'
{
  "commit": "2f3afcc47c3c702ba7a556b3ee8567f2b95ef5fd",
  "tree": "a40b9d55021f2878feeb348ffbd9505d44cd66f0",
  "parents": [
    "49d6c6c88b9d6f495f45dcf622f86de65ade5eaa"
  ],
  "author": {
    "name": "Cen Zhang",
    "email": "zzzccc427@gmail.com",
    "time": "Thu Oct 29 11:19:11 2026 +0800"
  },
  "committer": {
    "name": "Steffen Klassert",
    "email": "steffen.klassert@secunet.com",
    "time": "Thu Nov 05 10:18:15 2026 +0100"
  },
  "message": "xfrm: keep the mode module pinned until destroy_state returns\n\nAn IPTFS state keeps its mode module referenced while mode_data exists.\nHowever, iptfs_destroy_state() drops that reference before returning to\nxfrm_state_gc_destroy(), which has no reference covering the callback\u0027s\nreturn path.\n\nWith CONFIG_XFRM_IPTFS\u003dm and module unloading enabled, deleting the last\nIPTFS SA can overlap with ordinary module removal in this order:\n\n  XFRM GC worker                      rmmod xfrm_iptfs\n  iptfs_destroy_state()\n    free mode_data\n    module_put(owner)\n    \u003cpreempted\u003e\n                                      delete_module()\n                                        xfrm_iptfs_fini()\n                                          unregister mode callbacks\n                                        free_module()\n    resume in freed module text\n\nAn unload started after the put can finish before the callback resumes.\nGC invokes the callback outside an RCU read-side critical section, after\nits grace period. The RCU waits in mode unregistration and module\nfreeing therefore do not protect the callback. The GC mutex only\nserializes GC with device state flushes. Resuming the callback can cause\nan instruction-fetch fault in the freed module text.\n\nThe Oops below was observed on an earlier kernel with scheduling probes\nholding the worker in module_put() after the decrement until ordinary\nrmmod completed. The fixture created and deleted the SA over\nNETLINK_XFRM.\n\nTake an additional reference to the already pinned owner before calling\ndestroy_state(), and release it in XFRM core after the callback returns.\nCache the owner before the call so releasing the extra reference does\nnot need to access the callback table after the callback has finished.\n\nOops report as below:\n    BUG: unable to handle page fault for address: ffffffffc0407455\n    #PF: supervisor instruction fetch in kernel mode\n    #PF: error_code(0x0010) - not-present page\n    PGD 80a9067 P4D 80a9067 PUD 80ab067 PMD 0\n    Oops: Oops: 0010 [#1] SMP KASAN NOPTI\n    CPU: 3 UID: 0 PID: 53 Comm: kworker/3:1 Not tainted 7.2.0-rc5-pmb-xfrm-functional-v1+ #11 PREEMPT(lazy)\n    Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014\n    Workqueue: events xfrm_state_gc_task\n    RIP: 0010:0xffffffffc0407455\n    Code: Unable to access opcode bytes at 0xffffffffc040742b.\n    RSP: 0018:ffff8881013e7aa0 EFLAGS: 00010282\n    RAX: 0000000000000000 RBX: ffffffffc02199c0 RCX: ffffffff816fc84e\n    RDX: ffff8881013c0000 RSI: 0000000000000000 RDI: ffffffff86338344\n    RBP: ffff8881013e7ba8 R08: 0000000000000001 R09: 0000000000000001\n    R10: ffffffff893e0257 R11: ffff8881013c0000 R12: ffff888107e9ec00\n    R13: ffff888102b07980 R14: ffff888107412ec0 R15: ffff8881013e7ae0\n    FS:  0000000000000000(0000) GS:ffff8881fd929000(0000) knlGS:0000000000000000\n    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033\n    CR2: ffffffffc040742b CR3: 00000000080a6006 CR4: 0000000000770ef0\n    PKRU: 55555554\n    Call Trace:\n     \u003cTASK\u003e\n     ? pmbd_gate_maybe+0x47/0x60\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? lock_is_held_type+0x8f/0x100\n     xfrm_state_gc_task+0x17e/0x790\n     ? lock_acquire+0x17b/0x2f0\n     ? __pfx_xfrm_state_gc_task+0x10/0x10\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? lock_release+0xc8/0x280\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     process_one_work+0x908/0x19c0\n     ? __pfx_process_one_work+0x10/0x10\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? lock_is_held_type+0x8f/0x100\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     worker_thread+0x65c/0xe40\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? __kthread_parkme+0x175/0x220\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? __pfx_worker_thread+0x10/0x10\n     kthread+0x34f/0x460\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? __pfx_kthread+0x10/0x10\n     ret_from_fork+0x659/0x940\n     ? __pfx_ret_from_fork+0x10/0x10\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? __switch_to+0x74f/0xf80\n     ? __pfx_kthread+0x10/0x10\n     ret_from_fork_asm+0x1a/0x30\n     \u003c/TASK\u003e\n    Modules linked in: [last unloaded: xfrm_iptfs]\n    CR2: ffffffffc0407455\n    ---[ end trace 0000000000000000 ]---\n    RIP: 0010:0xffffffffc0407455\n    Code: Unable to access opcode bytes at 0xffffffffc040742b.\n    RSP: 0018:ffff8881013e7aa0 EFLAGS: 00010282\n    RAX: 0000000000000000 RBX: ffffffffc02199c0 RCX: ffffffff816fc84e\n    RDX: ffff8881013c0000 RSI: 0000000000000000 RDI: ffffffff86338344\n    RBP: ffff8881013e7ba8 R08: 0000000000000001 R09: 0000000000000001\n    R10: ffffffff893e0257 R11: ffff8881013c0000 R12: ffff888107e9ec00\n    R13: ffff888102b07980 R14: ffff888107412ec0 R15: ffff8881013e7ae0\n    FS:  0000000000000000(0000) GS:ffff8881fd929000(0000) knlGS:0000000000000000\n    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033\n    CR2: ffffffffc040742b CR3: 00000000080a6006 CR4: 0000000000770ef0\n    PKRU: 55555554\n    Kernel panic - not syncing: Fatal exception\n    Kernel Offset: disabled\n\nFixes: 4b3faf610cc6 (\"xfrm: iptfs: add new iptfs xfrm mode impl\")\nSigned-off-by: Cen Zhang \u003czzzccc427@gmail.com\u003e\nAssisted-by: LLM\nSigned-off-by: Steffen Klassert \u003csteffen.klassert@secunet.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "0555e5d796ede417ccaca21c998a0434f7146a21",
      "old_mode": 33188,
      "old_path": "net/xfrm/xfrm_state.c",
      "new_id": "45a52771796b9c1ee5c5cb7225018f1507cec3a9",
      "new_mode": 33188,
      "new_path": "net/xfrm/xfrm_state.c"
    }
  ]
}
