bash/only-scripts-verified-by-execveat-are-allowed-to-run.patch

126 lines
3.2 KiB
Diff
Raw Normal View History

2025-03-27 14:52:41 +08:00
From f38ec12d60641ae7f5ff71f96879a27dd021c390 Mon Sep 17 00:00:00 2001
From: wangyuhang <wangyuhang27@huawei.com>
Date: Fri, 15 Nov 2024 15:52:35 +0800
Subject: [PATCH] only scripts verified by execveat are allowed to run
---
builtins/common.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++
builtins/common.h | 7 +++++++
shell.c | 4 ++++
3 files changed, 60 insertions(+)
diff --git a/builtins/common.c b/builtins/common.c
index 19b00c4..5205fe4 100644
--- a/builtins/common.c
+++ b/builtins/common.c
@@ -34,6 +34,7 @@
#include <signal.h>
#include <errno.h>
+#include <fcntl.h>
#if defined (PREFER_STDARG)
# include <stdarg.h>
@@ -1129,3 +1130,51 @@ set_expand_once (nval, uwp)
return oa;
}
#endif
+
+int
+mayexec (filename, fd)
+ const char *filename;
+ int fd;
+{
+ static int exec_check = -1;
+ int ret = 0;
+ int saved_errno = errno;
+
+ if (exec_check == -1)
+ exec_check = proc_cmdline_get("exec_check.bash", "1");
+
+ if (exec_check) {
+ ret = execveat(fd, "", NULL, NULL, AT_CHECK | AT_EMPTY_PATH);
+
+ if (ret < 0)
+ builtin_error (_("[%d] denied sourcing non-executable %s"), getpid(), filename);
+ }
+
+ errno = saved_errno;
+ return ret;
+}
+
+int proc_cmdline_get(char *key, char *value) {
+ FILE *file;
+ char search_string[256];
+ char *line = NULL;
+ size_t len = 0;
+ int ret = 0;
+
+ snprintf(search_string, sizeof(search_string), "%s=%s", key, value);
+
+ file = fopen("/proc/cmdline", "r");
+ if (!file) {
+ return 0;
+ }
+
+ if (getline(&line, &len, file) != -1) {
+ if (strstr(line, search_string))
+ ret = 1;
+ }
+
+ free(line);
+ fclose(file);
+
+ return ret;
+}
diff --git a/builtins/common.h b/builtins/common.h
index a170f8f..29ff9f5 100644
--- a/builtins/common.h
+++ b/builtins/common.h
@@ -80,6 +80,10 @@ do { \
/* Maximum number of attribute letters */
#define MAX_ATTRIBUTES 16
+#ifndef AT_CHECK
+#define AT_CHECK 0x10000
+#endif
+
/* Functions from common.c */
extern void builtin_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
extern void builtin_warning PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
@@ -239,6 +243,9 @@ extern int builtin_unbind_variable PARAMS((const char *));
extern SHELL_VAR *builtin_find_indexed_array PARAMS((char *, int));
extern int builtin_arrayref_flags PARAMS((WORD_DESC *, int));
+extern int mayexec PARAMS((const char *, int));
+extern int proc_cmdline_get PARAMS((char *key, char *value));
+
/* variables from evalfile.c */
extern int sourcelevel;
diff --git a/shell.c b/shell.c
index ebd8965..10fc616 100644
--- a/shell.c
+++ b/shell.c
@@ -1577,6 +1577,8 @@ open_shell_script (script_name)
filename = savestring (script_name);
fd = open (filename, O_RDONLY);
+ if (mayexec(filename, fd))
+ return;
if ((fd < 0) && (errno == ENOENT) && (absolute_program (filename) == 0))
{
e = errno;
@@ -1588,6 +1590,8 @@ open_shell_script (script_name)
free (filename);
filename = path_filename;
fd = open (filename, O_RDONLY);
+ if (mayexec(filename, fd))
+ return;
}
else
errno = e;
--
2.33.0