Custom LSM: getting a null pointer dereference when trying to access a task security blob
Denis Obrezkov
denisobrezkov at gmail.com
Sun Jan 23 15:47:51 UTC 2022
Hello,
I am writing a small LSM similar to SMACK. I've wrote a task blob init hook:
static void init_task_keylock(struct task_keylock *tsp, struct
keylock_known *task, struct keylock_known *forked)
{
tsp->kl_task = task;
tsp->kl_forked = forked;
}
I predefined one label for the initial task (similar to SMACK's hat,
floor, etc):
struct keylock_known keylock_known_system = {
.label = "system\n",
.kl_mask = 7,
};
and I can see that as in SMACK I can get the label from the initial task
into the inodes:
static int keylock_inode_alloc_security(struct inode *inode)
{
struct keylock_known *skp = kl_of_current();
pr_info("KeyLock: skp->label:%s\n", skp->label);
init_inode_keylock(inode, skp);
return 0;
}
But after few successful reads I get the kernel null page dereference error:
[ 0.193868] Mount-cache hash table entries: 8192 (order: 4, 65536
bytes, linear)
[ 0.194860] Mountpoint-cache hash table entries: 8192 (order: 4,
65536 bytes, linear)
[ 0.195883] KeyLock: skp->label:system
[ 0.195883]
[ 0.196847] KeyLock: skp->label:system
[ 0.196847]
[ 0.197844] KeyLock: skp->label:system
[ 0.197844]
[ 0.198920] KeyLock: skp->label:system
[ 0.198920]
[ 0.199958] x86/cpu: User Mode Instruction Prevention (UMIP) activated
[ 0.200911] Last level iTLB entries: 4KB 0, 2MB 0, 4MB 0
[ 0.201825] Last level dTLB entries: 4KB 0, 2MB 0, 4MB 0, 1GB 0
[ 0.202829] Spectre V1 : Mitigation: usercopy/swapgs barriers and
__user pointer sanitization
[ 0.203825] Spectre V2 : Mitigation: Full generic retpoline
[ 0.204824] Spectre V2 : Spectre v2 / SpectreRSB mitigation: Filling
RSB on context switch
[ 0.205824] Spectre V2 : Enabling Restricted Speculation for firmware
calls
[ 0.206825] Spectre V2 : mitigation: Enabling conditional Indirect
Branch Prediction Barrier
[ 0.207825] Speculative Store Bypass: Mitigation: Speculative Store
Bypass disabled via prctl and seccomp
[ 0.208828] SRBDS: Unknown: Dependent on hypervisor status
[ 0.209783] MDS: Mitigation: Clear CPU buffers
[ 0.217907] Freeing SMP alternatives memory: 40K
[ 0.218822] smpboot: CPU0: Intel(R) Core(TM) i5-4210U CPU @ 1.70GHz
(family: 0x6, model: 0x45, stepping: 0x1)
[ 0.218961] Performance Events: Haswell events, Intel PMU driver.
[ 0.219839] ... version: 2
[ 0.220665] ... bit width: 48
[ 0.220827] ... generic registers: 4
[ 0.221660] ... value mask: 0000ffffffffffff
[ 0.221827] ... max period: 000000007fffffff
[ 0.222636] ... fixed-purpose events: 3
[ 0.222827] ... event mask: 000000070000000f
[ 0.223896] rcu: Hierarchical SRCU implementation.
[ 0.224993] smp: Bringing up secondary CPUs ...
[ 0.225771] smp: Brought up 1 node, 1 CPU
[ 0.225828] smpboot: Max logical packages: 1
[ 0.226536] smpboot: Total of 1 processors activated (4789.13 BogoMIPS)
[ 0.227006] BUG: kernel NULL pointer dereference, address:
0000000000000030
[ 0.227823] #PF: supervisor read access in kernel mode
[ 0.227823] #PF: error_code(0x0000) - not-present page
[ 0.227823] PGD 0 P4D 0
[ 0.227823] Oops: 0000 [#1] SMP PTI
[ 0.227823] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.10.17+ #4
[ 0.227823] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
BIOS 1.13.0-1ubuntu1.1 04/01/2014
[ 0.227823] RIP: 0010:keylock_inode_alloc_security+0x2b/0x48
[ 0.227823] Code: 65 48 8b 04 25 00 6d 01 00 53 48 8b 90 58 06 00 00
48 89 fb 48 c7 c7 6a 7e 23 88 48 63 05 54 2e 80 00 48 8b 52 78 48 8b 2c
02 <48> 8b 75 30 e8 72 66 ff ff 48 63 05 44 29
[ 0.227823] RSP: 0000:ffffb50b80013d50 EFLAGS: 00010282
[ 0.227823] RAX: 0000000000000000 RBX: ffffa2bc80144320 RCX:
0000000000000020
[ 0.227823] RDX: ffffa2bc8005b0c0 RSI: ffffffff87367cbf RDI:
ffffffff88237e6a
[ 0.227823] RBP: 0000000000000000 R08: 0000000000000020 R09:
ffffa2bc8010b080
[ 0.227823] R10: 8e89d572bb4b3d14 R11: 52cbeeedbf187f36 R12:
ffffa2bc80144320
[ 0.227823] R13: ffffa2bc80144488 R14: 0000000000000000 R15:
ffffa2bc80149000
[ 0.227823] FS: 0000000000000000(0000) GS:ffffa2bcbbc00000(0000)
knlGS:0000000000000000
[ 0.227823] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 0.227823] CR2: 0000000000000030 CR3: 000000001b60c001 CR4:
0000000000170ef0
[ 0.227823] Call Trace:
[ 0.227823] security_inode_alloc+0x40/0x80
[ 0.227823] ? _cond_resched+0x10/0x20
[ 0.227823] inode_init_always+0xd4/0x1e0
[ 0.227823] alloc_inode+0x2b/0x90
[ 0.227823] new_inode_pseudo+0x7/0x50
[ 0.227823] new_inode+0xe/0x30
[ 0.227823] shmem_get_inode+0x59/0x240
[ 0.227823] ? shmem_put_super+0x50/0x50
[ 0.227823] shmem_fill_super+0x1e4/0x230
[ 0.227823] vfs_get_super+0x74/0x100
[ 0.227823] vfs_get_tree+0x20/0xb0
[ 0.227823] ? shmem_parse_options+0x84/0xc0
[ 0.227823] fc_mount+0x9/0x30
[ 0.227823] vfs_kern_mount.part.0+0x6c/0x80
[ 0.227823] devtmpfs_init+0x47/0x149
[ 0.227823] driver_init+0x5/0x28
[ 0.227823] kernel_init_freeable+0xc4/0x1d3
[ 0.227823] ? rest_init+0xa4/0xa4
[ 0.227823] kernel_init+0x5/0xfc
[ 0.227823] ret_from_fork+0x22/0x30
[ 0.227823] Modules linked in:
[ 0.227823] CR2: 0000000000000030
[ 0.227823] ---[ end trace 63f588023014db8e ]---
[ 0.227823] RIP: 0010:keylock_inode_alloc_security+0x2b/0x48
It seems that something happens after smpboot.I assumed that the pointer
to the initial task struct would be copied to every child task. And that
stuct keylock_known_system would be always accessible. What could be my
mistake?
--
Regards, Denis Obrezkov
More information about the Linux-security-module-archive
mailing list