diff options
author | Robert de Bath <rdebath@poboxes.com> | 1996-05-31 21:33:17 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:30:46 +0200 |
commit | e85ee07172eccafd9441362e774f7b184810d008 (patch) | |
tree | 5dc12259ab7a61b12d9df284fe58ad5cb312c526 /elksemu | |
parent | dcc973ea3e31710429858c99d4f040334ac67c06 (diff) | |
download | dev86-e85ee07172eccafd9441362e774f7b184810d008.tar.gz |
Import Dev86-0.0.6.tar.gzv0.0.6
Diffstat (limited to 'elksemu')
-rw-r--r-- | elksemu/Kernel_patch | 6 | ||||
-rw-r--r-- | elksemu/Makefile | 20 | ||||
-rw-r--r-- | elksemu/Security | 20 | ||||
-rw-r--r-- | elksemu/V-files.tar | bin | 10240 -> 20480 bytes | |||
-rw-r--r-- | elksemu/Version | 2 | ||||
-rw-r--r-- | elksemu/binfmt_elks.c | 118 | ||||
-rw-r--r-- | elksemu/elks.c | 41 | ||||
-rw-r--r-- | elksemu/elks_signal.c | 14 | ||||
-rw-r--r-- | elksemu/elks_sys.c | 4 |
9 files changed, 204 insertions, 21 deletions
diff --git a/elksemu/Kernel_patch b/elksemu/Kernel_patch index 451455f..cc4ca40 100644 --- a/elksemu/Kernel_patch +++ b/elksemu/Kernel_patch @@ -1,6 +1,8 @@ - This kernel patch allows you to run Linux-8086 executables transparently -on a Linux-i386 system. It requires V0.0.2 of elksemu in "/lib/elksemu". +on a Linux-i386 (1.2.13) system. +It requires V0.0.2 or better of elksemu in the file "/lib/elksemu". + +If you are using kernel 1.3.* or later try the module: binfmt_elks.o --- orig-13/fs/exec.c Sun Sep 24 13:22:37 1995 +++ linux/fs/exec.c Sun Feb 11 20:11:47 1996 diff --git a/elksemu/Makefile b/elksemu/Makefile index cee13ac..92aa516 100644 --- a/elksemu/Makefile +++ b/elksemu/Makefile @@ -11,8 +11,8 @@ OBJ=elks.o elks_sys.o elks_signal.o elksemu: $(OBJ) $(CC) $(CFLAGS) -o elksemu $(OBJ) -$(OBJ): elks.h elks_sys.o: call_tab.v +$(OBJ): elks.h call_tab.v: dummy -cp -p ../libc/syscall/call_tab.v . 2>/dev/null @@ -20,10 +20,24 @@ call_tab.v: dummy dummy: -# The kernel patch _requires_ this location. +# The kernel patch or module _requires_ this location. install: elksemu - install -s -m 755 elksemu /lib/elksemu + install -s -o root -g root -m 4111 elksemu /lib/elksemu tar cvf V-files.tar call_tab.v defn_tab.v clean: rm -f $(OBJ) elksemu call_tab.v defn_tab.v + +module: binfmt_elks.o + +# HOW to compile the module... + +# This matches my compile; yours may be different. +binfmt_elks.o: binfmt_elks.c + gcc -O -c -fomit-frame-pointer -DCPU=386 -D__KERNEL__ -DMODULE -DMODVERSIONS -include /usr/include/linux/modversions.h binfmt_elks.c + +# This is another option +# gcc -O -c -fomit-frame-pointer -DCPU=386 -D__KERNEL__ -DMODULE binfmt_elks.c +# Or this ... +# gcc -O -c -fomit-frame-pointer -D__KERNEL__ -DMODULE -DCONFIG_MODVERSIONS binfmt_elks.c + diff --git a/elksemu/Security b/elksemu/Security new file mode 100644 index 0000000..2fbef8b --- /dev/null +++ b/elksemu/Security @@ -0,0 +1,20 @@ +The install scripts now install /lib/elksemu as a suid-root executable. +This gives two additional facilities when running elks executables. + +1) It is now possible to run programs that are execute only, without + read permission, as the file is opened while we have superuser + access. + +2) If the ELKS executable has suid or sgid bits set these will be honoured. + +The user now needs execute access to run an executable, this is checked. + +If the executable does not have either suid/sgid bits set then all +extra permissions will be dropped within the first few lines of the +main() function. Because of this you need only check this tiny +piece of code if you intend never to use suid. + +If you have any problem with elksemu being suid-root the program will +run as before, with no complaints, if you remove the suid permission. + +Rob. diff --git a/elksemu/V-files.tar b/elksemu/V-files.tar Binary files differindex c5e6082..3e1227c 100644 --- a/elksemu/V-files.tar +++ b/elksemu/V-files.tar diff --git a/elksemu/Version b/elksemu/Version index 38a680f..66a1fd7 100644 --- a/elksemu/Version +++ b/elksemu/Version @@ -1 +1 @@ -Version elksemu-0.0.4 +Version elksemu-0.0.6 diff --git a/elksemu/binfmt_elks.c b/elksemu/binfmt_elks.c new file mode 100644 index 0000000..09e5a29 --- /dev/null +++ b/elksemu/binfmt_elks.c @@ -0,0 +1,118 @@ +/* + * linux/fs/binfmt_elks.c + * + * Copyright (C) 1996 Martin von Löwis + * original #!-checking implemented by tytso. + * ELKS hack added by Chad Page... + * Cleaned up some more by Robert de Bath + * I can't make it work with 1.2.13 tho! :-( + */ + +#include <linux/module.h> +#ifndef LINUX_VERSION_CODE +#include <linux/version.h> +#endif +#include <linux/string.h> +#include <linux/stat.h> +#include <linux/malloc.h> +#include <linux/binfmts.h> + +static int do_load_elksaout(struct linux_binprm *bprm,struct pt_regs *regs) +{ + char *cp, *interp, *i_name, *i_arg; + int retval; + + /* What a horrible hack! :-) */ + if ((bprm->buf[0] != 1) || (bprm->buf[1] != 3) || + (bprm->buf[2] != 0x20) || (bprm->buf[3] != 4) || + bprm->sh_bang) + return -ENOEXEC; + + bprm->sh_bang++; + iput(bprm->inode); +#if LINUX_VERSION_CODE >= 0x010300 + bprm->dont_iput=1; +#endif + + interp = "/lib/elksemu"; + i_name = interp; + i_arg = 0; + + for (cp=i_name; *cp && (*cp != ' ') && (*cp != '\t'); cp++) { + if (*cp == '/') + i_name = cp+1; + } + + /* + * OK, we've parsed out the interpreter name and + * (optional) argument. + * Splice in (1) the interpreter's name for argv[0] + * (2) (optional) argument to interpreter + * (3) filename of shell script (replace argv[0]) + * + * This is done in reverse order, because of how the + * user environment and arguments are stored. + */ + remove_arg_zero(bprm); + bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2); + bprm->argc++; + if (i_arg) { + bprm->p = copy_strings(1, &i_arg, bprm->page, bprm->p, 2); + bprm->argc++; + } + bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2); + bprm->argc++; + if (!bprm->p) + return -E2BIG; + /* + * OK, now restart the process with the interpreter's inode. + * Note that we use open_namei() as the name is now in kernel + * space, and we don't need to copy it. + */ + retval = open_namei(interp, 0, 0, &bprm->inode, NULL); + if (retval) + return retval; +#if LINUX_VERSION_CODE >= 0x010300 + bprm->dont_iput=0; +#endif + retval=prepare_binprm(bprm); + if(retval<0) + return retval; + return search_binary_handler(bprm,regs); +} + +static int load_elksaout(struct linux_binprm *bprm,struct pt_regs *regs) +{ + int retval; + MOD_INC_USE_COUNT; + retval = do_load_elksaout(bprm,regs); + MOD_DEC_USE_COUNT; + return retval; +} + +struct linux_binfmt elksaout_format = { +#ifndef MODULE + NULL, 0, load_elksaout, NULL, NULL +#else + NULL, &mod_use_count_, load_elksaout, NULL, NULL +#endif +}; + +int init_elksaout_binfmt(void) { + return register_binfmt(&elksaout_format); +} + +#ifdef MODULE +#if LINUX_VERSION_CODE < 0x010300 +#include <linux/version.h> +char kernel_version[] = UTS_RELEASE; +#endif +int init_module(void) +{ + return init_elksaout_binfmt(); +} + +void cleanup_module( void) { + unregister_binfmt(&elksaout_format); +} +#endif diff --git a/elksemu/elks.c b/elksemu/elks.c index f84c994..10d9d78 100644 --- a/elksemu/elks.c +++ b/elksemu/elks.c @@ -21,8 +21,11 @@ volatile struct vm86_struct elks_cpu; unsigned char *elks_base; /* Paragraph aligned */ +#ifdef DEBUG #define dbprintf(x) db_printf x -/**/ +#else +#define dbprintf(x) +#endif static void elks_init() { @@ -195,12 +198,36 @@ void build_stack(char ** argv, char ** envp) void main(int argc, char *argv[], char *envp[]) { int fd; - dbprintf(("ELKSEMU 0.01 Alpha\n")); - if(argc==1) + struct stat st; + int ruid, euid, rgid, egid; + + if(argc<=1) { fprintf(stderr,"elksemu cmd args.....\n"); exit(1); } + /* This uses the _real_ user ID If the file is exec only that's */ + /* ok cause the suid root will override. */ + + if( access(argv[1], X_OK) < 0 + || stat(argv[1], &st) < 0 + || (fd=open(argv[1], O_RDONLY)) < 0) + { + perror(argv[1]); + exit(1); + } + + /* Check the suid bits ... */ + ruid = getuid(); rgid = getgid(); + euid = ruid; egid = rgid; + if( st.st_mode & S_ISUID ) euid = st.st_uid; + if( st.st_mode & S_ISGID ) egid = st.st_gid; + + /* Set the _real_ permissions, or revoke superuser priviliages */ + setregid(rgid, egid); + setreuid(ruid, euid); + + dbprintf(("ELKSEMU 0.0.6 Alpha\n")); elks_init(); /* The Linux vm will deal with not allocating the unused pages */ @@ -219,12 +246,6 @@ void main(int argc, char *argv[], char *envp[]) fprintf(stderr, "Elks memory is at an illegal address\n"); exit(255); } - fd=open(argv[1], O_RDONLY); - if(fd==-1) - { - perror(argv[1]); - exit(1); - } if(load_elks(fd) < 0) { @@ -240,6 +261,7 @@ void main(int argc, char *argv[], char *envp[]) run_elks(); } +#ifdef DEBUG void db_printf(const char * fmt, ...) { static FILE * db_fd = 0; @@ -256,3 +278,4 @@ static FILE * db_fd = 0; rv = vfprintf(db_fd,fmt,ptr); va_end(ptr); } +#endif diff --git a/elksemu/elks_signal.c b/elksemu/elks_signal.c index 2bf1e55..4b8e0c5 100644 --- a/elksemu/elks_signal.c +++ b/elksemu/elks_signal.c @@ -22,15 +22,17 @@ void sig_trap(int signo) int elks_signal(int bx,int cx,int dx,int di,int si) { - int rv; + void (*oldsig)(int) = 0; if( bx < 0 || bx >= NSIG ) { errno = EINVAL; return -1; } - if( cx == 0 ) rv = (signal(bx, SIG_DFL) == SIG_ERR); - else if( cx == 1 ) rv = (signal(bx, SIG_IGN) == SIG_ERR); + if( cx == 0 ) oldsig = signal(bx, SIG_DFL); + else if( cx == 1 ) oldsig = signal(bx, SIG_IGN); else { elks_sigtrap = cx; - rv = (signal(bx, sig_trap) == SIG_ERR); + oldsig = signal(bx, sig_trap); } - - return -rv; + if( oldsig == SIG_ERR) return -1; + if( oldsig == SIG_DFL) return 0; + if( oldsig == SIG_IGN) return 1; + return 2; } diff --git a/elksemu/elks_sys.c b/elksemu/elks_sys.c index 7ca946c..586ee9b 100644 --- a/elksemu/elks_sys.c +++ b/elksemu/elks_sys.c @@ -22,7 +22,11 @@ #include <dirent.h> #include "elks.h" +#ifdef DEBUG #define dbprintf(x) db_printf x +#else +#define dbprintf(x) +#endif #define sys_signal elks_signal extern int elks_signal(int bx,int cx,int dx,int di,int si); |