2022-02-08 22:37:25

by zhangxiaoxu (A)

[permalink] [raw]
Subject: Question about CVE-2022-24448

Hi Trond and Tao,

I have some question about CVE-2022-24448[1].

It's description as:
An issue was discovered in fs/nfs/dir.c in the Linux kernel before 5.16.5.
If an application sets the O_DIRECTORY flag, and tries to open a regular
file, nfs_atomic_open() performs a regular lookup. If a regular file is
found, ENOTDIR should occur, but the server instead returns uninitialized
data in the file descriptor.

It's fixed by ac795161c936 ("NFSv4: Handle case where the lookup of a directory fails")

When try to open a regular file with O_DIRECTORY flag,
it always return -ENOTDIR to userspace rather than a
valid file descriptor because the 'do_open' check the
dentry type.

My questions are:
1. which uninitialized data in the file description are returned from 'nfs_atomic_open'?
2. where use the uninitialized data?
3. which uninitialized data are returned from server?
4. is there a PoC reproducer or how to trigger it?


[1] https://nvd.nist.gov/vuln/detail/CVE-2022-24448


2022-02-09 12:40:11

by zhangxiaoxu (A)

[permalink] [raw]
Subject: Re: Question about CVE-2022-24448



在 2022/2/8 20:31, Lyu Tao 写道:
>
> Hi Xiaoxu,
>
> I only know about the question 2 and 4.
>
> 2. When the kernel executes nfs4_valid_open_stateid, the state is zero. Then it enters into the inline function nfs4_valid_open_stateid, and executes a dereference operation.
>
> /int nfs4_select_rw_stateid(struct nfs4_state *state,
>         fmode_t fmode, const struct nfs_lock_context *l_ctx,
>         nfs4_stateid *dst, const struct cred **cred)
> {
>     ...
>     if (!nfs4_valid_open_stateid(state))
>         return -EIO;
>     ...
> }
>
> static inline bool nfs4_valid_open_stateid(const struct nfs4_state *state)
> {
>     return test_bit(NFS_STATE_RECOVERY_FAILED, &state->flags) == 0;
> }/

how it happend? do you have the panic stacks?
when 'nfs_atomic_open' returned, the 'do_open' always checked the dentry type,
if not directory, it will return -ENOTDIR.

path_openat
alloc_empty_file
__alloc_file
atomic_long_set(&f->f_count, 1);
open_last_lookups
lookup_open
file->f_mode &= ~FMODE_CREATED;
atomic_open
nfs_atomic_open
goto no_open; # open_flags & O_DIRECTORY
nfs_lookup
do_open
if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry))
return -ENOTDIR;
# will return error here, how call the 'nfs4_select_rw_stateid' with ctx->state = NULL?
fput


>
> 4. The PoC is attached.
i create file1 on nfs mount point and run the poc, no nullptr derference occured.
Also, there no O_DIRECTORY flag set when call 'open/openat' syscall.

[root@fedora mnt]# ll
total 24
---------- 1 root root 0 Feb 9 06:11 file1
-rwxr-xr-x 1 root root 24440 Feb 9 06:05 poc

[root@fedora mnt]# strace -e trace=open,openat ./poc
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "./file1", O_RDWR|O_CREAT, 000) = 3
open("./file1", O_ACCMODE|O_CREAT|O_DIRECT|O_LARGEFILE|O_NOFOLLOW|O_NOATIME|O_CLOEXEC|FASYNC|0xb3000008, 001) = 4
+++ exited with 0 +++

>
> Best,
> Tao
>
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> *From:* zhangxiaoxu (A) <[email protected]>
> *Sent:* Tuesday, February 8, 2022 12:48:58 PM
> *To:* Lyu Tao; Trond Myklebust
> *Cc:* ChenXiaoSong; yanaijie; zhangyi (F); Linux NFS Mailing List
> *Subject:* Question about CVE-2022-24448
> Hi Trond and Tao,
>
> I have some question about CVE-2022-24448[1].
>
> It's description as:
>    An issue was discovered in fs/nfs/dir.c in the Linux kernel before 5.16.5.
>    If an application sets the O_DIRECTORY flag, and tries to open a regular
>    file, nfs_atomic_open() performs a regular lookup. If a regular file is
>    found, ENOTDIR should occur, but the server instead returns uninitialized
>    data in the file descriptor.
>
> It's fixed by ac795161c936 ("NFSv4: Handle case where the lookup of a directory fails")
>
> When try to open a regular file with O_DIRECTORY flag,
> it always return -ENOTDIR to userspace rather than a
> valid file descriptor because the 'do_open' check the
> dentry type.
>
> My questions are:
> 1. which uninitialized data in the file description are returned from 'nfs_atomic_open'?
> 2. where use the uninitialized data?
> 3. which uninitialized data are returned from server?
> 4. is there a PoC reproducer or how to trigger it?
>
>
> [1] https://nvd.nist.gov/vuln/detail/CVE-2022-24448 <https://nvd.nist.gov/vuln/detail/CVE-2022-24448>