From 1650e47b1bd18414c8ca7a9889a107e658e8473f Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Fri, 29 Jul 2022 15:21:52 +0200 Subject: [PATCH] fix(modern_bpf): final version of `auxmap__store_path_from_fd` use a final version of the `auxmap__store_path_from_fd` that correctly works on all supported architectures Signed-off-by: Andrea Terzolo Co-authored-by: Hendrik Brueckner Co-authored-by: Federico Di Pierro --- .../helpers/store/auxmap_store_params.h | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/driver/modern_bpf/helpers/store/auxmap_store_params.h b/driver/modern_bpf/helpers/store/auxmap_store_params.h index a2e4cc5647..7beee3c815 100644 --- a/driver/modern_bpf/helpers/store/auxmap_store_params.h +++ b/driver/modern_bpf/helpers/store/auxmap_store_params.h @@ -13,7 +13,7 @@ /* Right now a file path extracted from a file descriptor can * have at most `MAX_PATH_POINTERS` components. */ -#define MAX_PATH_POINTERS 16 +#define MAX_PATH_POINTERS 8 /* Concept of auxamp (auxiliary map): * @@ -298,6 +298,19 @@ static __always_inline u16 auxmap__store_charbuf_param(struct auxiliary_map *aux * So we need to do it by hand and this cause a limit in the max * path component that we can retrieve (MAX_PATH_POINTERS). * + * This version of `auxmap__store_path_from_fd` works smooth on all + * supported architectures: `s390x`, `ARM64`, `x86_64`. + * The drawback is that due to its complexity we can catch at most + * `MAX_PATH_POINTERS==8`. + * + * The previous version of this method was able to correctly catch paths + * under different mount points, but not on `s390x` architecture, where + * the userspace test `open_by_handle_atX_success_mp` failed. + * + * #@Andreagit97: reduce the complexity of this helper to allow the capture + * of more path components, or enable only this version of the helper on `s390x`, + * leaving the previous working version on `x86` and `aarch64` architectures. + * * @param auxmap pointer to the auxmap in which we are storing the param. * @param fd file descriptor from which we want to retrieve the file path. */ @@ -319,12 +332,7 @@ static __always_inline void auxmap__store_path_from_fd(struct auxiliary_map *aux struct mount *mnt = container_of(original_mount, struct mount, mnt); struct dentry *mount_dentry = BPF_CORE_READ(mnt, mnt.mnt_root); struct dentry *file_dentry_parent = NULL; - - /* this should catch the path from the right mount point. */ - if(file_dentry == mount_dentry && file_dentry != root_dentry) - { - BPF_CORE_READ_INTO(&file_dentry, mnt, mnt_mountpoint); - } + struct mount *parent_mount = NULL; /* Here we store all the pointers, note that we don't take the pointer * to the root so we will add it manually if it is necessary! @@ -336,6 +344,15 @@ static __always_inline void auxmap__store_path_from_fd(struct auxiliary_map *aux break; } + if(file_dentry == mount_dentry) + { + BPF_CORE_READ_INTO(&parent_mount, mnt, mnt_parent); + BPF_CORE_READ_INTO(&file_dentry, mnt, mnt_mountpoint); + mnt = parent_mount; + BPF_CORE_READ_INTO(&mount_dentry, mnt, mnt.mnt_root); + continue; + } + path_components++; BPF_CORE_READ_INTO(&path_pointers[k], file_dentry, d_name.name); BPF_CORE_READ_INTO(&file_dentry_parent, file_dentry, d_parent);