diff -urNX nopatch linux-2.4.18.orig/arch/i386/Makefile linux-2.4.18/arch/i386/Makefile --- linux-2.4.18.orig/arch/i386/Makefile Thu Apr 12 21:20:31 2001 +++ linux-2.4.18/arch/i386/Makefile Mon Feb 25 15:48:03 2002 @@ -88,7 +88,7 @@ HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o -SUBDIRS += arch/i386/kernel arch/i386/mm arch/i386/lib +SUBDIRS += arch/i386/tools arch/i386/kernel arch/i386/mm arch/i386/lib CORE_FILES := arch/i386/kernel/kernel.o arch/i386/mm/mm.o $(CORE_FILES) LIBS := $(TOPDIR)/arch/i386/lib/lib.a $(LIBS) $(TOPDIR)/arch/i386/lib/lib.a @@ -140,6 +140,7 @@ archclean: @$(MAKEBOOT) clean + @$(MAKE) -C arch/$(ARCH)/tools clean archmrproper: diff -urNX nopatch linux-2.4.18.orig/arch/i386/kernel/Makefile linux-2.4.18/arch/i386/kernel/Makefile --- linux-2.4.18.orig/arch/i386/kernel/Makefile Fri Nov 9 23:21:21 2001 +++ linux-2.4.18/arch/i386/kernel/Makefile Mon Feb 25 15:48:03 2002 @@ -41,4 +41,11 @@ obj-$(CONFIG_X86_IO_APIC) += io_apic.o acpitable.o obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o +entry.o: $(TOPDIR)/include/asm-i386/offsets.h + +$(TOPDIR)/include/asm-i386/offsets.h: $(TOPDIR)/arch/i386/tools/printoffset + +$(TOPDIR)/arch/i386/tools/printoffset: + $(MAKE) -C $(TOPDIR)/arch/i386/tools + include $(TOPDIR)/Rules.make diff -urNX nopatch linux-2.4.18.orig/arch/i386/kernel/entry.S linux-2.4.18/arch/i386/kernel/entry.S --- linux-2.4.18.orig/arch/i386/kernel/entry.S Sat Nov 3 02:18:49 2001 +++ linux-2.4.18/arch/i386/kernel/entry.S Mon Feb 25 15:48:03 2002 @@ -70,14 +70,8 @@ /* * these are offsets into the task-struct. */ -state = 0 -flags = 4 -sigpending = 8 -addr_limit = 12 -exec_domain = 16 -need_resched = 20 -tsk_ptrace = 24 -processor = 52 + +#include ENOSYS = 38 diff -urNX nopatch linux-2.4.18.orig/arch/i386/tools/Makefile linux-2.4.18/arch/i386/tools/Makefile --- linux-2.4.18.orig/arch/i386/tools/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.18/arch/i386/tools/Makefile Mon Feb 25 15:48:03 2002 @@ -0,0 +1,18 @@ +# Makefile for i386 kernel build tools + +TARGET=$(TOPDIR)/include/asm-$(ARCH)/offsets.h + +offsets all: $(TARGET) + +$(TARGET): printoffsets + ./printoffsets > $(TARGET) + +printoffsets: printoffsets.o + $(CC) $(CFLAGS) $^ -o $@ + +printoffsets.o: $(TOPDIR)/include/linux/sched.h + +clean: + rm -f $(TARGET) printoffsets + +include $(TOPDIR)/Rules.make diff -urNX nopatch linux-2.4.18.orig/arch/i386/tools/printoffsets.c linux-2.4.18/arch/i386/tools/printoffsets.c --- linux-2.4.18.orig/arch/i386/tools/printoffsets.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.18/arch/i386/tools/printoffsets.c Mon Feb 25 15:48:03 2002 @@ -0,0 +1,37 @@ +#define _LOOSE_KERNEL_NAMES +#include +#include + +#define OFFSET(structure, member) ((unsigned long)(&(((structure *)NULL)->member))) + +struct i386_offset { + const char identifier[64]; + unsigned long value; +} offsets[] = { + { "state", OFFSET(struct task_struct, state) }, + { "flags", OFFSET(struct task_struct, flags), }, + { "sigpending", OFFSET(struct task_struct, sigpending), }, + { "addr_limit", OFFSET(struct task_struct, addr_limit), }, + { "exec_domain", OFFSET(struct task_struct, exec_domain), }, + { "need_resched", OFFSET(struct task_struct, need_resched), }, + { "tsk_ptrace", OFFSET(struct task_struct, ptrace), }, + { "processor", OFFSET(struct task_struct, processor), }, +}; + +extern int printf (const char *, ...); + +int main(int argc, char *argv[]) +{ + int i; + + printf("#ifndef _I386_OFFSETS_H_\n#define _I386_OFFSETS_H_\n\n"); + printf("/* \n"); + printf(" * offsets for i386\n"); + printf(" * DO NOT TOUCH\n"); + printf(" * generated by arch/i386/tools/print_offset.c\n"); + printf(" */\n\n"); + for(i = 0; i < (sizeof(offsets) / sizeof(struct i386_offset)); i++) + printf("%s =\t%lu\n", offsets[i].identifier, offsets[i].value); + printf("\n#endif\n"); + return 0; +} diff -urNX nopatch linux-2.4.18.orig/fs/exec.c linux-2.4.18/fs/exec.c --- linux-2.4.18.orig/fs/exec.c Fri Dec 21 18:41:55 2001 +++ linux-2.4.18/fs/exec.c Mon Feb 25 19:33:09 2002 @@ -20,6 +20,10 @@ * table to check for several different types of binary formats. We keep * trying until we recognize the file or we run out of supported binary * formats. + * + * Modified formula for evolving capabilities to allow nice SUID emulation + * which work together with (future) VFS capabilities implementation. + * Feb 2002 by Marek Zelem */ #include @@ -624,11 +628,23 @@ bprm->e_uid = current->euid; bprm->e_gid = current->egid; + /* We don't have VFS support for capabilities yet */ + cap_clear(bprm->cap_permitted); + cap_set_full(bprm->cap_inheritable); + cap_set_full(bprm->cap_effective); + if(!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)) { /* Set-uid? */ - if (mode & S_ISUID) + if (mode & S_ISUID) { bprm->e_uid = inode->i_uid; - + if (bprm->e_uid == 0) { + if (!issecure(SECURE_NOROOT)) + cap_set_full(bprm->cap_permitted); + } + else { + cap_clear(bprm->cap_effective); + } + } /* Set-gid? */ /* * If setgid is set but no group execute bit then this @@ -639,28 +655,6 @@ bprm->e_gid = inode->i_gid; } - /* We don't have VFS support for capabilities yet */ - cap_clear(bprm->cap_inheritable); - cap_clear(bprm->cap_permitted); - cap_clear(bprm->cap_effective); - - /* To support inheritance of root-permissions and suid-root - * executables under compatibility mode, we raise all three - * capability sets for the file. - * - * If only the real uid is 0, we only raise the inheritable - * and permitted sets of the executable file. - */ - - if (!issecure(SECURE_NOROOT)) { - if (bprm->e_uid == 0 || current->uid == 0) { - cap_set_full(bprm->cap_inheritable); - cap_set_full(bprm->cap_permitted); - } - if (bprm->e_uid == 0) - cap_set_full(bprm->cap_effective); - } - memset(bprm->buf,0,BINPRM_BUF_SIZE); return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE); } @@ -671,6 +665,11 @@ * * The formula used for evolving capabilities is: * + * (***) pP' = (fP & X) | (fI & pI) + * pI' = pP' + * pE' = ((pP' & pE) | fP) & X & fE + * + * original was: * pI' = pI * (***) pP' = (fP & X) | (fI & pI) * pE' = pP' & fE [NB. fE is 0 or ~0] @@ -717,6 +716,14 @@ * capability rules */ if (current->pid != 1) { current->cap_permitted = new_permitted; +/* This is to allow good SUID emulation (Marek Zelem ) */ + current->cap_inheritable = new_permitted; + working = + cap_intersect(new_permitted,current->cap_effective); + new_permitted = + cap_combine(working,bprm->cap_permitted); + new_permitted = cap_intersect(new_permitted, cap_bset); +/* END of good SUID emulation (Marek Zelem ) */ current->cap_effective = cap_intersect(new_permitted, bprm->cap_effective); } diff -urNX nopatch linux-2.4.18.orig/include/linux/capability.h linux-2.4.18/include/linux/capability.h --- linux-2.4.18.orig/include/linux/capability.h Thu Nov 22 20:46:19 2001 +++ linux-2.4.18/include/linux/capability.h Wed Feb 27 17:00:49 2002 @@ -14,7 +14,7 @@ #define _LINUX_CAPABILITY_H #include -#include +//#include /* User-level do most of the mapping between kernel and user capabilities based on the version tag given by the kernel. The @@ -303,8 +303,9 @@ #define CAP_EMPTY_SET to_cap_t(0) #define CAP_FULL_SET to_cap_t(~0) -#define CAP_INIT_EFF_SET to_cap_t(~0 & ~CAP_TO_MASK(CAP_SETPCAP)) -#define CAP_INIT_INH_SET to_cap_t(0) +//#define CAP_INIT_EFF_SET to_cap_t(~0 & ~CAP_TO_MASK(CAP_SETPCAP)) +#define CAP_INIT_EFF_SET to_cap_t(~0) +#define CAP_INIT_INH_SET to_cap_t(~0) #define CAP_TO_MASK(x) (1 << (x)) #define cap_raise(c, flag) (cap_t(c) |= CAP_TO_MASK(flag)) diff -urNX nopatch linux-2.4.18.orig/include/linux/timex.h linux-2.4.18/include/linux/timex.h --- linux-2.4.18.orig/include/linux/timex.h Thu Nov 22 20:46:18 2001 +++ linux-2.4.18/include/linux/timex.h Mon Feb 25 15:48:03 2002 @@ -52,6 +52,7 @@ #define _LINUX_TIMEX_H #include +#include /* * The following defines establish the engineering parameters of the PLL diff -urNX nopatch linux-2.4.18.orig/kernel/signal.c linux-2.4.18/kernel/signal.c --- linux-2.4.18.orig/kernel/signal.c Thu Nov 22 01:26:27 2001 +++ linux-2.4.18/kernel/signal.c Mon Feb 25 15:48:03 2002 @@ -514,6 +514,10 @@ ret = -EINVAL; if (sig < 0 || sig > _NSIG) goto out_nolock; + /* Zombie task cannot be killed! */ + ret = -ESRCH; + if ( t->state == TASK_ZOMBIE ) + goto out_nolock; /* The somewhat baroque permissions check... */ ret = -EPERM; if (bad_signal(sig, info, t)) diff -urNX nopatch linux-2.4.18.orig/kernel/sys.c linux-2.4.18/kernel/sys.c --- linux-2.4.18.orig/kernel/sys.c Tue Sep 18 23:10:43 2001 +++ linux-2.4.18/kernel/sys.c Mon Feb 25 15:48:03 2002 @@ -481,6 +481,8 @@ !current->keep_capabilities) { cap_clear(current->cap_permitted); cap_clear(current->cap_effective); +/* This is to allow good SETUID emulation (Marek Zelem ) */ + cap_clear(current->cap_inheritable); } if (old_euid == 0 && current->euid != 0) { cap_clear(current->cap_effective); diff -urNX nopatch linux-2.4.18.orig/kernel/kmod.c linux-2.4.18/kernel/kmod.c --- linux-2.4.18.orig/kernel/kmod.c Wed Jul 18 03:23:50 2001 +++ linux-2.4.18/kernel/kmod.c Thu Feb 28 15:54:25 2002 @@ -125,6 +125,8 @@ curtask->euid = curtask->fsuid = 0; curtask->egid = curtask->fsgid = 0; cap_set_full(curtask->cap_effective); + cap_set_full(curtask->cap_inheritable); + cap_set_full(curtask->cap_permitted); /* Allow execve args to be in kernel space. */ set_fs(KERNEL_DS);