While fuzzing the kernel with syzkaller, the following issue was triggered:
Call Trace:
strlen usr/src/kernel/include/linux/string.h:306 [inline]
nfs_mount+0x316/0x740 usr/src/kernel/fs/nfs/mount_clnt.c:174
? __kernel_text_address+0x12/0x40 usr/src/kernel/kernel/extable.c:95
? mnt_xdr_dec_mountres+0x3a0/0x3a0 usr/src/kernel/fs/nfs/mount_clnt.c:371
? arch_stack_walk+0xa2/0xf0 usr/src/kernel/arch/x86/kernel/stacktrace.c:26
? mark_usage usr/src/kernel/kernel/locking/lockdep.c:3426 [inline]
? __lock_acquire+0x557/0x5ed0 usr/src/kernel/kernel/locking/lockdep.c:3752
nfs_request_mount.constprop.0+0x42e/0x680 usr/src/kernel/fs/nfs/super.c:1817
? nfs_fs_mount+0x2870/0x2870 usr/src/kernel/fs/nfs/super.c:2080
? lockdep_hardirqs_on+0x580/0x580 usr/src/kernel/kernel/locking/lockdep.c:3264
? lockdep_hardirqs_on+0x580/0x580 usr/src/kernel/kernel/locking/lockdep.c:3264
nfs_try_mount_request usr/src/kernel/fs/nfs/super.c:1839 [inline]
nfs_try_mount+0x25b/0x93a usr/src/kernel/fs/nfs/super.c:1907
? lock_downgrade+0x770/0x770 usr/src/kernel/kernel/locking/lockdep.c:4043
? nfs_request_mount.constprop.0+0x680/0x680 usr/src/kernel/fs/nfs/super.c:1800
? lock_downgrade+0x770/0x770 usr/src/kernel/kernel/locking/lockdep.c:4043
? rwlock_bug.part.0+0x90/0x90 usr/src/kernel/include/linux/sched.h:1250
? kasan_check_read+0x11/0x20 usr/src/kernel/mm/kasan/common.c:94
? atomic_read usr/src/kernel/include/asm-generic/atomic-instrumented.h:26
[inline]
? queued_spin_is_locked usr/src/kernel/include/asm-generic/qspinlock.h:26
[inline]
? debug_spin_unlock usr/src/kernel/kernel/locking/spinlock_debug.c:98 [inline]
? do_raw_spin_unlock+0x59/0x260
usr/src/kernel/kernel/locking/spinlock_debug.c:138
? __raw_spin_unlock usr/src/kernel/include/linux/spinlock_api_smp.h:152
[inline]
? _raw_spin_unlock+0x32/0x50 usr/src/kernel/kernel/locking/spinlock.c:183
? find_nfs_version+0xe6/0x110 usr/src/kernel/include/linux/err.h:26
nfs_fs_mount+0xe83/0x2870 usr/src/kernel/fs/nfs/super.c:2750
? nfs_remount+0x19e0/0x19e0 usr/src/kernel/include/net/ipv6.h:517
? trace_kfree usr/src/kernel/include/trace/events/kmem.h:137 [inline]
? kfree+0x194/0x2c0 usr/src/kernel/mm/slub.c:3983
? nfs_clone_super+0x420/0x420 usr/src/kernel/fs/nfs/super.c:2421
? nfs_parse_mount_options+0x2400/0x2400 usr/src/kernel/fs/nfs/super.c:1396
? vfs_parse_fs_string+0x11b/0x170 usr/src/kernel/fs/fs_context.c:190
? vfs_parse_fs_param+0x540/0x540 usr/src/kernel/fs/fs_context.c:163
? nfs_remount+0x19e0/0x19e0 usr/src/kernel/include/net/ipv6.h:517
legacy_get_tree+0x10f/0x220 usr/src/kernel/fs/fs_context.c:659
? legacy_parse_monolithic+0x124/0x180 usr/src/kernel/fs/fs_context.c:643
vfs_get_tree+0x98/0x3a0 usr/src/kernel/fs/super.c:1478
do_new_mount usr/src/kernel/fs/namespace.c:2801 [inline]
do_mount+0x1381/0x1c20 usr/src/kernel/fs/namespace.c:3121
? copy_mount_string+0x40/0x40 usr/src/kernel/fs/namespace.c:3024
? kasan_kmalloc+0x9/0x10 usr/src/kernel/mm/kasan/common.c:509
? kmem_cache_alloc_trace+0x147/0x310 usr/src/kernel/mm/slub.c:2810
? __sanitizer_cov_trace_const_cmp4+0x16/0x20 usr/src/kernel/kernel/kcov.c:189
? memset usr/src/kernel/include/linux/string.h:369 [inline]
? copy_mount_options+0x2d9/0x3d0 usr/src/kernel/fs/namespace.c:3017
ksys_mount+0xd8/0x130 usr/src/kernel/fs/namespace.c:3330
__do_sys_mount usr/src/kernel/fs/namespace.c:3344 [inline]
__se_sys_mount usr/src/kernel/fs/namespace.c:3341 [inline]
__x64_sys_mount+0xc3/0x150 usr/src/kernel/fs/namespace.c:3341
do_syscall_64+0xc7/0x600 usr/src/kernel/arch/x86/entry/common.c:295
entry_SYSCALL_64_after_hwframe+0x49/0xbe
It can be reproduced using the following simplified program:
#include <stdlib.h>
#include <sys/mount.h>
int main()
{
mount(NULL, "./file0", "nfs", 0x400, "\x07\000\000\000");
return 0;
}
It was introduced by the follwing yocto-specific commit:
commit ad818f6b28a610b53814d8b1d0da2fadfd83a3ad
Author: Jason Wessel <[email protected]>
Date: Wed Jan 7 00:59:33 2009 -0500
NFS: allow nfs root mount to use alternate rpc ports
Allow an nfs root mount to use alternate RPC ports for mountd and nfsd.
Signed-off-by: Jason Wessel <[email protected]>
[forward port to 2.6.33+]
Signed-off-by: Bruce Ashfield <[email protected]>
Since hardknott, "NFS: allow nfs root mount to use alternate rpc ports" patch is
no longer applied by yocto-kernel-cache (a4283cc6be0c65 ("kver: update
-dev to v5.6-rc5")) due to a merge conflict. Also, in later kernels (since v5.6
commit f2aedb713c284 ("NFS: Add fs_context support")), the nfs parser has been
refactored to use generic fs_context, so it is not clear how easy would be to
reproduce this issue.
The null pointer dereference takes place only when data->version is 0x07,
because that is the only switch case that does not perform struct
nfs_parsed_mount_data initialization (case 6 in the switch). All other
switch cases fall through case 6 and perform the initializations properly.
To fix this, also run legacy version 6 binary mount logic when NFS version
is 0x07.
Signed-off-by: Ovidiu Panait <[email protected]>
---
...oot-mount-to-use-alternate-rpc-ports.patch | 41 +++++++++++--------
1 file changed, 25 insertions(+), 16 deletions(-)
diff --git
a/patches/boot/NFS-allow-nfs-root-mount-to-use-alternate-rpc-ports.patch
b/patches/boot/NFS-allow-nfs-root-mount-to-use-alternate-rpc-ports.patch
index 540c2a7a..6206e944 100644
--- a/patches/boot/NFS-allow-nfs-root-mount-to-use-alternate-rpc-ports.patch
+++ b/patches/boot/NFS-allow-nfs-root-mount-to-use-alternate-rpc-ports.patch
@@ -1,4 +1,4 @@
-From ae9f6294d685cda95203d5752bb1d0cd275bb59a Mon Sep 17 00:00:00 2001
+From 946cd569252d22ec2d557fa323e36178d1af8ace Mon Sep 17 00:00:00 2001
From: Jason Wessel <[email protected]>
Date: Wed, 7 Jan 2009 00:59:33 -0500
Subject: [PATCH] NFS: allow nfs root mount to use alternate rpc ports
@@ -8,6 +8,8 @@ Allow an nfs root mount to use alternate RPC ports for mountd
and nfsd.
Signed-off-by: Jason Wessel <[email protected]>
[forward port to 2.6.33+]
Signed-off-by: Bruce Ashfield <[email protected]>
+[OP: fix NULL ptr dereference when mounting with legacy binary options]
+Signed-off-by: Ovidiu Panait <[email protected]>
---
fs/nfs/client.c | 12 ++++++++++--
fs/nfs/internal.h | 7 +++++--
@@ -76,10 +78,10 @@ index 30838304a0bf..a0389dc885ea 100644
struct nfs_client *clp;
int error;
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
-index a2346a2f8361..85fa99dd8441 100644
+index 447a3c17fa8e..559f14a6eb37 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
-@@ -85,6 +85,7 @@ struct nfs_client_initdata {
+@@ -77,6 +77,7 @@ struct nfs_client_initdata {
struct net *net;
const struct rpc_timeout *timeparms;
const struct cred *cred;
@@ -87,7 +89,7 @@ index a2346a2f8361..85fa99dd8441 100644
};
/*
-@@ -96,6 +97,8 @@ struct nfs_parsed_mount_data {
+@@ -88,6 +89,8 @@ struct nfs_parsed_mount_data {
unsigned int timeo, retrans;
unsigned int acregmin, acregmax,
acdirmin, acdirmax;
@@ -96,7 +98,7 @@ index a2346a2f8361..85fa99dd8441 100644
unsigned int namlen;
unsigned int options;
unsigned int bsize;
-@@ -153,11 +156,11 @@ struct nfs_mount_info {
+@@ -145,11 +148,11 @@ struct nfs_mount_info {
struct nfs_fh *mntfh;
};
@@ -150,7 +152,7 @@ index cb7c10e9721e..266da4cac411 100644
.number = NFS_MNT_PROGRAM,
.nrvers = ARRAY_SIZE(mnt_version),
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
-index 628631e2e34f..f05026a0c3da 100644
+index a84df7d63403..999b4162abba 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -105,6 +105,8 @@ enum {
@@ -216,16 +218,23 @@ index 628631e2e34f..f05026a0c3da 100644
if (status != 0) {
dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
request.hostname, status);
-@@ -2117,6 +2143,9 @@ static int nfs23_validate_mount_data(void *options,
- #endif
- }
+@@ -2016,6 +2042,8 @@ static int nfs23_validate_mount_data(void *options,
+ goto out_no_data;
-+ break;
+ args->version = NFS_DEFAULT_VERSION;
++ args->nfs_prog = (data->version >= 7) ? data->nfs_prog : NFS_PROGRAM;
++
+ switch (data->version) {
+ case 1:
+ data->namlen = 0; /* fall through */
+@@ -2037,6 +2065,7 @@ static int nfs23_validate_mount_data(void *options,
+ memset(data->context, 0, sizeof(data->context));
+ /* fall through */
+ case 6:
+ case 7:
-+ args->nfs_prog = (data->version >= 7) ? data->nfs_prog :
NFS_PROGRAM;
- break;
- default:
- return NFS_TEXT_DATA;
+ if (data->flags & NFS_MOUNT_VER3) {
+ if (data->root.size > NFS3_FHSIZE || data->root.size ==
0)
+ goto out_invalid_fh;
@@ -2180,6 +2209,7 @@ static int nfs_validate_text_mount_data(void *options,
int max_namelen = PAGE_SIZE;
int max_pathlen = NFS_MAXPATHLEN;
@@ -234,7 +243,7 @@ index 628631e2e34f..f05026a0c3da 100644
if (nfs_parse_mount_options((char *)options, args) == 0)
return -EINVAL;
-@@ -2823,6 +2853,8 @@ static int nfs4_validate_mount_data(void *options,
+@@ -2849,6 +2879,8 @@ static int nfs4_validate_mount_data(void *options,
args->version = 4;
@@ -286,5 +295,5 @@ index e3bcfc6aa3b0..ed57fec0beef 100644
/* bits in the flags field visible to user space */
--
-2.19.1
+2.17.1
--
2.17.1
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#10013):
https://lists.yoctoproject.org/g/linux-yocto/message/10013
Mute This Topic: https://lists.yoctoproject.org/mt/83845918/21656
Group Owner: [email protected]
Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-