From aa07fea7db66bd0f4bd264655ab8c3f47bfebe12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Mon, 5 Apr 1999 15:07:59 -0700 Subject: [PATCH] more security stuff... Rev: src/modules/files/efuns.c:1.68 Rev: src/modules/files/file.c:1.145 Rev: src/modules/system/system.c:1.64 Rev: src/security.c:1.13 Rev: src/security.h:1.5 Rev: src/signal_handler.c:1.121 --- src/modules/files/efuns.c | 29 ++++++++++++++-- src/modules/files/file.c | 6 ++-- src/modules/system/system.c | 60 +++++++++++++++++++++++++++++++-- src/security.c | 2 -- src/security.h | 67 ++++++++++++++++++++++++++++++++++++- src/signal_handler.c | 52 ++++++++++++++++++++++++++-- 6 files changed, 203 insertions(+), 13 deletions(-) diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c index 2a252705ac..7c9a14adda 100644 --- a/src/modules/files/efuns.c +++ b/src/modules/files/efuns.c @@ -19,11 +19,12 @@ #include "backend.h" #include "operators.h" #include "builtin_functions.h" +#include "security.h" #include "file_machine.h" #include "file.h" -RCSID("$Id: efuns.c,v 1.67 1999/03/12 20:30:11 mast Exp $"); +RCSID("$Id: efuns.c,v 1.68 1999/04/05 22:07:38 hubbe Exp $"); #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> @@ -103,7 +104,6 @@ struct array *encode_stat(struct stat *s) return a; } - void f_file_stat(INT32 args) { struct stat st; @@ -115,8 +115,12 @@ void f_file_stat(INT32 args) if(sp[-args].type != T_STRING) error("Bad argument 1 to file_stat()\n"); + VALID_FILE_IO("file_stat","read"); + s = sp[-args].u.string->str; l = (args>1 && !IS_ZERO(sp+1-args))?1:0; + + THREADS_ALLOW_UID(); #ifdef HAVE_LSTAT if(l) @@ -148,6 +152,8 @@ void f_filesystem_stat( INT32 args ) unsigned int free_sectors; unsigned int total_sectors; + VALID_FILE_IO("filesystem_stat","read"); + get_all_args( "filesystem_stat", args, "%s", &path ); if(sp[-1].u.string->len < 2 || path[1] != ':') @@ -381,6 +387,8 @@ void f_werror(INT32 args) args=1; } + VALID_FILE_IO("werror","werror"); + write_to_stderr(sp[-args].u.string->str, sp[-args].u.string->len); pop_n_elems(args); } @@ -397,6 +405,8 @@ void f_rm(INT32 args) if(sp[-args].type != T_STRING) error("Bad argument 1 to rm().\n"); + VALID_FILE_IO("rm","write"); + s = sp[-args].u.string->str; THREADS_ALLOW_UID(); @@ -441,6 +451,9 @@ void f_mkdir(INT32 args) mode = sp[1-args].u.integer; } + + VALID_FILE_IO("mkdir","write"); + s=sp[-args].u.string->str; #if MKDIR_ARGS == 2 THREADS_ALLOW_UID(); @@ -511,6 +524,8 @@ void f_get_dir(INT32 args) struct array *a=0; char *path; + VALID_FILE_IO("get_dir","read"); + get_all_args("get_dir",args,"%s",&path); #if defined(_REENTRANT) && defined(HAVE_READDIR_R) @@ -687,6 +702,8 @@ void f_cd(INT32 args) if(sp[-args].type != T_STRING) error("Bad argument 1 to cd()\n"); + VALID_FILE_IO("cd","status"); + i=chdir(sp[-args].u.string->str) != -1; pop_n_elems(args); push_int(i); @@ -744,6 +761,12 @@ void f_exece(INT32 args) if(args < 2) error("Too few arguments to exece().\n"); +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("exece: permission denied.\n"); +#endif + + e=0; en=0; switch(args) @@ -847,6 +870,8 @@ void f_mv(INT32 args) if(sp[-args+1].type != T_STRING) error("Bad argument 2 to mv().\n"); + VALID_FILE_IO("mv","write"); + i=rename((char *)sp[-args].u.string->str, (char *)sp[-args+1].u.string->str); diff --git a/src/modules/files/file.c b/src/modules/files/file.c index 14c918f6a8..64a2888558 100644 --- a/src/modules/files/file.c +++ b/src/modules/files/file.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: file.c,v 1.144 1999/04/02 02:07:40 hubbe Exp $"); +RCSID("$Id: file.c,v 1.145 1999/04/05 22:07:39 hubbe Exp $"); #include "fdlib.h" #include "interpret.h" #include "svalue.h" @@ -1274,12 +1274,12 @@ static void file_open(INT32 args) { case 0: /* return 0 */ ERRNO=EPERM; - pop_n_elems(args-1); + pop_n_elems(args+1); push_int(0); return; case 1: /* return 1 */ - pop_n_elems(args-1); + pop_n_elems(args+1); push_int(1); return; diff --git a/src/modules/system/system.c b/src/modules/system/system.c index d47e0e889b..9522ca4ab3 100644 --- a/src/modules/system/system.c +++ b/src/modules/system/system.c @@ -1,5 +1,5 @@ /* - * $Id: system.c,v 1.63 1999/03/12 17:49:51 mast Exp $ + * $Id: system.c,v 1.64 1999/04/05 22:07:59 hubbe Exp $ * * System-call module for Pike * @@ -15,7 +15,7 @@ #include "system_machine.h" #include "system.h" -RCSID("$Id: system.c,v 1.63 1999/03/12 17:49:51 mast Exp $"); +RCSID("$Id: system.c,v 1.64 1999/04/05 22:07:59 hubbe Exp $"); #ifdef HAVE_WINSOCK_H #include <winsock.h> #endif @@ -34,6 +34,7 @@ RCSID("$Id: system.c,v 1.63 1999/03/12 17:49:51 mast Exp $"); #include "builtin_functions.h" #include "constants.h" #include "pike_memory.h" +#include "security.h" #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> @@ -189,6 +190,8 @@ void f_hardlink(INT32 args) char *to; int err; + VALID_FILE_IO("hardlink","write"); + get_all_args("hardlink",args, "%s%s", &from, &to); THREADS_ALLOW_UID(); @@ -212,6 +215,8 @@ void f_symlink(INT32 args) char *to; int err; + VALID_FILE_IO("symlink","write"); + get_all_args("symlink",args, "%s%s", &from, &to); THREADS_ALLOW_UID(); @@ -236,6 +241,8 @@ void f_readlink(INT32 args) char *buf; int err; + VALID_FILE_IO("readlink","read"); + get_all_args("readlink",args, "%s", &path); buflen = 100; @@ -282,6 +289,8 @@ void f_resolvepath(INT32 args) char *buf; int err; + VALID_FILE_IO("resolvepath","read"); + get_all_args("resolvepath", args, "%s", &path); buflen = 100; @@ -316,6 +325,8 @@ void f_umask(INT32 args) { int oldmask; + VALID_FILE_IO("umask","status"); + if (args) { int setmask; get_all_args("umask", args, "%d", &setmask); @@ -337,6 +348,8 @@ void f_chmod(INT32 args) int mode; int err; + VALID_FILE_IO("chmod","write"); + get_all_args("chmod", args, "%s%i", &path, &mode); THREADS_ALLOW_UID(); do { @@ -357,6 +370,8 @@ void f_chown(INT32 args) int gid; int err; + VALID_FILE_IO("chown","write"); + get_all_args("chown", args, "%s%i%i", &path, &uid, &gid); THREADS_ALLOW_UID(); do { @@ -377,6 +392,13 @@ void f_initgroups(INT32 args) char *user; int err; INT32 group; + +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("initgroups: permission denied.\n"); +#endif + + VALID_FILE_IO("initgroups","status"); get_all_args("initgroups", args, "%s%i", &user, &group); err = initgroups(user, group); if (err < 0) { @@ -392,6 +414,12 @@ void f_cleargroups(INT32 args) { static gid_t gids[1] = { 65534 }; /* To safeguard against stupid OS's */ int err; + +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("cleargroups: permission denied.\n"); +#endif + pop_n_elems(args); err = setgroups(0, gids); if (err < 0) { @@ -410,6 +438,11 @@ void f_setgroups(INT32 args) INT32 size; int err; +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("setgroups: permission denied.\n"); +#endif + get_all_args("setgroups", args, "%a", &arr); if ((size = arr->size)) { gids = (gid_t *)xalloc(arr->size * sizeof(gid_t)); @@ -477,6 +510,11 @@ void f_setuid(INT32 args) { INT32 id; +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("setuid: permission denied.\n"); +#endif + get_all_args("setuid", args, "%i", &id); if(id == -1) { @@ -497,6 +535,10 @@ void f_setgid(INT32 args) { int id; +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("setgid: permission denied.\n"); +#endif get_all_args("setgid", args, "%i", &id); if(id == -1) { @@ -519,6 +561,10 @@ void f_seteuid(INT32 args) int id; int err; +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("seteuid: permission denied.\n"); +#endif get_all_args("seteuid", args, "%i", &id); if(id == -1) { @@ -546,6 +592,11 @@ void f_setegid(INT32 args) int id; int err; +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("setegid: permission denied.\n"); +#endif + get_all_args("setegid", args, "%i", &id); if(id == -1) @@ -624,6 +675,11 @@ void f_chroot(INT32 args) { int res; +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("chroot: permission denied.\n"); +#endif + #ifdef HAVE_FCHROOT check_all_args("chroot", args, BIT_STRING|BIT_OBJECT, 0); #else diff --git a/src/security.c b/src/security.c index b53ab15224..10ca304aa2 100644 --- a/src/security.c +++ b/src/security.c @@ -2,8 +2,6 @@ /* To do: * controls for file->pipe() - * controls for kill/create_process/signal - * controls for all/most functions in the system module * controls for all/most functions in spider * controls for threads */ diff --git a/src/security.h b/src/security.h index 26415fccdf..fbf693ff58 100644 --- a/src/security.h +++ b/src/security.h @@ -59,11 +59,74 @@ struct pike_creds #define FREE_PROT(X) do { if((X)->prot) free_object((X)->prot); (X)->prot=0; }while(0) +#define VALID_FILE_IO(name, access_type) \ + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) \ + { \ + int e; \ + struct svalue *base_sp=sp-args; \ + \ + if(!CHECK_SECURITY(SECURITY_BIT_CONDITIONAL_IO)) \ + error(name ": Permission denied.\n"); \ + \ + push_constant_text(name); \ + push_constant_text(access_type); \ + \ + for(e=0;e<args;e++) push_svalue(base_sp+e); \ + \ + safe_apply(OBJ2CREDS(current_creds)->user,"valid_io",args+2); \ + \ + switch(sp[-1].type) \ + { \ + case T_ARRAY: \ + case T_OBJECT: \ + case T_MAPPING: \ + assign_svalue(sp-args-1,sp-1); \ + pop_n_elems(args); \ + return; \ + \ + case T_INT: \ + switch(sp[-1].u.integer) \ + { \ + case 0: /* return 0 */ \ + errno=EPERM; \ + pop_n_elems(args+1); \ + push_int(0); \ + return; \ + \ + case 1: /* return 1 */ \ + pop_n_elems(args+1); \ + push_int(1); \ + return; \ + \ + case 2: /* ok */ \ + pop_stack(); \ + break; \ + \ + case 3: /* permission denied */ \ + error(name ": permission denied.\n"); \ + \ + default: \ + error("Error in user->valid_io, wrong return value.\n"); \ + } \ + break; \ + \ + default: \ + error("Error in user->valid_io, wrong return type.\n"); \ + \ + case T_STRING: \ + assign_svalue(sp-args-1,sp-1); \ + pop_stack(); \ + } \ + } + + extern struct object *current_creds; /* Prototypes begin here */ void init_pike_security(void); /* Prototypes end here */ - + + + #else #define INITIALIZE_PROT(X) @@ -73,6 +136,8 @@ void init_pike_security(void); #define init_pike_security() +#define VALID_FILE_IO(name, type) + #endif #endif diff --git a/src/signal_handler.c b/src/signal_handler.c index 5d986d3118..136cbb9036 100644 --- a/src/signal_handler.c +++ b/src/signal_handler.c @@ -21,9 +21,10 @@ #include "module_support.h" #include "operators.h" #include "builtin_functions.h" +#include "security.h" #include <signal.h> -RCSID("$Id: signal_handler.c,v 1.120 1999/04/02 20:52:48 hubbe Exp $"); +RCSID("$Id: signal_handler.c,v 1.121 1999/04/05 22:07:12 hubbe Exp $"); #ifdef HAVE_PASSWD_H # include <passwd.h> @@ -508,6 +509,11 @@ static void f_signal(int args) int signum; sigfunctype func; +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("signal: permission denied.\n"); +#endif + check_signals(0,0,0); if(args < 1) @@ -1029,6 +1035,10 @@ static void f_pid_status_set_priority(INT32 args) { char *to; int r; +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("pid_status_wait: permission denied.\n"); +#endif get_all_args("set_priority", args, "%s", &to); r = set_priority( THIS->pid, to ); pop_n_elems(args); @@ -1387,6 +1397,10 @@ void f_set_priority( INT32 args ) { int pid; char *plevel; +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("set_priority: permission denied.\n"); +#endif if(args == 1) { pid = 0; @@ -1528,6 +1542,11 @@ void f_create_process(INT32 args) struct svalue *tmp; int e; +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("Process.create_process: permission denied.\n"); +#endif + check_all_args("create_process",args, BIT_ARRAY, BIT_MAPPING | BIT_VOID, 0); switch(args) @@ -2120,11 +2139,14 @@ void f_create_process(INT32 args) storage.disabled = 1; #endif + do + { #if defined(HAVE_FORK1) && defined(_REENTRANT) - pid=fork1(); + pid=fork1(); #else - pid=fork(); + pid=fork(); #endif + }while(pid == -1 && (errno==EAGAIN || errno==EINTR)); UNSET_ONERROR(err); @@ -2457,6 +2479,10 @@ void f_fork(INT32 args) if(num_threads >1) error("You cannot use fork in a multithreaded application.\n"); #endif +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("fork: permission denied.\n"); +#endif /* THREADS_ALLOW_UID(); */ #if 0 && defined(HAVE_FORK1) && defined(_REENTRANT) @@ -2518,6 +2544,11 @@ static void f_kill(INT32 args) int pid; int res; +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("kill: permission denied.\n"); +#endif + if(args < 2) error("Too few arguments to kill().\n"); @@ -2553,6 +2584,11 @@ void f_kill(INT32 args) { HANDLE proc=INVALID_HANDLE_VALUE; +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("kill: permission denied.\n"); +#endif + if(args < 2) error("Too few arguments to kill().\n"); @@ -2625,6 +2661,11 @@ static void f_alarm(INT32 args) { long seconds; +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("alarm: permission denied.\n"); +#endif + if(args < 1) error("Too few arguments to signame()\n"); @@ -2646,6 +2687,11 @@ static void f_ualarm(INT32 args) #endif /* !HAVE_UALARM */ long useconds; +#ifdef PIKE_SECURITY + if(!CHECK_SECURITY(SECURITY_BIT_SECURITY)) + error("ualarm: permission denied.\n"); +#endif + if(args < 1) error("Too few arguments to ualarm()\n"); -- GitLab