Hi,
there is a Bug in fs/fcntl.c#locate_fd that can hang your system
completly within seconds. Just run this little program with a
ulimit > 1024 for the number of open files.
#include <unistd.h>
#include <stdlib.h>
int main () {
int fd;
while (1) {
fd = dup (0);
if (fd < 0)
break;
if (close (fd-1) < 0)
break;
fd = dup (0);
if (fd < 0)
break;
if (fd %100 == 0) {
write (0, "ok\n", 3);
}
}
perror ("duptest");
return 0;
}
The reason is an infinite loop in locate_fd. Here's the patch. It also
fixes another mostly harmless race that might cause unnecessary expansion
of the number of file descriptors. The patch is against 2.3.99-pre9 but
it applies cleanly against 2.4.0-test4.
--- linux-2.3.99/fs/fcntl.c.vanilla Wed Jul 19 00:34:07 2000
+++ linux-2.3.99/fs/fcntl.c Wed Jul 19 01:00:45 2000
@@ -21,19 +21,21 @@
*/
static inline int locate_fd(struct files_struct *files,
- struct file *file, int start)
+ struct file *file, int orig_start)
{
unsigned int newfd;
int error;
+ int start;
write_lock(&files->file_lock);
repeat:
error = -EMFILE;
+ start = orig_start; /* Someone might have closed fd's in the range
+ * orig_start..files->next_fd */
if (start < files->next_fd)
start = files->next_fd;
if (start >= files->max_fdset) {
- expand:
error = expand_files(files, start);
if (error < 0)
goto out;
@@ -46,8 +48,6 @@
error = -EMFILE;
if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
goto out;
- if (newfd >= files->max_fdset)
- goto expand;
error = expand_files(files, newfd);
if (error < 0)
regards Christian
-- THAT'S ALL FOLKS!- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Sun Jul 23 2000 - 21:00:12 EST