etmem/0077-etmem-fix-the-problem-of-libso-no-permission-verific.patch
liubo fe6d2a0135 etmem: sync source repo submission
Sync the features and bug fixed in the etmem
source repository.

Signed-off-by: liubo <liubo254@huawei.com>
(cherry picked from commit 07dd6a411bce9ed3d9f617a6f01ae076e24a3adf)
2022-10-12 10:10:23 +08:00

137 lines
4.5 KiB
Diff

From 9c924ce79851c30763eec0e5f247e96d1efc7e61 Mon Sep 17 00:00:00 2001
From: liubo <liubo254@huawei.com>
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 <liubo254@huawei.com>
---
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 <stdio.h>
#include <stdbool.h>
#include <sys/ioctl.h>
+#include <sys/stat.h>
#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 <sys/time.h>
#include <ctype.h>
#include <unistd.h>
-#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
-#include <sys/types.h>
#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