On Wed, Mar 19, 2025 at 06:40:18PM +0100, Michal Sekletar wrote: > Whenever possible, resolve all symlinks as if the sysroot path were a > chroot environment. This prevents potential interactions with files from > the host filesystem. > > Signed-off-by: Michal Sekletar <msekl...@redhat.com> > --- > configure.ac | 17 +++++++++++++++++ > libdwfl/dwfl_segment_report_module.c | 21 +++++++++++++++++++++ > libdwfl/link_map.c | 27 ++++++++++++++++++++++++++- > 3 files changed, 64 insertions(+), 1 deletion(-) > > diff --git a/configure.ac b/configure.ac > index 3298f7fc..22f7258a 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -283,6 +283,23 @@ case "$CFLAGS" in > ;; > esac > > +AC_MSG_CHECKING([for openat2 with RESOLVE_IN_ROOT support]) > +AC_LINK_IFELSE( > + [AC_LANG_PROGRAM([[ > + #include <fcntl.h> > + #include <linux/openat2.h> > + #include <sys/syscall.h> > + #include <unistd.h> > + #include <stdlib.h> > + ]], [[ > + struct open_how how = { .flags = O_RDONLY|O_DIRECTORY, .resolve = > RESOLVE_IN_ROOT }; > + return syscall (SYS_openat2, AT_FDCWD, ".", &how, sizeof(how)) >= 0 ? > EXIT_SUCCESS : EXIT_FAILURE; > + ]])], > + [AC_DEFINE([HAVE_OPENAT2_RESOLVE_IN_ROOT], [1], [Define if openat2 is > available]) > + AC_MSG_RESULT(yes)], > + [AC_MSG_RESULT(no)] > +) > +
It's always a good idea to wrap checks with AC_CACHE_CHECK, for example (untested): AC_CACHE_CHECK( [for openat2 with RESOLVE_IN_ROOT support], [eu_cv_openat2_RESOLVE_IN_ROOT], [AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <sys/syscall.h> #include <linux/openat2.h> ]], [[ struct open_how how = { .flags = O_RDONLY|O_DIRECTORY, .resolve = RESOLVE_IN_ROOT }; int dfd = open (".", O_DIRECTORY|O_PATH); return syscall (SYS_openat2, dfd, ".", &how, sizeof(how)) < 0; ]] )], [eu_cv_openat2_RESOLVE_IN_ROOT=yes], [eu_cv_openat2_RESOLVE_IN_ROOT=no] )] ) AS_IF([test "x$eu_cv_openat2_RESOLVE_IN_ROOT" = xyes], [AC_DEFINE([HAVE_OPENAT2_RESOLVE_IN_ROOT], [1], [Define if openat2 is available])] ) This way one can set eu_cv_openat2_RESOLVE_IN_ROOT variable for configure script invocation to override the check. > dnl enable debugging of branch prediction. > AC_ARG_ENABLE([debugpred], > AS_HELP_STRING([--enable-debugpred],[build binaries with support to debug > branch prediction]), > diff --git a/libdwfl/dwfl_segment_report_module.c > b/libdwfl/dwfl_segment_report_module.c > index 32f44af8..53b938b9 100644 > --- a/libdwfl/dwfl_segment_report_module.c > +++ b/libdwfl/dwfl_segment_report_module.c > @@ -37,6 +37,12 @@ > #include <inttypes.h> > #include <fcntl.h> > > +#if HAVE_OPENAT2_RESOLVE_IN_ROOT > +#include <linux/openat2.h> > +#include <sys/syscall.h> > +#include <unistd.h> > +#endif > + > #include <system.h> > > > @@ -784,6 +790,19 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const > char *name, > sysroot if it is set. */ > if (dwfl->sysroot && !executable) > { > +#if HAVE_OPENAT2_RESOLVE_IN_ROOT > + int sysrootfd; > + struct open_how how = { > + .flags = O_RDONLY, > + .resolve = RESOLVE_IN_ROOT, > + }; > + > + sysrootfd = open (dwfl->sysroot, O_DIRECTORY|O_PATH); > + if (sysrootfd < 0) > + return -1; > + fd = syscall (SYS_openat2, sysrootfd, name, &how, sizeof(how)); > + close (sysrootfd); > +#else I suggest implementing a runtime fallback to the old non-openat2 code if openat2 syscall is not available, e.g. filtered out by a seccomp filter. -- ldv