afh: Fix fd leak.
authorAndre Noll <maan@systemlinux.org>
Sun, 15 Dec 2013 21:39:21 +0000 (22:39 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Thu, 15 Jan 2015 20:57:28 +0000 (21:57 +0100)
The main() function of para_afh obtains the open file descriptor from
mmap_full_file() which is then passed to compute_afhi(). If this file
descriptor is never closed, we have an fd leak.

Unfortunately it depends on the audio format handler whether fd
gets closed or not: the mp3 audio format handler closes it through
libid3tag's id3_file_close() while all other audio format handlers
leave it open.

Fix this by changing mp3_get_id3() to operate on a copy of the fd
instead so that the original fd remains open. The newly added close()
in afh.c thus fixes the fd leak and never closes an invalid fd.

afh.c
mp3_afh.c

diff --git a/afh.c b/afh.c
index 49629cb1a7513ae300d0704cb543755f60b40131..f3c25a261ea5cc9c3b49398c850dba00e82afd35 100644 (file)
--- a/afh.c
+++ b/afh.c
@@ -111,6 +111,7 @@ int main(int argc, char **argv)
                        printf("\n");
                        clear_afhi(&afhi);
                }
+               close(fd);
                ret2 = para_munmap(audio_file_data, audio_file_size);
                if (ret2 < 0 && ret >= 0)
                        ret = ret2;
index cc3f49ffbb2b704af955e77e944a72250d3d309c..2506b95e8799780c5c5b26adf723450f63d41c91 100644 (file)
--- a/mp3_afh.c
+++ b/mp3_afh.c
@@ -126,9 +126,19 @@ static char *get_strings(struct id3_frame *fr)
 static void mp3_get_id3(__a_unused unsigned char *map,
                __a_unused size_t numbytes, int fd, struct taginfo *tags)
 {
-       int i;
+       int i, new_fd;
        struct id3_tag *id3_t;
-       struct id3_file *id3_f = id3_file_fdopen(fd, ID3_FILE_MODE_READONLY);
+       struct id3_file *id3_f;
+
+       /*
+        * We are not supposed to close fd, but to avoid memory leaks we must
+        * call id3_file_close() on the id3_file after we are done. As
+        * id3_file_close() closes fd, we first create a copy for libid3tag.
+        */
+       new_fd = dup(fd);
+       if (new_fd < 0)
+               return;
+       id3_f = id3_file_fdopen(new_fd, ID3_FILE_MODE_READONLY);
 
        if (!id3_f)
                return;