From 1833fabd6235480a364aa58bb550c426f4c532f1 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Fri, 19 May 2023 15:44:26 -0700 Subject: [PATCH] libsysprof-analyze: include inode when creating ELF We want to know the inode of the FD that was mmaped so that we can check the requested inode when processing the address map from a particular process. --- src/libsysprof-analyze/sysprof-elf-loader.c | 35 ++++++++++++++++++-- src/libsysprof-analyze/sysprof-elf-private.h | 1 + src/libsysprof-analyze/sysprof-elf.c | 2 ++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/libsysprof-analyze/sysprof-elf-loader.c b/src/libsysprof-analyze/sysprof-elf-loader.c index c0e0396a..cb0d9363 100644 --- a/src/libsysprof-analyze/sysprof-elf-loader.c +++ b/src/libsysprof-analyze/sysprof-elf-loader.c @@ -20,6 +20,9 @@ #include "config.h" +#include +#include + #include "sysprof-elf-private.h" #include "sysprof-elf-loader-private.h" #include "sysprof-strings-private.h" @@ -285,6 +288,33 @@ sysprof_elf_loader_annotate (SysprofElfLoader *self, sysprof_elf_set_debug_link_elf (elf, get_deepest_debuglink (debug_link_elf)); } +static gboolean +get_file_and_inode (const char *path, + GMappedFile **mapped_file, + guint64 *file_inode) +{ + struct stat stbuf; + int fd; + + g_assert (path != NULL); + g_assert (mapped_file != NULL); + g_assert (file_inode != NULL); + + *mapped_file = NULL; + *file_inode = 0; + + fd = open (path, O_RDONLY|O_CLOEXEC, 0); + if (fd == -1) + return FALSE; + + if (fstat (fd, &stbuf) == 0) + *file_inode = (guint64)stbuf.st_ino; + *mapped_file = g_mapped_file_new_from_fd (fd, FALSE, NULL); + close (fd); + + return *mapped_file != NULL; +} + /** * sysprof_elf_loader_load: * @self: a #SysprofElfLoader @@ -333,6 +363,7 @@ sysprof_elf_loader_load (SysprofElfLoader *self, SysprofElf *cached_elf = NULL; const char *path = paths[i]; const char *debug_link; + guint64 mapped_file_inode; if (in_flatpak || in_podman) path = container_path = access_path_from_container (path); @@ -353,8 +384,8 @@ sysprof_elf_loader_load (SysprofElfLoader *self, * store a failure record in the cache so that we don't attempt to load * it again. */ - if ((mapped_file = g_mapped_file_new (path, FALSE, NULL))) - elf = sysprof_elf_new (path, g_steal_pointer (&mapped_file), &local_error); + if (get_file_and_inode (path, &mapped_file, &mapped_file_inode)) + elf = sysprof_elf_new (path, g_steal_pointer (&mapped_file), mapped_file_inode, &local_error); g_hash_table_insert (self->cache, g_strdup (path), diff --git a/src/libsysprof-analyze/sysprof-elf-private.h b/src/libsysprof-analyze/sysprof-elf-private.h index 7dda3a36..e8d5ac92 100644 --- a/src/libsysprof-analyze/sysprof-elf-private.h +++ b/src/libsysprof-analyze/sysprof-elf-private.h @@ -30,6 +30,7 @@ G_DECLARE_FINAL_TYPE (SysprofElf, sysprof_elf, SYSPROF, ELF, GObject) SysprofElf *sysprof_elf_new (const char *filename, GMappedFile *mapped_file, + guint64 file_inode, GError **error); gboolean sysprof_elf_matches (SysprofElf *self, guint64 file_inode, diff --git a/src/libsysprof-analyze/sysprof-elf.c b/src/libsysprof-analyze/sysprof-elf.c index c19cb080..ac4e66bd 100644 --- a/src/libsysprof-analyze/sysprof-elf.c +++ b/src/libsysprof-analyze/sysprof-elf.c @@ -150,6 +150,7 @@ sysprof_elf_init (SysprofElf *self) SysprofElf * sysprof_elf_new (const char *filename, GMappedFile *mapped_file, + guint64 file_inode, GError **error) { SysprofElf *self; @@ -163,6 +164,7 @@ sysprof_elf_new (const char *filename, self = g_object_new (SYSPROF_TYPE_ELF, NULL); self->file = g_strdup (filename); self->parser = g_steal_pointer (&parser); + self->file_inode = file_inode; return self; }