Commit 40955015 authored by Ali Khaledi's avatar Ali Khaledi Committed by Steve French
Browse files

ksmbd: fix use-after-free in proc_show_files due to early rcu_read_unlock



The opinfo pointer obtained via rcu_dereference(fp->f_opinfo) is
dereferenced after rcu_read_unlock(), creating a use-after-free
window. A concurrent opinfo_put() can free the opinfo between the
unlock and the subsequent access to opinfo->is_lease,
opinfo->o_lease->state, and opinfo->level.

Fix this by deferring rcu_read_unlock() until after all opinfo
field accesses are complete. The values needed (const_names, count,
level) are copied into local variables under the RCU read lock,
and the potentially-sleeping seq_printf calls happen after the
lock is released.

Found by AI-assisted code review (Claude Opus 4.6, Anthropic)
in collaboration with Ali Khaledi.

Cc: stable@vger.kernel.org
Fixes: b38f99c1 ("ksmbd: add procfs interface for runtime monitoring and statistics")
Signed-off-by: default avatarAli Khaledi <ali.khaledi1989@gmail.com>
Acked-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent c15e7c62
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -87,11 +87,7 @@ static int proc_show_files(struct seq_file *m, void *v)

		rcu_read_lock();
		opinfo = rcu_dereference(fp->f_opinfo);
		rcu_read_unlock();

		if (!opinfo) {
			seq_printf(m, " %-15s", " ");
		} else {
		if (opinfo) {
			const struct ksmbd_const_name *const_names;
			int count;
			unsigned int level;
@@ -105,8 +101,12 @@ static int proc_show_files(struct seq_file *m, void *v)
				count = ARRAY_SIZE(ksmbd_oplock_const_names);
				level = opinfo->level;
			}
			rcu_read_unlock();
			ksmbd_proc_show_const_name(m, " %-15s",
						   const_names, count, level);
		} else {
			rcu_read_unlock();
			seq_printf(m, " %-15s", " ");
		}

		seq_printf(m, " %#010x %#010x %s\n",