2022-11-28 19:05:32

by butt3rflyh4ck

[permalink] [raw]
Subject: There is a null-ptr-deref bug because of udf_add_entry

Hi, there is a null-ptr-deref bug in ima_post_path_mknod invoked by
do_mknodat via modified syzkaller and reproducing it in the latest
kernel.

## simply analyze
when to do mknod syscall.
````
static int do_mknodat(int dfd, struct filename *name, umode_t mode,
unsigned int dev)
{
.....

error = may_mknod(mode);
if (error)
goto out1;
retry:
dentry = filename_create(dfd, name, &path, lookup_flags); /////[1]
.......
switch (mode & S_IFMT) {
case 0: case S_IFREG:
error = vfs_create(mnt_userns, path.dentry->d_inode,
dentry, mode, true); ///////////[2]
if (!error)
ima_post_path_mknod(mnt_userns, dentry); /////[3]
````
Normally
[1] creates a dentry for a new file, but at this moment dentry->d_inode is NULL.
[2] Create a vfs inode for dentry->d_inode.
```
void ima_post_path_mknod(struct user_namespace *mnt_userns,
struct dentry *dentry)
{
struct integrity_iint_cache *iint;
struct inode *inode = dentry->d_inode;
int must_appraise;

if (!ima_policy_flag || !S_ISREG(inode->i_mode)) //////[4]
return;
```
[3] call ima_post_path_mknod, Normally dentry->d_inode is NOT null, so
ima_post_path_mknod did not check inode.
[4] dereference inode.

I debug this bug to position it, maybe a problem in udf_add_entry.
the call stack chains:
vfs_create
-->udf_create
--->udf_add_nondir
```
static int udf_add_nondir(struct dentry *dentry, struct inode *inode)
{
.....
fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
if (unlikely(!fi)) { /////[5]
inode_dec_link_count(inode);
discard_new_inode(inode);
return err;
}
.....
d_instantiate_new(dentry, inode); ////[6]

return 0;
}
```
udf_add_entry would return NULL, fi is null but err is 0 too, so [5]
return err, but err is 0
[6] so did not call d_instantiate_new to set dentry->d_inode,
dentry->d_inode is NULL.

The udf_add_entry is more complicated, I haven't been able to analyze
it in depth.

###crash log
[ 6145.371558][ T4760] loop0: detected capacity change from 0 to 1664
[ 6145.373868][ T4760] UDF-fs: INFO Mounting volume 'LinuxUDF',
timestamp 2022/09/12 12:00 (1000)
[ 6145.572505][ T4760] BUG: kernel NULL pointer dereference, address:
0000000000000000
[ 6145.573237][ T4760] #PF: supervisor read access in kernel mode
[ 6145.573731][ T4760] #PF: error_code(0x0000) - not-present page
[ 6145.574237][ T4760] PGD 47d1b067 P4D 47d1b067 PUD 48554067 PMD 0
[ 6145.574756][ T4760] Oops: 0000 [#1] PREEMPT SMP
[ 6145.575157][ T4760] CPU: 1 PID: 4760 Comm: ima_post_path_m Not
tainted 6.1.0-rc6-00315-gfaf68e3523c2 #22
[ 6145.575991][ T4760] Hardware name: QEMU Standard PC (i440FX + PIIX,
1996), BIOS 1.14.0-2 04/01/2014
[ 6145.576789][ T4760] RIP: 0010:ima_post_path_mknod+0xf/0x50
[ 6145.577283][ T4760] Code: d9 ff ff 48 85 c0 74 de f0 80 88 c8 00 00
00 02 80 a0 d0 00 00 00 f0 5d c3 c3 90 8b 05 f6 96 b2 05 85 c0 74 45
55 48 8b 6e 68 <0f> b7 45 00 66 25 00 f0 66 3d 00 80 74 02 5d a
[ 6145.578984][ T4760] RSP: 0018:ffffc9000acdbea8 EFLAGS: 00010202
[ 6145.579513][ T4760] RAX: 0000000000000001 RBX: 0000000000000000
RCX: 0000000000000006
[ 6145.580212][ T4760] RDX: 0000000000000000 RSI: ffff888016b95af8
RDI: ffffffff84729a00
[ 6145.580889][ T4760] RBP: 0000000000000000 R08: 0000000000000001
R09: 0000000000000001
[ 6145.581546][ T4760] R10: 0000000000000002 R11: 0000000000000000
R12: ffff8880403a7000
[ 6145.582210][ T4760] R13: 0000000000000000 R14: 0000000000000006
R15: 0000000000000000
[ 6145.582880][ T4760] FS: 00000000013de380(0000)
GS:ffff88807ec00000(0000) knlGS:0000000000000000
[ 6145.583626][ T4760] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 6145.584162][ T4760] CR2: 0000000000000000 CR3: 000000004feb5000
CR4: 00000000000006e0
[ 6145.584843][ T4760] Call Trace:
[ 6145.585550][ T4760] <TASK>
[ 6145.585804][ T4760] do_mknodat+0x1ff/0x290
[ 6145.586183][ T4760] __x64_sys_mknodat+0x2d/0x40
[ 6145.586588][ T4760] do_syscall_64+0x35/0xb0
[ 6145.586993][ T4760] entry_SYSCALL_64_after_hwframe+0x63/0xcd
[ 6145.587509][ T4760] RIP: 0033:0x44929d
[ 6145.587849][ T4760] Code: 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 f3
0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b
4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff 8
[ 6145.589507][ T4760] RSP: 002b:00007fffc2fff4c8 EFLAGS: 00000287
ORIG_RAX: 0000000000000103
[ 6145.590197][ T4760] RAX: ffffffffffffffda RBX: 0000000000400540
RCX: 000000000044929d
[ 6145.590737][ T4760] RDX: 0000000000000000 RSI: 0000000020000580
RDI: 0000000000000006
[ 6145.591274][ T4760] RBP: 00007fffc2fff4e0 R08: 00000000200005a0
R09: 0000000000000000
[ 6145.591811][ T4760] R10: 0000000000000000 R11: 0000000000000287
R12: 0000000000404ef0
[ 6145.592338][ T4760] R13: 0000000000000000 R14: 00000000004c0018
R15: 0000000000400540

the attachment is reproduce.



Regards,
butt3rflyh4ck.


--
Active Defense Lab of Venustech


Attachments:
repro.c (16.88 kB)