summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2013-12-28 12:58:10 +0100
committerMark Wielaard <[email protected]>2013-12-31 13:58:32 +0100
commitac65261cc5f4b313d4f852e0a7f2b1b91918550b (patch)
treefae55b09a92edbc04977b7b067ca2a10a9ce8dd9
parent05a4412f11e9f48c8a67c48cd2fc71684873bb63 (diff)
libdwfl: dwfl_linux_proc_find_elf should only return regular files.
When the dwfl_linux_proc_find_elf callback is used together with the dwfl_linux_proc_report callback that reads /proc/PID/maps files we might see and try to open special character device files that cannot be normally read and processed by libelf (and might hang the library on the initial open or read from the file). Make sure we only try to open and return regular files. Signed-off-by: Mark Wielaard <[email protected]>
-rw-r--r--libdwfl/ChangeLog5
-rw-r--r--libdwfl/linux-proc-maps.c9
2 files changed, 14 insertions, 0 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 3f9c5255..6c983b2b 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,8 @@
+2013-12-28 Mark Wielaard <[email protected]>
+
+ * linux-proc-maps.c (dwfl_linux_proc_find_elf): Don't return special
+ character device files, only regular files.
+
2013-12-24 Mark Wielaard <[email protected]>
* linux-core-attach.c (core_next_thread): Check whether thread_argp
diff --git a/libdwfl/linux-proc-maps.c b/libdwfl/linux-proc-maps.c
index 8863cc88..b1f8b331 100644
--- a/libdwfl/linux-proc-maps.c
+++ b/libdwfl/linux-proc-maps.c
@@ -29,6 +29,7 @@
#include "libdwflP.h"
#include <inttypes.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdio_ext.h>
@@ -345,6 +346,14 @@ dwfl_linux_proc_find_elf (Dwfl_Module *mod __attribute__ ((unused)),
{
if (module_name[0] == '/')
{
+ /* When this callback is used together with dwfl_linux_proc_report
+ then we might see mappings of special character devices. Make
+ sure we only open and return regular files. Special devices
+ might hang on open or read. */
+ struct stat sb;
+ if (stat (module_name, &sb) == -1 || (sb.st_mode & S_IFMT) != S_IFREG)
+ return -1;
+
int fd = open64 (module_name, O_RDONLY);
if (fd >= 0)
{