summaryrefslogtreecommitdiff
path: root/elksemu
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>1996-05-31 21:33:17 +0200
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:30:46 +0200
commite85ee07172eccafd9441362e774f7b184810d008 (patch)
tree5dc12259ab7a61b12d9df284fe58ad5cb312c526 /elksemu
parentdcc973ea3e31710429858c99d4f040334ac67c06 (diff)
downloaddev86-e85ee07172eccafd9441362e774f7b184810d008.tar.gz
Import Dev86-0.0.6.tar.gzv0.0.6
Diffstat (limited to 'elksemu')
-rw-r--r--elksemu/Kernel_patch6
-rw-r--r--elksemu/Makefile20
-rw-r--r--elksemu/Security20
-rw-r--r--elksemu/V-files.tarbin10240 -> 20480 bytes
-rw-r--r--elksemu/Version2
-rw-r--r--elksemu/binfmt_elks.c118
-rw-r--r--elksemu/elks.c41
-rw-r--r--elksemu/elks_signal.c14
-rw-r--r--elksemu/elks_sys.c4
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
index c5e6082..3e1227c 100644
--- a/elksemu/V-files.tar
+++ b/elksemu/V-files.tar
Binary files differ
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);