Skip to contentSkip to conversation

max_fds race in select().

PATCH In review Rusty Russell 2 participants 2 messages May 4, 2001 VFS

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 max_fds race in select().

We can end up with the user getting more fds tban they asked for...

Unlikely, but possible,
Rusty.

fs/select.c +5 -3
@@ -260,7 +260,7 @@
 	fd_set_bits fds;
 	char *bits;
 	long timeout;
-	int ret, size;
+	int ret, size, max_fdset;
 
 	timeout = MAX_SCHEDULE_TIMEOUT;
 	if (tvp) {
@@ -285,8 +285,10 @@
 	if (n < 0)
 		goto out_nofds;
 
-	if (n > current->files->max_fdset)
-		n = current->files->max_fdset;
+	/* max_fdset can increase, so grab it once to avoid race */
+	max_fdset = current->files->max_fdset;
+	if (n > max_fdset)
+		n = max_fdset;
 
 	/*
 	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),

--
Premature optmztion is rt of all evl. --DK

#1 lore raw
Quoted 3 lines · Rusty Russell

We can end up with the user getting more fds tban they asked for...

Unlikely, but possible,

True. If n is originally greater than ->max_fdset and ->max_fdset grows between the comparison and assignment. Yuck.

Linus, please apply it - race is narrow, but...
Al

Quoted 28 lines
fs/select.c +5 -4
@@ -260,7 +260,7 @@
 	fd_set_bits fds;
 	char *bits;
 	long timeout;
-	int ret, size;
+	int ret, size, max_fdset;
 
 	timeout = MAX_SCHEDULE_TIMEOUT;
 	if (tvp) {
@@ -285,8 +285,10 @@
 	if (n < 0)
 		goto out_nofds;
 
-	if (n > current->files->max_fdset)
-		n = current->files->max_fdset;
+	/* max_fdset can increase, so grab it once to avoid race */
+	max_fdset = current->files->max_fdset;
+	if (n > max_fdset)
+		n = max_fdset;
 
 	/*
 	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
 
--

Premature optmztion is rt of all evl. --DK