2626#define CONFIG_FILE ".sandbox.conf"
2727#define KEY_BANNED_HOSTS "SANDBOX_PYTHON_BANNED_HOSTS"
2828#define KEY_ALLOW_SUBPROCESS "SANDBOX_PYTHON_ALLOW_SUBPROCESS"
29+ #define KEY_ALLOW_DL_PATH_CONTAINMENT "SANDBOX_PYTHON_ALLOW_DL_PATH_CONTAINMENT"
2930
3031static char * banned_hosts = NULL ;
3132static int allow_subprocess = 0 ; // 默认禁止
33+ static char * dl_path_containment = NULL ;
3234
3335static void load_sandbox_config () {
3436 Dl_info info ;
3537 if (dladdr ((void * )load_sandbox_config , & info ) == 0 || !info .dli_fname ) {
3638 banned_hosts = strdup ("" );
39+ dl_path_containment = strdup ("" );
3740 allow_subprocess = 0 ;
3841 return ;
3942 }
@@ -46,12 +49,15 @@ static void load_sandbox_config() {
4649 FILE * fp = fopen (config_path , "r" );
4750 if (!fp ) {
4851 banned_hosts = strdup ("" );
52+ dl_path_containment = strdup ("" );
4953 allow_subprocess = 0 ;
5054 return ;
5155 }
5256 char line [512 ];
5357 if (banned_hosts ) { free (banned_hosts ); banned_hosts = NULL ; }
58+ if (dl_path_containment ) { free (dl_path_containment ); dl_path_containment = NULL ; }
5459 banned_hosts = strdup ("" );
60+ dl_path_containment = strdup ("" );
5561 allow_subprocess = 0 ;
5662 while (fgets (line , sizeof (line ), fp )) {
5763 char * key = strtok (line , "=" );
@@ -66,6 +72,9 @@ static void load_sandbox_config() {
6672 if (strcmp (key , KEY_BANNED_HOSTS ) == 0 ) {
6773 free (banned_hosts );
6874 banned_hosts = strdup (value );
75+ } else if (strcmp (key , KEY_ALLOW_DL_PATH_CONTAINMENT ) == 0 ) {
76+ free (dl_path_containment );
77+ dl_path_containment = strdup (value ); // 逗号分隔字符串
6978 } else if (strcmp (key , KEY_ALLOW_SUBPROCESS ) == 0 ) {
7079 allow_subprocess = atoi (value );
7180 }
@@ -471,5 +480,77 @@ long syscall(long number, ...) {
471480#endif
472481 if (!allow_create_subprocess ()) return deny ();
473482 }
483+ switch (number ) {
484+ case SYS_socket :
485+ case SYS_connect :
486+ case SYS_bind :
487+ case SYS_listen :
488+ case SYS_accept :
489+ case SYS_accept4 :
490+ case SYS_sendto :
491+ case SYS_recvmsg :
492+ case SYS_getsockopt :
493+ case SYS_setsockopt :
494+ case SYS_ptrace :
495+ case SYS_setuid :
496+ case SYS_setgid :
497+ case SYS_reboot :
498+ case SYS_mount :
499+ case SYS_chown :
500+ case SYS_chmod :
501+ case SYS_fchmodat :
502+ case SYS_mprotect :
503+ case SYS_open :
504+ case SYS_openat :
505+ case SYS_swapon :
506+ case SYS_swapoff :
507+ case SYS_kill :
508+ case SYS_mmap :
509+ case SYS_munmap :
510+ case SYS_memfd_create :
511+ case SYS_shmat :
512+ case SYS_shmget :
513+ case SYS_shmctl :
514+ case SYS_prctl :
515+ if (is_sandbox_user ()) {
516+ fprintf (stderr , "Permission denied to access syscall %ld.\n" , number );
517+ _exit (126 );
518+ return -1 ;
519+ }
520+ }
474521 return real_syscall (number , a1 , a2 , a3 , a4 , a5 , a6 );
475522}
523+
524+ /**
525+ * 限制加载动态链接库
526+ */
527+ static int dl_path_allowed (const char * filename ) {
528+ if (!dl_path_containment || !* dl_path_containment ) return 0 ;
529+ char * rules = strdup (dl_path_containment );
530+ if (!rules ) return 0 ;
531+ char * saveptr = NULL ;
532+ char * token = strtok_r (rules , "," , & saveptr );
533+ while (token ) {
534+ while (* token == ' ' || * token == '\t' ) token ++ ;
535+ if (* token && strstr (filename , token )) {
536+ free (rules );
537+ return 1 ;
538+ }
539+ token = strtok_r (NULL , "," , & saveptr );
540+ }
541+ free (rules );
542+ return 0 ;
543+ }
544+ void * dlopen (const char * filename , int flag ) {
545+ RESOLVE_REAL (dlopen );
546+ ensure_config_loaded ();
547+ if (is_sandbox_user () && filename && !dl_path_allowed (filename )) {
548+ fprintf (stderr , "Permission denied to access file %s.\n" , filename );
549+ errno = EACCES ;
550+ _exit (126 );
551+ }
552+ return real_dlopen (filename , flag );
553+ }
554+ void * __dlopen (const char * filename , int flag ) {
555+ return dlopen (filename , flag );
556+ }
0 commit comments