lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <tencent_FA76EF66A63CD7369E971636784A0074D509@qq.com>
Date: Sat, 29 Mar 2025 17:39:51 +0800
From: Edward Adam Davis <eadavis@...com>
To: syzbot+3b6c5c6a1d0119b687a1@...kaller.appspotmail.com
Cc: linux-kernel@...r.kernel.org,
	syzkaller-bugs@...glegroups.com
Subject: Re: [syzbot] [afs?] BUG: sleeping function called from invalid context in __alloc_frozen_pages_noprof

#syz test: upstream 1d0b929fc070b4115403a0a6206a0c6a62dd61f5

diff --git a/fs/afs/dynroot.c b/fs/afs/dynroot.c
index eb20e231d7ac..8d640f6537fc 100644
--- a/fs/afs/dynroot.c
+++ b/fs/afs/dynroot.c
@@ -286,12 +286,16 @@ static int afs_dynroot_readdir_cells(struct afs_net *net, struct dir_context *ct
 
 	_enter("%llu", ctx->pos);
 
+	rcu_read_lock();
 	for (;;) {
 		unsigned int ix = ctx->pos >> 1;
+		u8 name_len;
+		char *name;
+		unsigned int dynroot_ino;
 
 		cell = idr_get_next(&net->cells_dyn_ino, &ix);
 		if (!cell)
-			return 0;
+			goto unlock;
 		if (READ_ONCE(cell->state) == AFS_CELL_FAILED ||
 		    READ_ONCE(cell->state) == AFS_CELL_REMOVED) {
 			ctx->pos += 2;
@@ -305,19 +309,29 @@ static int afs_dynroot_readdir_cells(struct afs_net *net, struct dir_context *ct
 
 		_debug("pos %llu -> cell %u", ctx->pos, cell->dynroot_ino);
 
+		name_len = cell->name_len;
+		name = cell->name;
+		dynroot_ino = cell->dynroot_ino;
 		if ((ctx->pos & 1) == 0) {
-			if (!dir_emit(ctx, cell->name, cell->name_len,
-				      cell->dynroot_ino, DT_DIR))
-				return 0;
+			rcu_read_unlock();
+			if (!dir_emit(ctx, name, name_len,
+				      dynroot_ino, DT_DIR))
+				goto out;
+			rcu_read_lock();
 			ctx->pos++;
 		}
 		if ((ctx->pos & 1) == 1) {
-			if (!dir_emit(ctx, cell->name - 1, cell->name_len + 1,
-				      cell->dynroot_ino + 1, DT_DIR))
-				return 0;
+			rcu_read_unlock();
+			if (!dir_emit(ctx, name - 1, name_len + 1,
+				      dynroot_ino + 1, DT_DIR))
+				goto out;
+			rcu_read_lock();
 			ctx->pos++;
 		}
 	}
+unlock:
+	rcu_read_unlock();
+out:
 	return 0;
 }
 
@@ -347,9 +361,7 @@ static int afs_dynroot_readdir(struct file *file, struct dir_context *ctx)
 	}
 
 	if ((unsigned long long)ctx->pos <= AFS_MAX_DYNROOT_CELL_INO) {
-		rcu_read_lock();
 		ret = afs_dynroot_readdir_cells(net, ctx);
-		rcu_read_unlock();
 	}
 	return ret;
 }


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ