[PATCH] Infinite loop in fs/fcntl.c

From: Christian Ehrhardt (ehrhardt@mathematik.uni-ulm.de)
Date: Wed Jul 19 2000 - 03:12:40 EST


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