From 9c924ce79851c30763eec0e5f247e96d1efc7e61 Mon Sep 17 00:00:00 2001 From: liubo Date: Tue, 17 May 2022 10:02:34 +0800 Subject: [PATCH 27/33] etmem: fix the problem of libso no permission verification etmem supports third-party policy injection. During the injection process, the required so path is specified by the configuration file. However, in the so loading process, the lack of effective permission verification may introduce problems. Therefore, this patch adds permission verification during the so loading process, and only allows root permissions to load so. Signed-off-by: liubo --- etmem/inc/etmemd_inc/etmemd_common.h | 4 ++- etmem/src/etmemd_src/etmemd_common.c | 42 ++++++++++++++++++++++++++++++-- etmem/src/etmemd_src/etmemd_thirdparty.c | 11 +++++++-- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/etmem/inc/etmemd_inc/etmemd_common.h b/etmem/inc/etmemd_inc/etmemd_common.h index 03792a7..db71446 100644 --- a/etmem/inc/etmemd_inc/etmemd_common.h +++ b/etmem/inc/etmemd_inc/etmemd_common.h @@ -19,6 +19,7 @@ #include #include #include +#include #define PROC_PATH "/proc/" #define STATUS_FILE "/status" @@ -39,6 +40,7 @@ #define MAX_SWAPCACHE_WMARK_VALUE 100 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) +#define S_IRWX_VALID (S_IRWXU | S_IRWXG | S_IRWXO) /* in some system the max length of pid may be larger than 5, so we use 10 herr */ #define PID_STR_MAX_LEN 10 @@ -80,5 +82,5 @@ int get_mem_from_proc_file(const char *pid, const char *file_name, unsigned long int dprintf_all(int fd, const char *format, ...); int get_swap_threshold_inKB(const char *string, unsigned long *value); - +int file_permission_check(const char *file_path, mode_t mode); #endif diff --git a/etmem/src/etmemd_src/etmemd_common.c b/etmem/src/etmemd_src/etmemd_common.c index dfbae6d..ab9a05b 100644 --- a/etmem/src/etmemd_src/etmemd_common.c +++ b/etmem/src/etmemd_src/etmemd_common.c @@ -22,10 +22,8 @@ #include #include #include -#include #include #include -#include #include "securec.h" #include "etmemd_common.h" @@ -555,3 +553,43 @@ free_out: out: return ret; } + +int file_permission_check(const char *file_path, mode_t mode) +{ + struct stat buf = {0}; + mode_t file_p; + + if (file_path == NULL || (mode & S_IRWX_VALID) == 0) { + etmemd_log(ETMEMD_LOG_ERR, "file_permission_check failed, invalid para\n"); + return -1; + } + + if (access(file_path, F_OK) != 0) { + etmemd_log(ETMEMD_LOG_ERR, "no such file: %s\n", file_path); + return -1; + } + + if (stat(file_path, &buf) != 0) { + etmemd_log(ETMEMD_LOG_ERR, "get file : %s stat failed.\n", file_path); + return -1; + } + + if (S_ISDIR(buf.st_mode)) { + etmemd_log(ETMEMD_LOG_ERR, "file : %s is a dir\n", file_path); + return -1; + } + + if (buf.st_uid != 0 || buf.st_gid != 0) { + etmemd_log(ETMEMD_LOG_ERR, "file : %s should created by root\n", file_path); + return -1; + } + + file_p = buf.st_mode & S_IRWX_VALID; + if (file_p != mode) { + etmemd_log(ETMEMD_LOG_WARN, "file : %s mode is wrong.\n", file_path); + return -1; + } + + return 0; +} + diff --git a/etmem/src/etmemd_src/etmemd_thirdparty.c b/etmem/src/etmemd_src/etmemd_thirdparty.c index 8d1b50e..ec417b1 100644 --- a/etmem/src/etmemd_src/etmemd_thirdparty.c +++ b/etmem/src/etmemd_src/etmemd_thirdparty.c @@ -91,10 +91,17 @@ static int set_engine_ops(struct engine *eng, struct thirdparty_params *params) return -1; } - handler = dlopen(params->libname, RTLD_NOW | RTLD_LOCAL); + if (file_permission_check(resolve_path, S_IRWXU) != 0 && + file_permission_check(resolve_path, S_IRUSR | S_IXUSR) != 0) { + etmemd_log(ETMEMD_LOG_ERR, "file : %s permissions do not meet requirements." + "Only support 500 or 700\n", resolve_path); + return -1; + } + + handler = dlopen(resolve_path, RTLD_NOW | RTLD_LOCAL); err = dlerror(); if (err != NULL && handler == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "load library %s fail with error: %s\n", params->libname, err); + etmemd_log(ETMEMD_LOG_ERR, "load library %s fail with error: %s\n", resolve_path, err); return -1; } -- 1.8.3.1