KASAN: slab-out-of-bounds Read in write_tag_3_packet

Status: upstream: reported C repro on 2026/11/05 11:22
Subsystems: ecryptfs
Labels: prio:normal
[Documentation on labels]
Reported-by: syzbot+2e8c4ecc07730b29ae27@syzkaller.appspotmail.com
First crash: 1d08h, last: 1d08h
✨ AI-generated root cause summary:

In eCryptfs, ecryptfs_verify_auth_tok_from_key() and ecryptfs_get_key_payload_data() cast the data buffer of a key's payload (struct user_key_payload or struct encrypted_key_payload) to struct ecryptfs_auth_tok without validating that the key payload length (datalen) is at least sizeof(struct ecryptfs_auth_tok) (740 bytes). When a user key is provided with a smaller payload length, subsequent accesses to auth_tok fields (such as auth_tok->token.password.salt at offset 729 bytes) in write_tag_3_packet() read beyond the allocated user_key_payload buffer into adjacent slab objects, causing a slab-out-of-bounds read and leaking kernel memory into file metadata.

▶ ▼ ✨ Full AI root cause analysis
Based on kernel commit 05441d697f7f:

Root Cause Analysis

Vulnerability Overview

The bug is a slab out-of-bounds read (and potential out-of-bounds write) in the eCryptfs subsystem caused by missing payload size validation when retrieving an authentication token (struct ecryptfs_auth_tok) from a user or encrypted key.

Involved Components

Technical Mechanism & Trigger Flow

  1. Key Creation with Short Payload: A user-defined key is added via add_key("user", "syz", payload, 0xc9, ...) where datalen = 201 (0xc9). In user_preparse() (security/keys/user_defined.c), upayload is allocated via kmalloc_flex() for sizeof(struct user_key_payload) + datalen = $24 + 201 = 225$ bytes, which lands in the kmalloc-256 slab cache.

  2. Mount and Key Lookup: An eCryptfs filesystem is mounted with ecryptfs_sig=syz. During mount (ecryptfs_init_global_auth_toks()) and subsequent file creation (ecryptfs_create() $\to$ ecryptfs_initialize_file() $\to$ ecryptfs_write_metadata() $\to$ ecryptfs_generate_key_packet_set() $\to$ ecryptfs_find_global_auth_tok_for_sig()), eCryptfs verifies the key using ecryptfs_verify_auth_tok_from_key().

  3. Missing Payload Length Validation: In ecryptfs_verify_auth_tok_from_key():

    (*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key);
    

    ecryptfs_get_key_payload_data() fetches ukp = user_key_payload_locked(key) and immediately returns:

    return (struct ecryptfs_auth_tok *)ukp->data;
    

    Neither ecryptfs_get_key_payload_data() nor ecryptfs_verify_auth_tok_from_key() checks whether ukp->datalen >= sizeof(struct ecryptfs_auth_tok) (or the corresponding payload->decrypted_datalen for encrypted keys). ecryptfs_verify_auth_tok_from_key() only checks that (*auth_tok)->version matches ECRYPTFS_VERSION_MAJOR/MINOR (at offset 0) and (*auth_tok)->token_type is valid (at offset 2).

  4. Out-of-Bounds Memory Access: sizeof(struct ecryptfs_auth_tok) is 740 bytes. Inside struct ecryptfs_auth_tok:

    • session_key is at offset 8 bytes (size 588 bytes).
    • reserved is at offset 596 bytes (size 32 bytes).
    • token (union containing struct ecryptfs_password) starts at offset 628 bytes.
    • Within struct ecryptfs_password, salt[ECRYPTFS_SALT_SIZE] is at offset 101 bytes.
    • Thus, auth_tok->token.password.salt resides at offset $628 + 101 = 729$ bytes into ukp->data.

    Adding the 24-byte user_key_payload header yields an offset of $24 + 729 = 753$ bytes from the start of the allocated user_key_payload object in kmalloc-256. Since $753 = 2 \times 256 + 241$, this pointer lands 2 slab slots past the user_key_payload object, specifically at offset 241 (0xf1) within a third, unrelated 248-byte slab object in kmalloc-256 (in the crash report, an allocated fib_info object [ffff888043e1bc00, ffff888043e1bcf8)).

  5. Crash Manifestation: In write_tag_3_packet() (fs/ecryptfs/keystore.c:2353):

    memcpy(&dest[(*packet_size)], auth_tok->token.password.salt, ECRYPTFS_SALT_SIZE);
    

    An 8-byte memcpy starting at offset 241 attempts to read bytes 241 through 248 ($241 + 8 = 249 > 248$), crossing 1 byte past the end of the 248-byte allocation into the KASAN redzone at ffff888043e1bcf8, triggering the reported KASAN: slab-out-of-bounds read.

▶ ▼ ✨ AI Jobs (1)
ID Workflow Result Correct Bug Created Started Finished Revision
fd872f7f assessment-security DenialOfService: ✅ Exploitable: ✅ FilesystemTrigger: ❌ FuzzingArtifact: ❌ MemoryCorruption: ✅ NetworkNeedsSetup: ❌ NetworkTrigger: ❌ PeripheralTrigger: ❌ RemoteTrigger: ❌ Unprivileged: ❌ UserNamespace: ❌ VMGuestTrigger: ❌ VMHostTrigger: ❌ ❓ KASAN: slab-out-of-bounds Read in write_tag_3_packet 2026/11/04 04:25 2026/11/04 04:26 2026/11/04 05:00 d02c3949
▶ ▼ Discussions (1)
Title Replies (including bot) Last reply
[syzbot] [ecryptfs?] KASAN: slab-out-of-bounds Read in write_tag_3_packet 0 (1) 2026/11/05 11:22

Sample crash report:
==================================================================
BUG: KASAN: slab-out-of-bounds in write_tag_3_packet+0xe4f/0x1430 fs/ecryptfs/keystore.c:2353
Read of size 8 at addr ffff888043e1bcf1 by task syz.0.17/6007

CPU: 3 UID: 0 PID: 6007 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:94 [inline]
 dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120
 print_address_description mm/kasan/report.c:378 [inline]
 print_report+0x13d/0x4b0 mm/kasan/report.c:482
 kasan_report+0xdf/0x1c0 mm/kasan/report.c:595
 check_region_inline mm/kasan/generic.c:186 [inline]
 kasan_check_range+0x10f/0x1e0 mm/kasan/generic.c:200
 __asan_memcpy+0x23/0x60 mm/kasan/shadow.c:105
 write_tag_3_packet+0xe4f/0x1430 fs/ecryptfs/keystore.c:2353
 ecryptfs_generate_key_packet_set+0x7ae/0x1880 fs/ecryptfs/keystore.c:2422
 ecryptfs_write_headers_virt fs/ecryptfs/crypto.c:955 [inline]
 ecryptfs_write_metadata+0x590/0x930 fs/ecryptfs/crypto.c:1065
 ecryptfs_initialize_file+0xb6/0x180 fs/ecryptfs/inode.c:252
 ecryptfs_create+0x393/0x550 fs/ecryptfs/inode.c:286
 lookup_open+0xd8a/0x19e0 fs/namei.c:4575
 open_last_lookups fs/namei.c:4774 [inline]
 path_openat+0xe75/0x23f0 fs/namei.c:5013
 do_file_open+0x20e/0x430 fs/namei.c:5045
 do_sys_openat2+0x163/0x1d0 fs/open.c:1442
 do_sys_open fs/open.c:1448 [inline]
 __do_compat_sys_openat fs/open.c:1510 [inline]
 __se_compat_sys_openat fs/open.c:1508 [inline]
 __ia32_compat_sys_openat+0x12d/0x210 fs/open.c:1508
 do_syscall_32_irqs_on arch/x86/entry/syscall_32.c:79 [inline]
 __do_fast_syscall_32+0x14b/0x8c0 arch/x86/entry/syscall_32.c:282
 do_fast_syscall_32+0x32/0x70 arch/x86/entry/syscall_32.c:307
 entry_SYSENTER_compat_after_hwframe+0x84/0x8e
RIP: 0023:0xf73eefbc
Code: d2 74 05 c1 e8 0c 89 02 8b 5d fc 31 c0 c9 c3 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f 00 51 52 55 89 e5 0f 34 cd 80 <5d> 5a 59 c3 90 2e 8d b4 26 00 00 00 00 8d b4 26 00 00 00 00 58 b8
RSP: 002b:00000000ffad3b4c EFLAGS: 00000292 ORIG_RAX: 0000000000000127
RAX: ffffffffffffffda RBX: 00000000ffffff9c RCX: 0000000080000580
RDX: 0000000000101042 RSI: 000000000000009d RDI: 0000000000000000
RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
 </TASK>

Allocated by task 5949:
 kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
 kasan_save_track+0x14/0x30 mm/kasan/common.c:78
 poison_kmalloc_redzone mm/kasan/common.c:409 [inline]
 __kasan_kmalloc+0xaa/0xb0 mm/kasan/common.c:426
 kasan_kmalloc include/linux/kasan.h:263 [inline]
 __do_kmalloc_node mm/slub.c:5531 [inline]
 __kmalloc_noprof+0x32f/0x840 mm/slub.c:5556
 _kmalloc_noprof include/linux/slab.h:995 [inline]
 _kzalloc_noprof include/linux/slab.h:1312 [inline]
 fib_create_info+0x5bf/0x4640 net/ipv4/fib_semantics.c:1432
 fib_table_insert+0x169/0x1c70 net/ipv4/fib_trie.c:1210
 fib_magic+0x4d4/0x5c0 net/ipv4/fib_frontend.c:1147
 fib_add_ifaddr+0x3a1/0x560 net/ipv4/fib_frontend.c:1184
 fib_netdev_event+0x3d6/0x710 net/ipv4/fib_frontend.c:1529
 notifier_call_chain+0x99/0x3f0 kernel/notifier.c:86
 call_netdevice_notifiers_info+0xbe/0x110 net/core/dev.c:2313
 call_netdevice_notifiers_extack net/core/dev.c:2351 [inline]
 call_netdevice_notifiers net/core/dev.c:2365 [inline]
 __dev_notify_flags+0x22c/0x4b0 net/core/dev.c:10032
 netif_change_flags+0x108/0x160 net/core/dev.c:10061
 do_setlink.isra.0+0x1b9f/0x3f50 net/core/rtnetlink.c:3294
 rtnl_changelink net/core/rtnetlink.c:3942 [inline]
 __rtnl_newlink net/core/rtnetlink.c:4113 [inline]
 rtnl_newlink+0x13c1/0x2620 net/core/rtnetlink.c:4252
 rtnetlink_rcv_msg+0x95e/0xe90 net/core/rtnetlink.c:7169
 netlink_rcv_skb+0x159/0x420 net/netlink/af_netlink.c:2584
 netlink_unicast_kernel net/netlink/af_netlink.c:1335 [inline]
 netlink_unicast+0x668/0x950 net/netlink/af_netlink.c:1361
 netlink_sendmsg+0x9ac/0x10c0 net/netlink/af_netlink.c:1920
 sock_sendmsg_nosec net/socket.c:800 [inline]
 __sock_sendmsg net/socket.c:818 [inline]
 __sys_sendto+0x492/0x4e0 net/socket.c:2283
 __do_compat_sys_socketcall net/compat.c:474 [inline]
 __se_compat_sys_socketcall net/compat.c:422 [inline]
 __ia32_compat_sys_socketcall+0x59a/0x770 net/compat.c:422
 do_syscall_32_irqs_on arch/x86/entry/syscall_32.c:79 [inline]
 do_int80_emulation+0x166/0x650 arch/x86/entry/syscall_32.c:166
 asm_int80_emulation+0x1a/0x20 arch/x86/include/asm/idtentry.h:598

The buggy address belongs to the object at ffff888043e1bc00
 which belongs to the cache kmalloc-256 of size 256
The buggy address is located 241 bytes inside of
 allocated 248-byte region [ffff888043e1bc00, ffff888043e1bcf8)

The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x43e1a
head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0x4fff00000000040(head|node=1|zone=1|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 04fff00000000040 ffff88801d442b40 dead000000000100 dead000000000122
raw: 0000000000000000 0000000000100010 00000000f5000000 0000000000000000
head: 04fff00000000040 ffff88801d442b40 dead000000000100 dead000000000122
head: 0000000000000000 0000000000100010 00000000f5000000 0000000000000000
head: 04fff00000000001 ffffffffffffff81 00000000ffffffff 00000000ffffffff
head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000002
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 1, migratetype Unmovable, gfp_mask 0xd2820(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 5864, tgid 5864 (syz-executor), ts 41561072516
 set_page_owner include/linux/page_owner.h:33 [inline]
 post_alloc_hook+0xfd/0x120 mm/page_alloc.c:1856
 prep_new_page mm/page_alloc.c:1864 [inline]
 get_page_from_freelist+0x1113/0x35e0 mm/page_alloc.c:3935
 __alloc_frozen_pages_noprof+0x2bd/0x3280 mm/page_alloc.c:5444
 alloc_slab_page mm/slub.c:3384 [inline]
 allocate_slab mm/slub.c:3499 [inline]
 new_slab+0xb1/0x6d0 mm/slub.c:3550
 refill_objects+0xe3/0x410 mm/slub.c:7539
 refill_sheaf mm/slub.c:2917 [inline]
 __pcs_replace_empty_main+0x35e/0x650 mm/slub.c:4811
 alloc_from_pcs mm/slub.c:4887 [inline]
 slab_alloc_node mm/slub.c:5021 [inline]
 __kmalloc_cache_noprof+0x4ef/0x6d0 mm/slub.c:5676
 _kmalloc_noprof include/linux/slab.h:991 [inline]
 _kzalloc_noprof include/linux/slab.h:1312 [inline]
 ____ip_mc_inc_group+0x40b/0x10d0 net/ipv4/igmp.c:1601
 br_ip4_multicast_join_snoopers.isra.0+0x152/0x400 net/bridge/br_multicast.c:4263
 br_multicast_join_snoopers+0x8b/0x120 net/bridge/br_multicast.c:4283
 br_dev_open+0x112/0x150 net/bridge/br_device.c:175
 __dev_open+0x3ad/0x8f0 net/core/dev.c:1762
 __dev_change_flags+0x596/0x850 net/core/dev.c:9991
 netif_change_flags+0x8d/0x160 net/core/dev.c:10056
 do_setlink.isra.0+0x1b9f/0x3f50 net/core/rtnetlink.c:3294
 rtnl_changelink net/core/rtnetlink.c:3942 [inline]
 __rtnl_newlink net/core/rtnetlink.c:4113 [inline]
 rtnl_newlink+0x13c1/0x2620 net/core/rtnetlink.c:4252
page last free pid 5856 tgid 5856 ts 40658746840 stack trace:
 reset_page_owner include/linux/page_owner.h:26 [inline]
 __free_pages_prepare mm/page_alloc.c:1403 [inline]
 __free_frozen_pages+0x7b4/0x1110 mm/page_alloc.c:2954
 qlink_free mm/kasan/quarantine.c:163 [inline]
 qlist_free_all+0x47/0xf0 mm/kasan/quarantine.c:179
 kasan_quarantine_reduce+0x1a0/0x1f0 mm/kasan/quarantine.c:286
 __kasan_slab_alloc+0x69/0x90 mm/kasan/common.c:361
 kasan_slab_alloc include/linux/kasan.h:253 [inline]
 slab_post_alloc_hook mm/slub.c:4720 [inline]
 slab_alloc_node mm/slub.c:5033 [inline]
 kmem_cache_alloc_node_noprof+0x282/0x6e0 mm/slub.c:5105
 __alloc_skb+0x140/0x710 net/core/skbuff.c:705
 alloc_skb include/linux/skbuff.h:1390 [inline]
 nlmsg_new include/net/netlink.h:1055 [inline]
 rtmsg_ifinfo_build_skb+0x81/0x260 net/core/rtnetlink.c:4617
 rtmsg_ifinfo_event net/core/rtnetlink.c:4659 [inline]
 rtmsg_ifinfo_event net/core/rtnetlink.c:4649 [inline]
 rtmsg_ifinfo+0xa4/0x1b0 net/core/rtnetlink.c:4668
 netif_close_many+0x3ca/0x810 net/core/dev.c:1866
 unregister_netdevice_many_notify+0x563/0x1e00 net/core/dev.c:12694
 unregister_netdevice_many net/core/dev.c:12796 [inline]
 unregister_netdevice_queue net/core/dev.c:12592 [inline]
 unregister_netdevice_queue+0x30b/0x3c0 net/core/dev.c:12578
 unregister_netdevice include/linux/netdevice.h:3509 [inline]
 __tun_detach+0x1386/0x1850 drivers/net/tun.c:641
 tun_detach drivers/net/tun.c:657 [inline]
 tun_chr_close+0xc2/0x220 drivers/net/tun.c:3608
 __fput+0x3fb/0xb50 fs/file_table.c:512
 fput_close_sync+0x118/0x250 fs/file_table.c:618
 filp_close_sync+0x75/0xa0 fs/open.c:1573

Memory state around the buggy address:
 ffff888043e1bb80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff888043e1bc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff888043e1bc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fc
                                                                ^
 ffff888043e1bd00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff888043e1bd80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================
----------------
Code disassembly (best guess):
   0:	d2 74 05 c1          	shlb   %cl,-0x3f(%rbp,%rax,1)
   4:	e8 0c 89 02 8b       	call   0x8b028915
   9:	5d                   	pop    %rbp
   a:	fc                   	cld
   b:	31 c0                	xor    %eax,%eax
   d:	c9                   	leave
   e:	c3                   	ret
   f:	90                   	nop
  10:	90                   	nop
  11:	90                   	nop
  12:	90                   	nop
  13:	90                   	nop
  14:	90                   	nop
  15:	90                   	nop
  16:	90                   	nop
  17:	90                   	nop
  18:	90                   	nop
  19:	90                   	nop
  1a:	90                   	nop
  1b:	90                   	nop
  1c:	90                   	nop
  1d:	90                   	nop
  1e:	0f 1f 00             	nopl   (%rax)
  21:	51                   	push   %rcx
  22:	52                   	push   %rdx
  23:	55                   	push   %rbp
  24:	89 e5                	mov    %esp,%ebp
  26:	0f 34                	sysenter
  28:	cd 80                	int    $0x80
* 2a:	5d                   	pop    %rbp <-- trapping instruction
  2b:	5a                   	pop    %rdx
  2c:	59                   	pop    %rcx
  2d:	c3                   	ret
  2e:	90                   	nop
  2f:	2e 8d b4 26 00 00 00 	cs lea 0x0(%rsi,%riz,1),%esi
  36:	00
  37:	8d b4 26 00 00 00 00 	lea    0x0(%rsi,%riz,1),%esi
  3e:	58                   	pop    %rax
  3f:	b8                   	.byte 0xb8

Crashes (1):
Time Kernel Commit Syzkaller Config Log Report Syz repro C repro VM info Assets (help?) Manager Title
2026/11/04 04:25 upstream 05441d697f7f 5af5b6c6 .config console log report syz / log C [disk image (non-bootable)] [vmlinux] [kernel image] ci-qemu-upstream-386 KASAN: slab-out-of-bounds Read in write_tag_3_packet
* Struck through repros no longer work on HEAD.