-
Bug
-
Resolution: Done-Errata
-
Undefined
-
rhel-9.2.0.z, rhel-9.3.0.z
-
kernel-5.14.0-410.el9
-
None
-
Moderate
-
ZStream
-
rhel-fs
-
ssg_filesystems_storage_and_HA
-
21
-
23
-
5
-
QE ack, Dev ack
-
False
-
False
-
-
None
-
Red Hat Enterprise Linux
-
None
-
Approved Blocker
-
Pass
-
-
RegressionOnly
-
None
What were you trying to do that didn't work?
System crashed with an invalid address for a cred->group_info in cred_fscmp:
[363434.546053] general protection fault, probably for non-canonical address 0x6b6b6b6b6b6b6b6f: 0000 [#1] PREEMPT SMP PTI [363434.547463] CPU: 39 PID: 564685 Comm: ifind Kdump: loaded Not tainted 5.14.0-378.el9.x86_64 #1 [363434.548736] Hardware name: HP ProLiant DL380 Gen9/ProLiant DL380 Gen9, BIOS P89 07/18/2022 [363434.550031] RIP: 0010:cred_fscmp+0x53/0xa0 PID: 564685 TASK: ffff8a3016c2d8c0 CPU: 39 COMMAND: "ifind" [exception RIP: cred_fscmp+0x53] #6 [ffffa8548626bae0] nfs_access_get_cached at ffffffffc172f198 [nfs] #7 [ffffa8548626bb30] nfs_do_access at ffffffffc172fedf [nfs] #8 [ffffa8548626bbc8] nfs_permission at ffffffffc17301f3 [nfs] #9 [ffffa8548626bbf0] inode_permission at ffffffffa3e32410 #10 [ffffa8548626bc20] link_path_walk at ffffffffa3e37426 #11 [ffffa8548626bc80] path_lookupat at ffffffffa3e37b0e #12 [ffffa8548626bcb8] filename_lookup at ffffffffa3e38f2f #13 [ffffa8548626bdd8] vfs_statx at ffffffffa3e2ad9d #14 [ffffa8548626be30] vfs_fstatat at ffffffffa3e2b1b4 #15 [ffffa8548626be58] __do_sys_newlstat at ffffffffa3e2b523
the crashing instruction:
0xffffffffa3b3b4e3 <cred_fscmp+0x53>: movslq 0x4(%rdx),%rsi RDX: 6b6b6b6b6b6b6b6b RSI: ffff8ab810ba19c0 RDI: ffff8a25a2c5b940
more analysis below
Please provide the package NVR for which bug is seen:
internal kernel-5.14.0-378.el9.x86_64
How reproducible:
unknown, crash experienced once thus far
Steps to reproduce
unknown
Expected results
no crash
Actual results
the crashing instruction:
0xffffffffa3b3b4e3 <cred_fscmp+0x53>: movslq 0x4(%rdx),%rsi RDX: 6b6b6b6b6b6b6b6b RSI: ffff8ab810ba19c0 RDI: ffff8a25a2c5b940
where %rdx contains a struct group_info, and came from %rdi+0x98 (cred->group_info) slightly earlier:
0xffffffffa3b3b4c6 <cred_fscmp+0x36>: mov 0x98(%rdi),%rdx 0xffffffffa3b3b4cd <cred_fscmp+0x3d>: mov 0x98(%rsi),%rcx 0xffffffffa3b3b4d4 <cred_fscmp+0x44>: cmp %rcx,%rdx 0xffffffffa3b3b4d7 <cred_fscmp+0x47>: je 0xffffffffa3b3b529 <cred_fscmp+0x99> 0xffffffffa3b3b4d9 <cred_fscmp+0x49>: test %rdx,%rdx 0xffffffffa3b3b4dc <cred_fscmp+0x4c>: je 0xffffffffa3b3b515 <cred_fscmp+0x85> 0xffffffffa3b3b4de <cred_fscmp+0x4e>: test %rcx,%rcx 0xffffffffa3b3b4e1 <cred_fscmp+0x51>: je 0xffffffffa3b3b524 <cred_fscmp+0x94> 0xffffffffa3b3b4e3 <cred_fscmp+0x53>: movslq 0x4(%rdx),%rsi
however %rdi+0x98 contains a different (and expected) value:
crash> cred.group_info ffff8a25a2c5b940 group_info = 0xffffffffa565ed90 <init_groups>,
so %rdx should not have the bogus value
626 int cred_fscmp(const struct cred *a, const struct cred *b)
627 {
628 struct group_info *ga, *gb;
629 int g;
630
631 if (a == b)
632 return 0;
633 if (uid_lt(a->fsuid, b->fsuid))
634 return -1;
635 if (uid_gt(a->fsuid, b->fsuid))
636 return 1;
637
638 if (gid_lt(a->fsgid, b->fsgid))
639 return -1;
640 if (gid_gt(a->fsgid, b->fsgid))
641 return 1;
642
643 ga = a->group_info;
644 gb = b->group_info;
645 if (ga == gb)
646 return 0;
647 if (ga == NULL)
648 return -1;
649 if (gb == NULL)
650 return 1;
651 if (ga->ngroups < gb->ngroups) <<<<
called from the following:
3054 int nfs_access_get_cached(struct inode *inode, const struct cred *cred,
3055 u32 *mask, bool may_block)
3056 {
3057 int status;
3058
3059 status = nfs_access_get_cached_rcu(inode, cred, mask);
3022 static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cred, u32 *mask)
3023 {
3024 /* Only check the most recently returned cache entry,
3025 * but do it without locking.
3026 */
3027 struct nfs_inode *nfsi = NFS_I(inode);
3028 u64 login_time = nfs_access_login_time(current, cred);
2956 static u64 nfs_access_login_time(const struct task_struct *task,
2957 const struct cred *cred)
2958 {
2959 const struct task_struct *parent;
2960 const struct cred *pcred;
2961 u64 ret;
2962
2963 rcu_read_lock();
2964 for (;;) {
2965 parent = rcu_dereference(task->real_parent);
2966 pcred = rcu_dereference(parent->cred);
2967 if (parent == task || cred_fscmp(pcred, cred) != 0)
- links to
-
RHSA-2023:120102
kernel bug fix and enhancement update
- mentioned on