2323#include <linux/sched.h>
2424#include <pty.h>
2525#include <stdint.h>
26+ #include <strings.h>
2627
2728#define CONFIG_FILE ".sandbox.conf"
2829#define KEY_BANNED_HOSTS "SANDBOX_PYTHON_BANNED_HOSTS"
2930#define KEY_ALLOW_SUBPROCESS "SANDBOX_PYTHON_ALLOW_SUBPROCESS"
30- #define KEY_ALLOW_DL_PATH_CONTAINMENT "SANDBOX_PYTHON_ALLOW_DL_PATH_CONTAINMENT "
31+ #define KEY_ALLOW_DL_PATHS "SANDBOX_PYTHON_ALLOW_DL_PATHS "
3132
3233static char * banned_hosts = NULL ;
3334static int allow_subprocess = 0 ; // 默认禁止
34- static char * dl_path_containment = NULL ;
35+ static char * allow_dl_paths = NULL ;
3536
3637static void load_sandbox_config () {
3738 Dl_info info ;
3839 if (dladdr ((void * )load_sandbox_config , & info ) == 0 || !info .dli_fname ) {
3940 banned_hosts = strdup ("" );
40- dl_path_containment = strdup ("" );
41+ allow_dl_paths = strdup ("" );
4142 allow_subprocess = 0 ;
4243 return ;
4344 }
@@ -50,15 +51,15 @@ static void load_sandbox_config() {
5051 FILE * fp = fopen (config_path , "r" );
5152 if (!fp ) {
5253 banned_hosts = strdup ("" );
53- dl_path_containment = strdup ("" );
54+ allow_dl_paths = strdup ("" );
5455 allow_subprocess = 0 ;
5556 return ;
5657 }
5758 char line [512 ];
5859 if (banned_hosts ) { free (banned_hosts ); banned_hosts = NULL ; }
59- if (dl_path_containment ) { free (dl_path_containment ); dl_path_containment = NULL ; }
60+ if (allow_dl_paths ) { free (allow_dl_paths ); allow_dl_paths = NULL ; }
6061 banned_hosts = strdup ("" );
61- dl_path_containment = strdup ("" );
62+ allow_dl_paths = strdup ("" );
6263 allow_subprocess = 0 ;
6364 while (fgets (line , sizeof (line ), fp )) {
6465 char * key = strtok (line , "=" );
@@ -73,9 +74,9 @@ static void load_sandbox_config() {
7374 if (strcmp (key , KEY_BANNED_HOSTS ) == 0 ) {
7475 free (banned_hosts );
7576 banned_hosts = strdup (value );
76- } else if (strcmp (key , KEY_ALLOW_DL_PATH_CONTAINMENT ) == 0 ) {
77- free (dl_path_containment );
78- dl_path_containment = strdup (value ); // 逗号分隔字符串
77+ } else if (strcmp (key , KEY_ALLOW_DL_PATHS ) == 0 ) {
78+ free (allow_dl_paths );
79+ allow_dl_paths = strdup (value ); // 逗号分隔字符串
7980 } else if (strcmp (key , KEY_ALLOW_SUBPROCESS ) == 0 ) {
8081 allow_subprocess = atoi (value );
8182 }
@@ -507,30 +508,34 @@ long syscall(long number, ...) {
507508/**
508509 * 限制加载动态链接库
509510 */
510- static int dl_path_allowed (const char * filename ) {
511+ static int is_in_allow_dl_paths (const char * filename ) {
511512 if (!filename || !* filename ) return 1 ;
512513 ensure_config_loaded ();
513- if (!dl_path_containment || !* dl_path_containment ) return 0 ;
514- char * rules = strdup (dl_path_containment );
514+ if (!allow_dl_paths || !* allow_dl_paths ) return 0 ;
515+ char real_file [PATH_MAX ];
516+ if (!realpath (filename , real_file )) return 0 ;
517+ char * rules = strdup (allow_dl_paths );
515518 if (!rules ) return 0 ;
516- char real_full_path_of_filename [PATH_MAX ];
517- if (realpath (filename , real_full_path_of_filename ) == NULL ) return 0 ;
519+ int allowed = 0 ;
518520 char * saveptr = NULL ;
519- char * token = strtok_r (rules , "," , & saveptr );
520- while (token ) {
521+ for (char * token = strtok_r (rules , "," , & saveptr ); token ; token = strtok_r (NULL , "," , & saveptr )) {
521522 while (* token == ' ' || * token == '\t' ) token ++ ;
522- if (* token && strstr (real_full_path_of_filename , token )) {
523- free (rules );
524- return 1 ;
523+ if (!* token ) continue ;
524+ char real_rule [PATH_MAX ];
525+ if (!realpath (token , real_rule )) continue ;
526+ size_t len = strlen (real_rule );
527+ if (strncmp (real_file , real_rule , len ) == 0 &&
528+ (real_file [len ] == '\0' || real_file [len ] == '/' )) {
529+ allowed = 1 ;
530+ break ;
525531 }
526- token = strtok_r (NULL , "," , & saveptr );
527532 }
528533 free (rules );
529- return 0 ;
534+ return allowed ;
530535}
531536void * dlopen (const char * filename , int flag ) {
532537 RESOLVE_REAL (dlopen );
533- if (is_sandbox_user () && !dl_path_allowed (filename )) {
538+ if (is_sandbox_user () && !is_in_allow_dl_paths (filename )) {
534539 fprintf (stderr , "Permission denied to access file %s.\n" , filename );
535540 errno = EACCES ;
536541 _exit (126 );
@@ -542,7 +547,7 @@ void *__dlopen(const char *filename, int flag) {
542547}
543548void * dlmopen (Lmid_t lmid , const char * filename , int flags ) {
544549 RESOLVE_REAL (dlmopen );
545- if (is_sandbox_user () && !dl_path_allowed (filename )) {
550+ if (is_sandbox_user () && !is_in_allow_dl_paths (filename )) {
546551 fprintf (stderr , "Permission denied to access file %s.\n" , filename );
547552 errno = EACCES ;
548553 _exit (126 );
@@ -570,7 +575,7 @@ void* mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off) {
570575 _exit (126 );
571576 }
572577 real_path [n ] = '\0' ;
573- if (!dl_path_allowed (real_path )) {
578+ if (!is_in_allow_dl_paths (real_path )) {
574579 fprintf (stderr ,"Permission denied to mmap %s.\n" , real_path );
575580 errno = EACCES ;
576581 _exit (126 );
0 commit comments