OSDN Git Service

Fix crash when started with stdin, stdout or stderr closed.
authorrelan <relan@users.noreply.github.com>
Sat, 25 Mar 2017 06:24:09 +0000 (09:24 +0300)
committerrelan <relan@users.noreply.github.com>
Fri, 31 Mar 2017 05:23:59 +0000 (08:23 +0300)
libexfat/io.c

index 8cbcfa1..63ccfdb 100644 (file)
@@ -45,6 +45,11 @@ struct exfat_dev
        off_t size; /* in bytes */
 };
 
+static bool is_open(int fd)
+{
+       return fcntl(fd, F_GETFD) != -1;
+}
+
 static int open_ro(const char* spec)
 {
        return open(spec, O_RDONLY);
@@ -75,6 +80,24 @@ struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode)
        struct exfat_dev* dev;
        struct stat stbuf;
 
+       /* The system allocates file descriptors sequentially. If we have been
+          started with stdin (0), stdout (1) or stderr (2) closed, the system
+          will give us descriptor 0, 1 or 2 later when we open block device,
+          FUSE communication pipe, etc. As a result, functions using stdin,
+          stdout or stderr will actualy work with a different thing and can
+          corrupt it. Protect descriptors 0, 1 and 2 from such misuse. */
+       while (!is_open(STDIN_FILENO)
+               || !is_open(STDOUT_FILENO)
+               || !is_open(STDERR_FILENO))
+       {
+               /* we don't need those descriptors, let them leak */
+               if (open("/dev/null", O_RDWR) == -1)
+               {
+                       exfat_error("failed to open /dev/null");
+                       return NULL;
+               }
+       }
+
        dev = malloc(sizeof(struct exfat_dev));
        if (dev == NULL)
        {