From 29175af7e3859b9892e9113ea9a71e38048552e2 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Wed, 1 Aug 2018 14:34:41 +0100 Subject: [PATCH] Close resource leaks in the BFD library's plugin handler. PR 23460 * plugin.c (bfd_plugin_open_input): Close file descriptor if the call to fstat fails. (try_claim): Always close the file descriptor at the end of the function. (try_load_plugin): If a plugin has already been registered, then skip the dlopen and onload steps and go straight to claiming the file. If these is an error, close the plugin. --- bfd/plugin.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/bfd/plugin.c b/bfd/plugin.c index 7c5bba22c7..d9b9e2f174 100644 --- a/bfd/plugin.c +++ b/bfd/plugin.c @@ -124,7 +124,7 @@ message (int level ATTRIBUTE_UNUSED, } /* Register a claim-file handler. */ -static ld_plugin_claim_file_handler claim_file; +static ld_plugin_claim_file_handler claim_file = NULL; static enum ld_plugin_status register_claim_file (ld_plugin_claim_file_handler handler) @@ -186,8 +186,13 @@ bfd_plugin_open_input (bfd *ibfd, struct ld_plugin_input_file *file) if (iobfd == ibfd) { struct stat stat_buf; + if (fstat (file->fd, &stat_buf)) - return 0; + { + close(file->fd); + return 0; + } + file->offset = 0; file->filesize = stat_buf.st_size; } @@ -208,21 +213,24 @@ try_claim (bfd *abfd) file.handle = abfd; if (!bfd_plugin_open_input (abfd, &file)) return 0; - claim_file (&file, &claimed); - if (!claimed) - close (file.fd); + if (claim_file) + claim_file (&file, &claimed); + close (file.fd); return claimed; } static int try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p) { - void *plugin_handle; + void *plugin_handle = NULL; struct ld_plugin_tv tv[4]; int i; ld_plugin_onload onload; enum ld_plugin_status status; + if (claim_file) + goto have_claim_file; + *has_plugin_p = 0; plugin_handle = dlopen (pname, RTLD_NOW); @@ -257,6 +265,7 @@ try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p) if (status != LDPS_OK) goto err; +have_claim_file: *has_plugin_p = 1; abfd->plugin_format = bfd_plugin_no; @@ -272,6 +281,9 @@ try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p) return 1; err: + if (plugin_handle) + dlclose (plugin_handle); + register_claim_file (NULL); return 0; } @@ -362,7 +374,7 @@ load_plugin (bfd *abfd) int valid_plugin; full_name = concat (p, "/", ent->d_name, NULL); - if (stat(full_name, &s) == 0 && S_ISREG (s.st_mode)) + if (stat (full_name, &s) == 0 && S_ISREG (s.st_mode)) found = try_load_plugin (full_name, abfd, &valid_plugin); if (has_plugin <= 0) has_plugin = valid_plugin; -- 2.18.0