diff -ruNp linux-2.6.15.5/Makefile linux-2.6.15.5-cher1/Makefile --- linux-2.6.15.5/Makefile Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/Makefile Thu Mar 2 12:58:39 2006 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 15 -EXTRAVERSION = .5 +EXTRAVERSION = .5-cher1 NAME=Sliding Snow Leopard # *DOCUMENTATION* diff -ruNp linux-2.6.15.5/SYSCALLS.i368 linux-2.6.15.5-cher1/SYSCALLS.i368 --- linux-2.6.15.5/SYSCALLS.i368 Thu Jan 1 03:00:00 1970 +++ linux-2.6.15.5-cher1/SYSCALLS.i368 Thu Mar 2 12:58:20 2006 @@ -0,0 +1,299 @@ +sys_exit OK +sys_fork arch/i386/kernel/process.c* CAP +sys_read OK +sys_write OK +sys_open fs/open.c CAP +sys_close OK +sys_waitpid kernel/exit.c CAP +sys_creat fs/open.c CAP +sys_link fs/namei.c CAP +sys_unlink fs/namei.c CAP +sys_execve arch/i386/kernel/process.c CAP +sys_chdir fs/open.c CAP +sys_time OK +sys_mknod fs/namei.c CAP +sys_chmod fs/open.c CAP +sys_lchown16 kernel/uid16.c CAP +sys_ni_syscall --- +sys_stat fs/stat.c CAP +sys_lseek fs/read_write.c CAP +sys_getpid OK +sys_mount fs/namespace.c CAP +sys_oldumount fs/namespace.c CAP +sys_setuid16 kernel/uid16.c CAP +sys_getuid16 kernel/uid16.c OK +sys_stime fs/time.c CAP +sys_ptrace kernel/ptrace.c CAP +sys_alarm kernel/timer.c OK +sys_fstat fs/stat.c CAP +sys_pause kernel/signal.c CAP +sys_utime fs/open.c CAP +sys_ni_syscall --- +sys_ni_syscall --- +sys_access fs/open.c CAP +sys_nice kernel/sched.c CAP +sys_ni_syscall --- +sys_sync fs/buffer.c CAP +sys_kill kernel/signal.c CAP +sys_rename fs/namei.c CAP +sys_mkdir fs/namei.c CAP +sys_rmdir fs/namei.c CAP +sys_dup fs/fcntl.c CAP +sys_pipe arch/i386/kernel/sys_i386.c CAP +sys_times OK +sys_ni_syscall --- +sys_brk OK +sys_setgid16 kernel/uid16.c CAP +sys_getgid16 kernel/uid16.c OK +sys_signal OK +sys_geteuid16 kernel/uid16.c OK +sys_getegid16 kernel/uid16.c OK +sys_acct kernel/acct.c CAP +sys_umount fs/namespace.c CAP +sys_ni_syscall --- +sys_ioctl fs/ioctl.c CAP +sys_fcntl fs/fcntl.c CAP +sys_ni_syscall --- +sys_setpgid kernel/sys.c CAP +sys_ni_syscall --- +sys_olduname arch/i386/kernel/sys_i386.c CAP +sys_umask kernel/sys.c CAP +sys_chroot fs/open.c CAP +sys_ustat fs/super.c CAP +sys_dup2 fs/fcntl.c CAP +sys_getppid OK +sys_getpgrp kernel/sys.c OK +sys_setsid kernel/sys.c CAP +sys_sigaction OK +sys_sgetmask OK +sys_ssetmask OK +sys_setreuid16 kernel/uid16.c CAP +sys_setregid16 kernel/uid16.c CAP +sys_sigsuspend OK +sys_sigpending OK +sys_sethostname kernel/sys.c CAP +sys_setrlimit kernel/sys.c CAP +sys_old_getrlimit kernel/sys.c OK +sys_getrusage kernel/sys.c OK +sys_gettimeofday OK +sys_settimeofday kernel/time.c CAP +sys_getgroups16 kernel/uid16.c CAP +sys_setgroups16 kernel/uid16.c CAP +old_select arch/i386/kernel/sys_i386.c OK +sys_symlink fs/namei.c CAP +sys_lstat fs/stat.c CAP +sys_readlink fs/stat.c CAP +sys_uselib fs/exec.c CAP +sys_swapon mm/swapfile.c CAP +sys_reboot kernel/sys.c CAP +old_readdir fs/readdir.c CAP +old_mmap arch/i386/kernel/sys_i386.c CAP +sys_munmap OK +sys_truncate fs/open.c CAP +sys_ftruncate fs/open.c CAP +sys_fchmod fs/open.c CAP +sys_fchown16 kernel/uid16.c CAP +sys_getpriority kernel/sys.c CAP +sys_setpriority kernel/sys.c CAP +sys_ni_syscall --- +sys_statfs fs/open.c CAP +sys_fstatfs fs/open.c CAP +sys_ioperm arch/i386/kernel/ioport.c CAP +sys_socketcall net/socket.c CAP +sys_syslog kernel/printk.c CAP +sys_setitimer OK +sys_getitimer OK +sys_newstat fs/stat.c CAP +sys_newlstat fs/stat.c CAP +sys_newfstat fs/stat.c CAP +sys_uname arch/i386/kernel/sys_i386.c CAP +sys_iopl arch/i386/kernel/ioport.c CAP +sys_vhangup fs/open.c CAP +sys_ni_syscall --- +sys_vm86old arch/i386/kernel/vm86.c CAP +sys_wait4 kernel/exit.c CAP +sys_swapoff mm/swapfile.c CAP +sys_sysinfo kernel/timer.c CAP +sys_ipc arch/i386/kernel/sys_i386.c CAP +sys_fsync fs/buffer.c CAP +sys_sigreturn OK +sys_clone arch/i386/kernel/process.c* CAP +sys_setdomainname kernel/sys.c CAP +sys_newuname kernel/sys.c OK +sys_modify_ldt arch/i386/kernel/ldt.c CAP +sys_adjtimex kernel/time.c CAP +sys_mprotect mm/mprotect.c CAP +sys_sigprocmask OK +sys_ni_syscall --- +sys_init_module kernel/module.c CAP +sys_delete_module kernel/module.c CAP +sys_ni_syscall --- +sys_quotactl fs/quota.c CAP +sys_getpgid kernel/sys.c CAP +sys_fchdir fs/open.c CAP +sys_bdflush fs/buffer.c CAP +sys_sysfs fs/filesystems.c CAP +sys_personality kernel/exec_domain.c CAP +sys_ni_syscall --- +sys_setfsuid16 kernel/uid16.c CAP +sys_setfsgid16 kernel/uid16.c CAP +sys_llseek fs/read_write.c CAP +sys_getdents fs/readdir.c CAP +sys_select OK +sys_flock fs/locks.c CAP +sys_msync OK +sys_readv OK +sys_writev OK +sys_getsid kernel/sys.c CAP +sys_fdatasync fs/buffer.c CAP +sys_sysctl kernel/sysctl.c CAP +sys_mlock mm/mlock.c CAP +sys_munlock mm/mlock.c CAP +sys_mlockall mm/mlock.c CAP +sys_munlockall mm/mlock.c CAP +sys_sched_setparam kernel/sched.c CAP +sys_sched_getparam kernel/sched.c CAP +sys_sched_setscheduler kernel/sched.c CAP +sys_sched_getscheduler kernel/sched.c CAP +sys_sched_yield kernel/sched.c OK +sys_sched_get_priority_max kernel/sched.c CAP +sys_sched_get_priority_min kernel/sched.c CAP +sys_sched_rr_get_interval kernel/sched.c CAP +sys_nanosleep OK +sys_mremap mm/mremap.c CAP +sys_setresuid16 kernel/uid16.c CAP +sys_getresuid16 OK +sys_vm86 arch/i386/kernel/vm86.c CAP +sys_ni_syscall --- +sys_poll OK +sys_nfsservctl fs/nfsctl.c CAP +sys_setresgid16 kernel/uid16.c CAP +sys_getresgid16 OK +sys_prctl kernel/sys.c CAP +sys_rt_sigreturn OK +sys_rt_sigaction OK +sys_rt_sigprocmask OK +sys_rt_sigpending OK +sys_rt_sigtimedwait OK +sys_rt_sigqueueinfo kernel/signal.c CAP +sys_rt_sigsuspend OK +sys_pread64 fs/read_write.c CAP +sys_pwrite64 fs/read_write.c CAP +sys_chown16 kernel/uid16.c CAP +sys_getcwd fs/dcache.c CAP +sys_capget kernel/capability.c CAP +sys_capset kernel/capability.c CAP +sys_sigaltstack OK +sys_sendfile fs/read_write.c CAP +sys_ni_syscall --- +sys_ni_syscall --- +sys_vfork arch/i386/kernel/process.c* CAP +sys_getrlimit kernel/sys.c OK +sys_mmap2 arch/i386/kernel/sys_i386.c CAP +sys_truncate64 fs/open.c CAP +sys_ftruncate64 fs/open.c CAP +sys_stat64 fs/stat.c CAP +sys_lstat64 fs/stat.c CAP +sys_fstat64 fs/stat.c CAP +sys_lchown fs/open.c CAP +sys_getuid kernel/timer.c OK +sys_getgid OK +sys_geteuid OK +sys_getegid OK +sys_setreuid kernel/sys.c CAP +sys_setregid kernel/sys.c CAP +sys_getgroups kernel/sys.c CAP +sys_setgroups kernel/sys.c CAP +sys_fchown fs/open.c CAP +sys_setresuid kernel/sys.c CAP +sys_getresuid kernel/sys.c CAP +sys_setresgid kernel/sys.c CAP +sys_getresgid kernel/sys.c CAP +sys_chown fs/open.c CAP +sys_setuid kernel/sys.c CAP +sys_setgid kernel/sys.c CAP +sys_setfsuid kernel/sys.c CAP +sys_setfsgid kernel/sys.c CAP +sys_pivot_root fs/namespace.c CAP +sys_mincore mm/mincore.c CAP +sys_madvise mm/madvise.c CAP +sys_getdents64 fs/readdir.c CAP +sys_fcntl64 fs/fcntl.c CAP +sys_ni_syscall --- +sys_ni_syscall --- +sys_gettid OK +sys_readahead mm/filemap.c CAP +sys_setxattr fs/xattr.c CAP +sys_lsetxattr fs/xattr.c CAP +sys_fsetxattr fs/xattr.c CAP +sys_getxattr fs/xattr.c CAP +sys_lgetxattr fs/xattr.c CAP +sys_fgetxattr fs/xattr.c CAP +sys_listxattr fs/xattr.c CAP +sys_llistxattr fs/xattr.c CAP +sys_flistxattr fs/xattr.c CAP +sys_removexattr fs/xattr.c CAP +sys_lremovexattr fs/xattr.c CAP +sys_fremovexattr fs/xattr.c CAP +sys_tkill kernel/signal.c CAP +sys_sendfile64 fs/read_write.c CAP +sys_futex OK +sys_sched_setaffinity kernel/sched.c CAP +sys_sched_getaffinity kernel/sched.c CAP +sys_set_thread_area OK +sys_get_thread_area OK +sys_io_setup fs/aio.c CAP +sys_io_destroy fs/aio.c CAP +sys_io_getevents fs/aio.c CAP +sys_io_submit fs/aio.c CAP +sys_io_cancel fs/aio.c CAP +sys_fadvise64 mm/fadvise.c CAP +sys_ni_syscall --- +sys_exit_group OK +sys_lookup_dcookie fs/dcookies.c CAP +sys_epoll_create fs/eventpoll.c CAP +sys_epoll_ctl fs/eventpoll.c CAP +sys_epoll_wait fs/eventpoll.c CAP +sys_remap_file_pages fs/fremap.c CAP +sys_set_tid_address OK +sys_timer_create kernel/posix-timers.c CAP +sys_timer_settime kernel/posix-timers.c CAP +sys_timer_gettime kernel/posix-timers.c CAP +sys_timer_getoverrun kernel/posix-timers.c CAP +sys_timer_delete kernel/posix-timers.c CAP +sys_clock_settime kernel/posix-timers.c CAP +sys_clock_gettime kernel/posix-timers.c CAP +sys_clock_getres kernel/posix-timers.c CAP +sys_clock_nanosleep kernel/posix-timers.c CAP +sys_statfs64 fs/open.c CAP +sys_fstatfs64 fs/open.c CAP +sys_tgkill kernel/signal.c CAP +sys_utimes fs/open.c CAP +sys_fadvise64_64 mm/fadvise.c CAP +sys_ni_syscall --- +sys_mbind mm/mempolicy.c CAP +sys_get_mempolicy mm/mempolicy.c CAP +sys_set_mempolicy mm/mempolicy.c CAP +sys_mq_open ipc/mqueue.c CAP +sys_mq_unlink ipc/mqueue.c CAP +sys_mq_timedsend ipc/mqueue.c CAP +sys_mq_timedreceive ipc/mqueue.c CAP +sys_mq_notify ipc/mqueue.c CAP +sys_mq_getsetattr ipc/mqueue.c CAP +sys_kexec_load kernel/kexec.c CAP +sys_waitid kernel/exit.c CAP +sys_ni_syscall --- +sys_add_key security/keys/keyctl.c CAP +sys_request_key security/keys/keyctl.c CAP +sys_keyctl security/keys/keyctl.c CAP +sys_ioprio_set fs/ioprio.c CAP +sys_ioprio_get fs/ioprio.c CAP +sys_inotify_init fs/inotify.c CAP +sys_inotify_add_watch fs/inotify.c CAP +sys_inotify_rm_watch fs/inotify.c CAP + + +!!!! This is syscall 0 +sys_restart_syscall + +*sys_fork, sys_vfork, sys_clone -> do_fork (kernel/fork.c) diff -ruNp linux-2.6.15.5/arch/i386/kernel/ioport.c linux-2.6.15.5-cher1/arch/i386/kernel/ioport.c --- linux-2.6.15.5/arch/i386/kernel/ioport.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/arch/i386/kernel/ioport.c Thu Mar 2 12:58:20 2006 @@ -61,6 +61,9 @@ asmlinkage long sys_ioperm(unsigned long struct tss_struct * tss; unsigned long *bitmap; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) return -EINVAL; if (turn_on && !capable(CAP_SYS_RAWIO)) @@ -137,6 +140,9 @@ asmlinkage long sys_iopl(unsigned long u unsigned int old = (regs->eflags >> 12) & 3; struct thread_struct *t = ¤t->thread; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (level > 3) return -EINVAL; /* Trying to gain more privileges? */ @@ -149,3 +155,9 @@ asmlinkage long sys_iopl(unsigned long u set_iopl_mask(t->iopl); return 0; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/arch/i386/kernel/ldt.c linux-2.6.15.5-cher1/arch/i386/kernel/ldt.c --- linux-2.6.15.5/arch/i386/kernel/ldt.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/arch/i386/kernel/ldt.c Thu Mar 2 12:58:20 2006 @@ -235,6 +235,9 @@ asmlinkage int sys_modify_ldt(int func, { int ret = -ENOSYS; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (func) { case 0: ret = read_ldt(ptr, bytecount); @@ -251,3 +254,9 @@ asmlinkage int sys_modify_ldt(int func, } return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/arch/i386/kernel/process.c linux-2.6.15.5-cher1/arch/i386/kernel/process.c --- linux-2.6.15.5/arch/i386/kernel/process.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/arch/i386/kernel/process.c Thu Mar 2 12:58:20 2006 @@ -767,6 +767,11 @@ asmlinkage int sys_execve(struct pt_regs { int error; char * filename; + int no_sys_operations = 0; + + if (!capable(CAP_SYS_OPERATIONS) && !capable(CAP_SYS_ONE_EXEC)) + return -EPERM; + if (!capable(CAP_SYS_OPERATIONS)) no_sys_operations = 1; filename = getname((char __user *) regs.ebx); error = PTR_ERR(filename); @@ -778,6 +783,14 @@ asmlinkage int sys_execve(struct pt_regs ®s); if (error == 0) { task_lock(current); + if (no_sys_operations) { + cap_lower(current->cap_effective, CAP_SYS_ONE_EXEC); + cap_lower(current->cap_effective, CAP_SYS_OPERATIONS); + cap_lower(current->cap_permitted, CAP_SYS_ONE_EXEC); + cap_lower(current->cap_permitted, CAP_SYS_OPERATIONS); + cap_lower(current->cap_inheritable, CAP_SYS_ONE_EXEC); + cap_lower(current->cap_inheritable, CAP_SYS_OPERATIONS); + } current->ptrace &= ~PT_DTRACE; task_unlock(current); /* Make sure we don't return using sysenter.. */ @@ -936,3 +949,9 @@ unsigned long arch_align_stack(unsigned sp -= get_random_int() % 8192; return sp & ~0xf; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruNp linux-2.6.15.5/arch/i386/kernel/sys_i386.c linux-2.6.15.5-cher1/arch/i386/kernel/sys_i386.c --- linux-2.6.15.5/arch/i386/kernel/sys_i386.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/arch/i386/kernel/sys_i386.c Thu Mar 2 13:03:53 2006 @@ -32,6 +32,9 @@ asmlinkage int sys_pipe(unsigned long __ int fd[2]; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = do_pipe(fd); if (!error) { if (copy_to_user(fildes, fd, 2*sizeof(int))) @@ -70,6 +73,11 @@ asmlinkage long sys_mmap2(unsigned long unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) { + if (!(flags & MAP_ANONYMOUS)) return -EPERM; + fd = -1; + } + return do_mmap2(addr, len, prot, flags, fd, pgoff); } @@ -101,6 +109,11 @@ asmlinkage int old_mmap(struct mmap_arg_ if (a.offset & ~PAGE_MASK) goto out; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) { + if (!(a.flags & MAP_ANONYMOUS)) return -EPERM; + a.fd = -1; + } + err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); out: return err; @@ -133,6 +146,9 @@ asmlinkage int sys_ipc (uint call, int f { int version, ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; @@ -216,6 +232,10 @@ asmlinkage int sys_uname(struct old_utsn int err; if (!name) return -EFAULT; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + down_read(&uts_sem); err=copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); @@ -226,6 +246,9 @@ asmlinkage int sys_olduname(struct oldol { int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!name) return -EFAULT; if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) @@ -250,3 +273,9 @@ asmlinkage int sys_olduname(struct oldol return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/arch/i386/kernel/vm86.c linux-2.6.15.5-cher1/arch/i386/kernel/vm86.c --- linux-2.6.15.5/arch/i386/kernel/vm86.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/arch/i386/kernel/vm86.c Thu Mar 2 12:58:20 2006 @@ -179,6 +179,9 @@ asmlinkage int sys_vm86old(struct pt_reg struct task_struct *tsk; int tmp, ret = -EPERM; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + tsk = current; if (tsk->thread.saved_esp0) goto out; @@ -209,6 +212,9 @@ asmlinkage int sys_vm86(struct pt_regs r int tmp, ret; struct vm86plus_struct __user *v86; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + tsk = current; switch (regs.ebx) { case VM86_REQUEST_IRQ: @@ -806,3 +812,8 @@ static int do_vm86_irq_handling(int subf return -EINVAL; } +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/aio.c linux-2.6.15.5-cher1/fs/aio.c --- linux-2.6.15.5/fs/aio.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/aio.c Thu Mar 2 12:58:20 2006 @@ -1259,6 +1259,9 @@ asmlinkage long sys_io_setup(unsigned nr unsigned long ctx; long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + ret = get_user(ctx, ctxp); if (unlikely(ret)) goto out; @@ -1293,7 +1296,12 @@ out: */ asmlinkage long sys_io_destroy(aio_context_t ctx) { - struct kioctx *ioctx = lookup_ioctx(ctx); + struct kioctx *ioctx; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + ioctx = lookup_ioctx(ctx); if (likely(NULL != ioctx)) { io_destroy(ioctx); return 0; @@ -1568,6 +1576,9 @@ asmlinkage long sys_io_submit(aio_contex long ret = 0; int i; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (unlikely(nr < 0)) return -EINVAL; @@ -1645,6 +1656,9 @@ asmlinkage long sys_io_cancel(aio_contex u32 key; int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + ret = get_user(key, &iocb->aio_key); if (unlikely(ret)) return -EFAULT; @@ -1704,9 +1718,13 @@ asmlinkage long sys_io_getevents(aio_con struct io_event __user *events, struct timespec __user *timeout) { - struct kioctx *ioctx = lookup_ioctx(ctx_id); + struct kioctx *ioctx; long ret = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + ioctx = lookup_ioctx(ctx_id); if (likely(ioctx)) { if (likely(min_nr <= nr && min_nr >= 0 && nr >= 0)) ret = read_events(ioctx, min_nr, nr, events, timeout); @@ -1721,3 +1739,9 @@ __initcall(aio_setup); EXPORT_SYMBOL(aio_complete); EXPORT_SYMBOL(aio_put_req); EXPORT_SYMBOL(wait_on_sync_kiocb); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/binfmt_aout.c linux-2.6.15.5-cher1/fs/binfmt_aout.c --- linux-2.6.15.5/fs/binfmt_aout.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/binfmt_aout.c Thu Mar 2 12:58:20 2006 @@ -289,8 +289,13 @@ static int load_aout_binary(struct linux rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; if (rlim >= RLIM_INFINITY) rlim = ~0; - if (ex.a_data + ex.a_bss > rlim) + if (ex.a_data + ex.a_bss > rlim) { + if ((current->flags & PF_MEMLIMITON)) { + current->flags |= PF_MEMLIMITERR; + //send_sig(SIGKILL, current, 0); ??? + } return -ENOMEM; + } /* Flush all traces of the currently running executable */ retval = flush_old_exec(bprm); diff -ruNp linux-2.6.15.5/fs/binfmt_flat.c linux-2.6.15.5-cher1/fs/binfmt_flat.c --- linux-2.6.15.5/fs/binfmt_flat.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/binfmt_flat.c Thu Mar 2 12:58:20 2006 @@ -489,8 +489,13 @@ static int load_flat_file(struct linux_b rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; if (rlim >= RLIM_INFINITY) rlim = ~0; - if (data_len + bss_len > rlim) + if (data_len + bss_len > rlim) { + if ((current->flags & PF_MEMLIMITON)) { + current->flags |= PF_MEMLIMITERR; + //send_sig(SIGKILL, current, 0); ??? + } return -ENOMEM; + } /* Flush all traces of the currently running executable */ if (id == 0) { @@ -898,3 +903,9 @@ core_initcall(init_flat_binfmt); module_exit(exit_flat_binfmt); /****************************************************************************/ + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/buffer.c linux-2.6.15.5-cher1/fs/buffer.c --- linux-2.6.15.5/fs/buffer.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/buffer.c Thu Mar 2 12:58:20 2006 @@ -294,6 +294,9 @@ static void do_sync(unsigned long wait) asmlinkage long sys_sync(void) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + do_sync(1); return 0; } @@ -338,6 +341,9 @@ static long do_fsync(unsigned int fd, in struct address_space *mapping; int ret, err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + ret = -EBADF; file = fget(fd); if (!file) @@ -3007,6 +3013,9 @@ asmlinkage long sys_bdflush(int func, lo { static int msg_count; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -3152,3 +3161,9 @@ EXPORT_SYMBOL(mark_buffer_dirty); EXPORT_SYMBOL(submit_bh); EXPORT_SYMBOL(sync_dirty_buffer); EXPORT_SYMBOL(unlock_buffer); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/dcache.c linux-2.6.15.5-cher1/fs/dcache.c --- linux-2.6.15.5/fs/dcache.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/dcache.c Thu Mar 2 12:58:20 2006 @@ -1469,8 +1469,12 @@ asmlinkage long sys_getcwd(char __user * int error; struct vfsmount *pwdmnt, *rootmnt; struct dentry *pwd, *root; - char *page = (char *) __get_free_page(GFP_USER); + char *page; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + page = (char *) __get_free_page(GFP_USER); if (!page) return -ENOMEM; @@ -1765,3 +1769,9 @@ EXPORT_SYMBOL(have_submounts); EXPORT_SYMBOL(names_cachep); EXPORT_SYMBOL(shrink_dcache_parent); EXPORT_SYMBOL(shrink_dcache_sb); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/dcookies.c linux-2.6.15.5-cher1/fs/dcookies.c --- linux-2.6.15.5/fs/dcookies.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/dcookies.c Thu Mar 2 12:58:20 2006 @@ -150,6 +150,9 @@ asmlinkage long sys_lookup_dcookie(u64 c size_t pathlen; struct dcookie_struct * dcs; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* we could leak path information to users * without dir read permission without this */ @@ -326,3 +329,9 @@ void dcookie_unregister(struct dcookie_u EXPORT_SYMBOL_GPL(dcookie_register); EXPORT_SYMBOL_GPL(dcookie_unregister); EXPORT_SYMBOL_GPL(get_dcookie); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/eventpoll.c linux-2.6.15.5-cher1/fs/eventpoll.c --- linux-2.6.15.5/fs/eventpoll.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/eventpoll.c Thu Mar 2 12:58:20 2006 @@ -510,6 +510,9 @@ asmlinkage long sys_epoll_create(int siz struct inode *inode; struct file *file; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n", current, size)); @@ -559,6 +562,9 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epitem *epi; struct epoll_event epds; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %p)\n", current, epfd, op, fd, event)); @@ -661,6 +667,9 @@ asmlinkage long sys_epoll_wait(int epfd, struct file *file; struct eventpoll *ep; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d)\n", current, epfd, events, maxevents, timeout)); @@ -1666,3 +1675,9 @@ module_init(eventpoll_init); module_exit(eventpoll_exit); MODULE_LICENSE("GPL"); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/exec.c linux-2.6.15.5-cher1/fs/exec.c --- linux-2.6.15.5/fs/exec.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/exec.c Thu Mar 2 12:58:20 2006 @@ -127,6 +127,9 @@ asmlinkage long sys_uselib(const char __ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ); if (error) goto out; @@ -1520,3 +1523,9 @@ fail_unlock: fail: return retval; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruNp linux-2.6.15.5/fs/fcntl.c linux-2.6.15.5-cher1/fs/fcntl.c --- linux-2.6.15.5/fs/fcntl.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/fcntl.c Thu Mar 2 12:58:20 2006 @@ -141,6 +141,9 @@ asmlinkage long sys_dup2(unsigned int ol struct files_struct * files = current->files; struct fdtable *fdt; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + spin_lock(&files->file_lock); if (!(file = fcheck(oldfd))) goto out_unlock; @@ -193,8 +196,12 @@ out_fput: asmlinkage long sys_dup(unsigned int fildes) { int ret = -EBADF; - struct file * file = fget(fildes); + struct file * file; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + file = fget(fildes); if (file) ret = dupfd(file, 0); return ret; @@ -353,6 +360,9 @@ asmlinkage long sys_fcntl(unsigned int f struct file *filp; long err = -EBADF; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + filp = fget(fd); if (!filp) goto out; @@ -376,6 +386,9 @@ asmlinkage long sys_fcntl64(unsigned int struct file * filp; long err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + err = -EBADF; filp = fget(fd); if (!filp) @@ -619,3 +632,9 @@ static int __init fasync_init(void) } module_init(fasync_init) + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/filesystems.c linux-2.6.15.5-cher1/fs/filesystems.c --- linux-2.6.15.5/fs/filesystems.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/filesystems.c Thu Mar 2 12:58:20 2006 @@ -182,6 +182,9 @@ asmlinkage long sys_sysfs(int option, un { int retval = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (option) { case 1: retval = fs_index((const char __user *) arg1); @@ -235,3 +238,9 @@ struct file_system_type *get_fs_type(con } EXPORT_SYMBOL(get_fs_type); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/inotify.c linux-2.6.15.5-cher1/fs/inotify.c --- linux-2.6.15.5/fs/inotify.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/inotify.c Thu Mar 2 12:58:20 2006 @@ -869,6 +869,9 @@ asmlinkage long sys_inotify_init(void) struct file *filp; int fd, ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + fd = get_unused_fd(); if (fd < 0) return fd; @@ -936,6 +939,9 @@ asmlinkage long sys_inotify_add_watch(in int mask_add = 0; unsigned flags = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + filp = fget_light(fd, &fput_needed); if (unlikely(!filp)) return -EBADF; @@ -1011,6 +1017,9 @@ asmlinkage long sys_inotify_rm_watch(int struct inotify_device *dev; int ret, fput_needed; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + filp = fget_light(fd, &fput_needed); if (unlikely(!filp)) return -EBADF; @@ -1077,3 +1086,9 @@ static int __init inotify_setup(void) } module_init(inotify_setup); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/ioctl.c linux-2.6.15.5-cher1/fs/ioctl.c --- linux-2.6.15.5/fs/ioctl.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/ioctl.c Thu Mar 2 12:58:20 2006 @@ -162,6 +162,9 @@ asmlinkage long sys_ioctl(unsigned int f int error = -EBADF; int fput_needed; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + filp = fget_light(fd, &fput_needed); if (!filp) goto out; @@ -184,3 +187,9 @@ asmlinkage long sys_ioctl(unsigned int f #ifdef CONFIG_COMPAT EXPORT_SYMBOL(sys_ioctl); #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/ioprio.c linux-2.6.15.5-cher1/fs/ioprio.c --- linux-2.6.15.5/fs/ioprio.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/ioprio.c Thu Mar 2 12:58:20 2006 @@ -52,6 +52,9 @@ asmlinkage long sys_ioprio_set(int which struct user_struct *user; int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (class) { case IOPRIO_CLASS_RT: if (!capable(CAP_SYS_ADMIN)) @@ -124,6 +127,9 @@ asmlinkage long sys_ioprio_get(int which struct user_struct *user; int ret = -ESRCH; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + read_lock_irq(&tasklist_lock); switch (which) { case IOPRIO_WHO_PROCESS: @@ -173,3 +179,8 @@ asmlinkage long sys_ioprio_get(int which return ret; } +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/locks.c linux-2.6.15.5-cher1/fs/locks.c --- linux-2.6.15.5/fs/locks.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/locks.c Thu Mar 2 12:58:20 2006 @@ -1500,6 +1500,9 @@ asmlinkage long sys_flock(unsigned int f int can_sleep, unlock; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EBADF; filp = fget(fd); if (!filp) @@ -2249,3 +2252,9 @@ static int __init filelock_init(void) } core_initcall(filelock_init); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/namei.c linux-2.6.15.5-cher1/fs/namei.c --- linux-2.6.15.5/fs/namei.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/namei.c Thu Mar 2 12:58:20 2006 @@ -1750,6 +1750,9 @@ asmlinkage long sys_mknod(const char __u struct dentry * dentry; struct nameidata nd; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (S_ISDIR(mode)) return -EPERM; tmp = getname(filename); @@ -1819,6 +1822,9 @@ asmlinkage long sys_mkdir(const char __u int error = 0; char * tmp; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + tmp = getname(pathname); error = PTR_ERR(tmp); if (!IS_ERR(tmp)) { @@ -1913,6 +1919,9 @@ asmlinkage long sys_rmdir(const char __u struct dentry *dentry; struct nameidata nd; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + name = getname(pathname); if(IS_ERR(name)) return PTR_ERR(name); @@ -1991,6 +2000,9 @@ asmlinkage long sys_unlink(const char __ struct nameidata nd; struct inode *inode = NULL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + name = getname(pathname); if(IS_ERR(name)) return PTR_ERR(name); @@ -2057,6 +2069,9 @@ asmlinkage long sys_symlink(const char _ char * from; char * to; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + from = getname(oldname); if(IS_ERR(from)) return PTR_ERR(from); @@ -2138,6 +2153,9 @@ asmlinkage long sys_link(const char __us int error; char * to; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + to = getname(newname); if (IS_ERR(to)) return PTR_ERR(to); @@ -2396,6 +2414,9 @@ asmlinkage long sys_rename(const char __ char * from; char * to; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + from = getname(oldname); if(IS_ERR(from)) return PTR_ERR(from); @@ -2584,3 +2605,9 @@ EXPORT_SYMBOL(vfs_symlink); EXPORT_SYMBOL(vfs_unlink); EXPORT_SYMBOL(dentry_unhash); EXPORT_SYMBOL(generic_readlink); + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruNp linux-2.6.15.5/fs/namespace.c linux-2.6.15.5-cher1/fs/namespace.c --- linux-2.6.15.5/fs/namespace.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/namespace.c Thu Mar 2 12:58:20 2006 @@ -593,6 +593,9 @@ asmlinkage long sys_umount(char __user * struct nameidata nd; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = __user_walk(name, LOOKUP_FOLLOW, &nd); if (retval) goto out; @@ -1412,6 +1415,9 @@ asmlinkage long sys_mount(char __user * unsigned long dev_page; char *dir_page; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = copy_mount_options(type, &type_page); if (retval < 0) return retval; @@ -1541,6 +1547,9 @@ asmlinkage long sys_pivot_root(const cha struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1732,3 +1741,9 @@ void __put_namespace(struct namespace *n release_mounts(&umount_list); kfree(namespace); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/nfsctl.c linux-2.6.15.5-cher1/fs/nfsctl.c --- linux-2.6.15.5/fs/nfsctl.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/nfsctl.c Thu Mar 2 12:58:20 2006 @@ -94,6 +94,9 @@ asmlinkage sys_nfsservctl(int cmd, struc int version; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (copy_from_user(&version, &arg->ca_version, sizeof(int))) return -EFAULT; @@ -116,3 +119,9 @@ asmlinkage sys_nfsservctl(int cmd, struc fput(file); return err; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/open.c linux-2.6.15.5-cher1/fs/open.c --- linux-2.6.15.5/fs/open.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/open.c Thu Mar 2 12:58:20 2006 @@ -124,6 +124,9 @@ asmlinkage long sys_statfs(const char __ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(path, &nd); if (!error) { struct statfs tmp; @@ -141,6 +144,9 @@ asmlinkage long sys_statfs64(const char struct nameidata nd; long error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (sz != sizeof(*buf)) return -EINVAL; error = user_path_walk(path, &nd); @@ -161,6 +167,9 @@ asmlinkage long sys_fstatfs(unsigned int struct statfs tmp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EBADF; file = fget(fd); if (!file) @@ -179,6 +188,9 @@ asmlinkage long sys_fstatfs64(unsigned i struct statfs64 tmp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (sz != sizeof(*buf)) return -EINVAL; @@ -222,6 +234,9 @@ static inline long do_sys_truncate(const struct inode * inode; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EINVAL; if (length < 0) /* sorry, but loff_t says... */ goto out; @@ -289,6 +304,9 @@ static inline long do_sys_ftruncate(unsi struct file * file; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EINVAL; if (length < 0) goto out; @@ -363,6 +381,9 @@ asmlinkage long sys_utime(char __user * struct inode * inode; struct iattr newattrs; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(filename, &nd); if (error) goto out; @@ -463,6 +484,9 @@ asmlinkage long sys_utimes(char __user * { struct timeval times[2]; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (utimes && copy_from_user(×, utimes, sizeof(times))) return -EFAULT; return do_utimes(filename, utimes ? times : NULL); @@ -481,6 +505,9 @@ asmlinkage long sys_access(const char __ kernel_cap_t old_cap; int res; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL; @@ -526,6 +553,9 @@ asmlinkage long sys_chdir(const char __u struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd); if (error) goto out; @@ -550,6 +580,9 @@ asmlinkage long sys_fchdir(unsigned int struct vfsmount *mnt; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EBADF; file = fget(fd); if (!file) @@ -577,6 +610,9 @@ asmlinkage long sys_chroot(const char __ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); if (error) goto out; @@ -606,6 +642,9 @@ asmlinkage long sys_fchmod(unsigned int int err = -EBADF; struct iattr newattrs; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + file = fget(fd); if (!file) goto out; @@ -640,6 +679,9 @@ asmlinkage long sys_chmod(const char __u int error; struct iattr newattrs; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(filename, &nd); if (error) goto out; @@ -707,6 +749,9 @@ asmlinkage long sys_chown(const char __u struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(filename, &nd); if (!error) { error = chown_common(nd.dentry, user, group); @@ -720,6 +765,9 @@ asmlinkage long sys_lchown(const char __ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk_link(filename, &nd); if (!error) { error = chown_common(nd.dentry, user, group); @@ -734,6 +782,9 @@ asmlinkage long sys_fchown(unsigned int struct file * file; int error = -EBADF; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + file = fget(fd); if (file) { error = chown_common(file->f_dentry, user, group); @@ -1019,6 +1070,17 @@ long do_sys_open(const char __user *file char *tmp = getname(filename); int fd = PTR_ERR(tmp); + if (!IS_ERR(tmp) && !capable(CAP_SYS_OPERATIONS)) { + char *s = tmp; + while (s[0] == '.' && s[1] == '/') s += 2; + for (; *s && *s != '/'; s++); + if (*s == '/') { + putname(tmp); + return -EPERM; + } + flags &= ~(O_CREAT | O_EXCL); + } + if (!IS_ERR(tmp)) { fd = get_unused_fd(); if (fd >= 0) { @@ -1119,6 +1181,9 @@ EXPORT_SYMBOL(sys_close); */ asmlinkage long sys_vhangup(void) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (capable(CAP_SYS_TTY_CONFIG)) { tty_vhangup(current->signal->tty); return 0; @@ -1152,3 +1217,9 @@ int nonseekable_open(struct inode *inode } EXPORT_SYMBOL(nonseekable_open); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/quota.c linux-2.6.15.5-cher1/fs/quota.c --- linux-2.6.15.5/fs/quota.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/quota.c Thu Mar 2 12:58:20 2006 @@ -350,6 +350,9 @@ asmlinkage long sys_quotactl(unsigned in char *tmp; int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + cmds = cmd >> SUBCMDSHIFT; type = cmd & SUBCMDMASK; @@ -375,3 +378,9 @@ asmlinkage long sys_quotactl(unsigned in return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/read_write.c linux-2.6.15.5-cher1/fs/read_write.c --- linux-2.6.15.5/fs/read_write.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/read_write.c Thu Mar 2 12:58:20 2006 @@ -130,6 +130,9 @@ asmlinkage off_t sys_lseek(unsigned int struct file * file; int fput_needed; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = -EBADF; file = fget_light(fd, &fput_needed); if (!file) @@ -157,6 +160,9 @@ asmlinkage long sys_llseek(unsigned int loff_t offset; int fput_needed; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = -EBADF; file = fget_light(fd, &fput_needed); if (!file) @@ -367,6 +373,9 @@ asmlinkage ssize_t sys_pread64(unsigned ssize_t ret = -EBADF; int fput_needed; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (pos < 0) return -EINVAL; @@ -388,6 +397,9 @@ asmlinkage ssize_t sys_pwrite64(unsigned ssize_t ret = -EBADF; int fput_needed; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (pos < 0) return -EINVAL; @@ -721,6 +733,9 @@ asmlinkage ssize_t sys_sendfile(int out_ off_t off; ssize_t ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (offset) { if (unlikely(get_user(off, offset))) return -EFAULT; @@ -739,6 +754,9 @@ asmlinkage ssize_t sys_sendfile64(int ou loff_t pos; ssize_t ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (offset) { if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t)))) return -EFAULT; @@ -750,3 +768,9 @@ asmlinkage ssize_t sys_sendfile64(int ou return do_sendfile(out_fd, in_fd, NULL, count, 0); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/readdir.c linux-2.6.15.5-cher1/fs/readdir.c --- linux-2.6.15.5/fs/readdir.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/readdir.c Thu Mar 2 12:58:20 2006 @@ -100,6 +100,9 @@ asmlinkage long old_readdir(unsigned int struct file * file; struct readdir_callback buf; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EBADF; file = fget(fd); if (!file) @@ -180,6 +183,9 @@ asmlinkage long sys_getdents(unsigned in struct getdents_callback buf; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EFAULT; if (!access_ok(VERIFY_WRITE, dirent, count)) goto out; @@ -266,6 +272,9 @@ asmlinkage long sys_getdents64(unsigned struct getdents_callback64 buf; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EFAULT; if (!access_ok(VERIFY_WRITE, dirent, count)) goto out; @@ -298,3 +307,9 @@ out_putf: out: return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/stat.c linux-2.6.15.5-cher1/fs/stat.c --- linux-2.6.15.5/fs/stat.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/stat.c Thu Mar 2 12:58:20 2006 @@ -151,8 +151,12 @@ static int cp_old_stat(struct kstat *sta asmlinkage long sys_stat(char __user * filename, struct __old_kernel_stat __user * statbuf) { struct kstat stat; - int error = vfs_stat(filename, &stat); + int error; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = vfs_stat(filename, &stat); if (!error) error = cp_old_stat(&stat, statbuf); @@ -161,8 +165,12 @@ asmlinkage long sys_stat(char __user * f asmlinkage long sys_lstat(char __user * filename, struct __old_kernel_stat __user * statbuf) { struct kstat stat; - int error = vfs_lstat(filename, &stat); + int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + error = vfs_lstat(filename, &stat); if (!error) error = cp_old_stat(&stat, statbuf); @@ -171,8 +179,12 @@ asmlinkage long sys_lstat(char __user * asmlinkage long sys_fstat(unsigned int fd, struct __old_kernel_stat __user * statbuf) { struct kstat stat; - int error = vfs_fstat(fd, &stat); + int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + error = vfs_fstat(fd, &stat); if (!error) error = cp_old_stat(&stat, statbuf); @@ -232,8 +244,12 @@ static int cp_new_stat(struct kstat *sta asmlinkage long sys_newstat(char __user * filename, struct stat __user * statbuf) { struct kstat stat; - int error = vfs_stat(filename, &stat); + int error; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = vfs_stat(filename, &stat); if (!error) error = cp_new_stat(&stat, statbuf); @@ -242,8 +258,12 @@ asmlinkage long sys_newstat(char __user asmlinkage long sys_newlstat(char __user * filename, struct stat __user * statbuf) { struct kstat stat; - int error = vfs_lstat(filename, &stat); + int error; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = vfs_lstat(filename, &stat); if (!error) error = cp_new_stat(&stat, statbuf); @@ -252,8 +272,12 @@ asmlinkage long sys_newlstat(char __user asmlinkage long sys_newfstat(unsigned int fd, struct stat __user * statbuf) { struct kstat stat; - int error = vfs_fstat(fd, &stat); + int error; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = vfs_fstat(fd, &stat); if (!error) error = cp_new_stat(&stat, statbuf); @@ -265,6 +289,9 @@ asmlinkage long sys_readlink(const char struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (bufsiz <= 0) return -EINVAL; @@ -327,8 +354,12 @@ static long cp_new_stat64(struct kstat * asmlinkage long sys_stat64(char __user * filename, struct stat64 __user * statbuf) { struct kstat stat; - int error = vfs_stat(filename, &stat); + int error; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = vfs_stat(filename, &stat); if (!error) error = cp_new_stat64(&stat, statbuf); @@ -337,8 +368,12 @@ asmlinkage long sys_stat64(char __user * asmlinkage long sys_lstat64(char __user * filename, struct stat64 __user * statbuf) { struct kstat stat; - int error = vfs_lstat(filename, &stat); + int error; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = vfs_lstat(filename, &stat); if (!error) error = cp_new_stat64(&stat, statbuf); @@ -347,8 +382,12 @@ asmlinkage long sys_lstat64(char __user asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user * statbuf) { struct kstat stat; - int error = vfs_fstat(fd, &stat); + int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + error = vfs_fstat(fd, &stat); if (!error) error = cp_new_stat64(&stat, statbuf); @@ -408,3 +447,9 @@ void inode_set_bytes(struct inode *inode } EXPORT_SYMBOL(inode_set_bytes); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/super.c linux-2.6.15.5-cher1/fs/super.c --- linux-2.6.15.5/fs/super.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/super.c Thu Mar 2 12:58:20 2006 @@ -482,6 +482,9 @@ asmlinkage long sys_ustat(unsigned dev, struct kstatfs sbuf; int err = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + s = user_get_super(new_decode_dev(dev)); if (s == NULL) goto out; @@ -864,3 +867,9 @@ struct vfsmount *kern_mount(struct file_ } EXPORT_SYMBOL(kern_mount); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/fs/xattr.c linux-2.6.15.5-cher1/fs/xattr.c --- linux-2.6.15.5/fs/xattr.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/fs/xattr.c Thu Mar 2 12:58:20 2006 @@ -85,6 +85,9 @@ sys_setxattr(char __user *path, char __u struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(path, &nd); if (error) return error; @@ -100,6 +103,9 @@ sys_lsetxattr(char __user *path, char __ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk_link(path, &nd); if (error) return error; @@ -115,6 +121,9 @@ sys_fsetxattr(int fd, char __user *name, struct file *f; int error = -EBADF; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + f = fget(fd); if (!f) return error; @@ -183,6 +192,9 @@ sys_getxattr(char __user *path, char __u struct nameidata nd; ssize_t error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(path, &nd); if (error) return error; @@ -198,6 +210,9 @@ sys_lgetxattr(char __user *path, char __ struct nameidata nd; ssize_t error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk_link(path, &nd); if (error) return error; @@ -212,6 +227,9 @@ sys_fgetxattr(int fd, char __user *name, struct file *f; ssize_t error = -EBADF; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + f = fget(fd); if (!f) return error; @@ -267,6 +285,9 @@ sys_listxattr(char __user *path, char __ struct nameidata nd; ssize_t error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(path, &nd); if (error) return error; @@ -281,6 +302,9 @@ sys_llistxattr(char __user *path, char _ struct nameidata nd; ssize_t error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk_link(path, &nd); if (error) return error; @@ -295,6 +319,9 @@ sys_flistxattr(int fd, char __user *list struct file *f; ssize_t error = -EBADF; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + f = fget(fd); if (!f) return error; @@ -339,6 +366,9 @@ sys_removexattr(char __user *path, char struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(path, &nd); if (error) return error; @@ -353,6 +383,9 @@ sys_lremovexattr(char __user *path, char struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk_link(path, &nd); if (error) return error; @@ -367,6 +400,9 @@ sys_fremovexattr(int fd, char __user *na struct file *f; int error = -EBADF; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + f = fget(fd); if (!f) return error; @@ -502,3 +538,9 @@ EXPORT_SYMBOL(generic_getxattr); EXPORT_SYMBOL(generic_listxattr); EXPORT_SYMBOL(generic_setxattr); EXPORT_SYMBOL(generic_removexattr); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/include/asm-generic/resource.h linux-2.6.15.5-cher1/include/asm-generic/resource.h --- linux-2.6.15.5/include/asm-generic/resource.h Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/include/asm-generic/resource.h Thu Mar 2 12:58:20 2006 @@ -45,7 +45,9 @@ 0-39 for nice level 19 .. -20 */ #define RLIMIT_RTPRIO 14 /* maximum realtime priority */ -#define RLIM_NLIMITS 15 +#define RLIMIT_MCPU 15 /* time limit in subsecond prec. */ + +#define RLIM_NLIMITS 16 /* * SuS says limits have to be unsigned. @@ -86,6 +88,7 @@ [RLIMIT_MSGQUEUE] = { MQ_BYTES_MAX, MQ_BYTES_MAX }, \ [RLIMIT_NICE] = { 0, 0 }, \ [RLIMIT_RTPRIO] = { 0, 0 }, \ + [RLIMIT_MCPU] = { RLIM_INFINITY, RLIM_INFINITY }, \ } #endif /* __KERNEL__ */ diff -ruNp linux-2.6.15.5/include/linux/capability.h linux-2.6.15.5-cher1/include/linux/capability.h --- linux-2.6.15.5/include/linux/capability.h Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/include/linux/capability.h Thu Mar 2 12:58:20 2006 @@ -287,6 +287,15 @@ typedef __u32 kernel_cap_t; #define CAP_AUDIT_CONTROL 30 +/* The following two capability bits are added by cher */ +/* Allow open/close and most of the file operations */ + +#define CAP_SYS_OPERATIONS 29 + +/* Allow one time exec (effective when CAP_SYS_OPERATIONS dropped) */ + +#define CAP_SYS_ONE_EXEC 30 + #ifdef __KERNEL__ /* * Bounding set @@ -347,10 +356,10 @@ static inline kernel_cap_t cap_invert(ke return dest; } -#define cap_isclear(c) (!cap_t(c)) +#define cap_isclear(c) (!(cap_t(c) & ~(CAP_TO_MASK(CAP_SYS_OPERATIONS) | CAP_TO_MASK(CAP_SYS_ONE_EXEC)))) #define cap_issubset(a,set) (!(cap_t(a) & ~cap_t(set))) -#define cap_clear(c) do { cap_t(c) = 0; } while(0) +#define cap_clear(c) do { cap_t(c) = (CAP_TO_MASK(CAP_SYS_OPERATIONS) | CAP_TO_MASK(CAP_SYS_ONE_EXEC)); } while(0) #define cap_set_full(c) do { cap_t(c) = ~0; } while(0) #define cap_mask(c,mask) do { cap_t(c) &= cap_t(mask); } while(0) diff -ruNp linux-2.6.15.5/include/linux/ptrace.h linux-2.6.15.5-cher1/include/linux/ptrace.h --- linux-2.6.15.5/include/linux/ptrace.h Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/include/linux/ptrace.h Thu Mar 2 12:58:20 2006 @@ -29,6 +29,8 @@ #define PTRACE_GETSIGINFO 0x4202 #define PTRACE_SETSIGINFO 0x4203 +#define PTRACE_MEMLIMIT 0x4280 + /* options set using PTRACE_SETOPTIONS */ #define PTRACE_O_TRACESYSGOOD 0x00000001 #define PTRACE_O_TRACEFORK 0x00000002 diff -ruNp linux-2.6.15.5/include/linux/sched.h linux-2.6.15.5-cher1/include/linux/sched.h --- linux-2.6.15.5/include/linux/sched.h Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/include/linux/sched.h Thu Mar 2 12:58:20 2006 @@ -909,6 +909,9 @@ do { if (atomic_dec_and_test(&(tsk)->usa #define PF_BORROWED_MM 0x00400000 /* I am a kthread doing use_mm */ #define PF_RANDOMIZE 0x00800000 /* randomize virtual address space */ +#define PF_MEMLIMITON 0x01000000 /* Memory limit detection enabled */ +#define PF_MEMLIMITERR 0x02000000 /* Killed for memory limit error */ + /* * Only the _current_ task can read/write to tsk->flags, but other * tasks can access tsk->flags in readonly mode for example diff -ruNp linux-2.6.15.5/ipc/mqueue.c linux-2.6.15.5-cher1/ipc/mqueue.c --- linux-2.6.15.5/ipc/mqueue.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/ipc/mqueue.c Thu Mar 2 12:58:20 2006 @@ -655,6 +655,9 @@ asmlinkage long sys_mq_open(const char _ char *name; int fd, error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (IS_ERR(name = getname(u_name))) return PTR_ERR(name); @@ -717,6 +720,9 @@ asmlinkage long sys_mq_unlink(const char struct dentry *dentry; struct inode *inode = NULL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + name = getname(u_name); if (IS_ERR(name)) return PTR_ERR(name); @@ -812,6 +818,9 @@ asmlinkage long sys_mq_timedsend(mqd_t m long timeout; int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX)) return -EINVAL; @@ -894,6 +903,9 @@ asmlinkage ssize_t sys_mq_timedreceive(m struct mqueue_inode_info *info; struct ext_wait_queue wait; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + timeout = prepare_timeout(u_abs_timeout); ret = -EBADF; @@ -973,6 +985,9 @@ asmlinkage long sys_mq_notify(mqd_t mqde struct mqueue_inode_info *info; struct sk_buff *nc; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + nc = NULL; sock = NULL; if (u_notification != NULL) { @@ -1091,6 +1106,9 @@ asmlinkage long sys_mq_getsetattr(mqd_t struct inode *inode; struct mqueue_inode_info *info; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (u_mqstat != NULL) { if (copy_from_user(&mqstat, u_mqstat, sizeof(struct mq_attr))) return -EFAULT; @@ -1259,3 +1277,9 @@ out_sysctl: } __initcall(init_mqueue_fs); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/acct.c linux-2.6.15.5-cher1/kernel/acct.c --- linux-2.6.15.5/kernel/acct.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/acct.c Thu Mar 2 12:58:20 2006 @@ -252,6 +252,9 @@ asmlinkage long sys_acct(const char __us { int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SYS_PACCT)) return -EPERM; @@ -602,3 +605,9 @@ void acct_clear_integrals(struct task_st tsk->acct_vm_mem1 = 0; } } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/capability.c linux-2.6.15.5-cher1/kernel/capability.c --- linux-2.6.15.5/kernel/capability.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/capability.c Thu Mar 2 12:58:20 2006 @@ -48,6 +48,9 @@ asmlinkage long sys_capget(cap_user_head task_t *target; struct __user_cap_data_struct data; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (get_user(version, &header->version)) return -EFAULT; @@ -175,6 +178,9 @@ asmlinkage long sys_capset(cap_user_head int ret; pid_t pid; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (get_user(version, &header->version)) return -EFAULT; @@ -232,3 +238,9 @@ out: return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/exec_domain.c linux-2.6.15.5-cher1/kernel/exec_domain.c --- linux-2.6.15.5/kernel/exec_domain.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/exec_domain.c Thu Mar 2 12:58:20 2006 @@ -194,6 +194,9 @@ sys_personality(u_long personality) { u_long old = current->personality; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return (long) old; + if (personality != 0xffffffff) { set_personality(personality); if (current->personality != personality) @@ -207,3 +210,9 @@ sys_personality(u_long personality) EXPORT_SYMBOL(register_exec_domain); EXPORT_SYMBOL(unregister_exec_domain); EXPORT_SYMBOL(__set_personality); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/exit.c linux-2.6.15.5-cher1/kernel/exit.c --- linux-2.6.15.5/kernel/exit.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/exit.c Thu Mar 2 12:58:20 2006 @@ -1115,7 +1115,7 @@ static int wait_task_zombie(task_t *p, i status = (p->signal->flags & SIGNAL_GROUP_EXIT) ? p->signal->group_exit_code : p->exit_code; if (!retval && stat_addr) - retval = put_user(status, stat_addr); + retval = put_user(status | (((p->flags & PF_MEMLIMITERR))?0x10000:0), stat_addr); if (!retval && infop) retval = put_user(SIGCHLD, &infop->si_signo); if (!retval && infop) @@ -1517,6 +1517,9 @@ asmlinkage long sys_waitid(int which, pi { long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (options & ~(WNOHANG|WNOWAIT|WEXITED|WSTOPPED|WCONTINUED)) return -EINVAL; if (!(options & (WEXITED|WSTOPPED|WCONTINUED))) @@ -1551,6 +1554,9 @@ asmlinkage long sys_wait4(pid_t pid, int { long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (options & ~(WNOHANG|WUNTRACED|WCONTINUED| __WNOTHREAD|__WCLONE|__WALL)) return -EINVAL; @@ -1573,3 +1579,9 @@ asmlinkage long sys_waitpid(pid_t pid, i } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruNp linux-2.6.15.5/kernel/fork.c linux-2.6.15.5-cher1/kernel/fork.c --- linux-2.6.15.5/kernel/fork.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/fork.c Thu Mar 2 12:58:20 2006 @@ -829,6 +829,10 @@ static inline int copy_signal(unsigned l tsk->it_prof_expires = secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur); } + if (sig->rlim[RLIMIT_MCPU].rlim_cur != RLIM_INFINITY) { + tsk->it_prof_expires = + msecs_to_cputime(sig->rlim[RLIMIT_MCPU].rlim_cur); + } return 0; } @@ -839,6 +843,7 @@ static inline void copy_flags(unsigned l new_flags &= ~(PF_SUPERPRIV | PF_NOFREEZE); new_flags |= PF_FORKNOEXEC; + new_flags |= (p->flags & PF_MEMLIMITON); if (!(clone_flags & CLONE_PTRACE)) p->ptrace = 0; p->flags = new_flags; @@ -1102,6 +1107,7 @@ static task_t *copy_process(unsigned lon !cputime_eq(current->signal->it_prof_expires, cputime_zero) || current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY || + current->signal->rlim[RLIMIT_MCPU].rlim_cur != RLIM_INFINITY || !list_empty(¤t->signal->cpu_timers[0]) || !list_empty(¤t->signal->cpu_timers[1]) || !list_empty(¤t->signal->cpu_timers[2])) { @@ -1237,8 +1243,12 @@ long do_fork(unsigned long clone_flags, { struct task_struct *p; int trace = 0; - long pid = alloc_pidmap(); + long pid; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + pid = alloc_pidmap(); if (pid < 0) return -EAGAIN; if (unlikely(current->ptrace)) { @@ -1311,3 +1321,9 @@ void __init proc_caches_init(void) sizeof(struct mm_struct), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruNp linux-2.6.15.5/kernel/kexec.c linux-2.6.15.5-cher1/kernel/kexec.c --- linux-2.6.15.5/kernel/kexec.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/kexec.c Thu Mar 2 12:58:20 2006 @@ -915,6 +915,9 @@ asmlinkage long sys_kexec_load(unsigned int locked; int result; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* We only trust the superuser with rebooting the system. */ if (!capable(CAP_SYS_BOOT)) return -EPERM; @@ -1060,3 +1063,9 @@ void crash_kexec(struct pt_regs *regs) xchg(&kexec_lock, 0); } } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/module.c linux-2.6.15.5-cher1/kernel/module.c --- linux-2.6.15.5/kernel/module.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/module.c Thu Mar 2 12:58:20 2006 @@ -575,6 +575,9 @@ sys_delete_module(const char __user *nam char name[MODULE_NAME_LEN]; int ret, forced = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SYS_MODULE)) return -EPERM; @@ -1883,6 +1886,9 @@ sys_init_module(void __user *umod, struct module *mod; int ret = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* Must have permission */ if (!capable(CAP_SYS_MODULE)) return -EPERM; @@ -2221,3 +2227,9 @@ EXPORT_SYMBOL(module_remove_driver); void struct_module(struct module *mod) { return; } EXPORT_SYMBOL(struct_module); #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/posix-cpu-timers.c linux-2.6.15.5-cher1/kernel/posix-cpu-timers.c --- linux-2.6.15.5/kernel/posix-cpu-timers.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/posix-cpu-timers.c Thu Mar 2 12:58:20 2006 @@ -648,6 +648,10 @@ static void arm_timer(struct k_itimer *t if (i != RLIM_INFINITY && i <= cputime_to_secs(timer->it.cpu.expires.cpu)) break; + i = p->signal->rlim[RLIMIT_MCPU].rlim_cur; + if (i != RLIM_INFINITY && + i <= cputime_to_msecs(timer->it.cpu.expires.cpu)) + break; goto rebalance; case CPUCLOCK_SCHED: rebalance: @@ -1029,6 +1033,7 @@ static void check_process_timers(struct if (list_empty(&timers[CPUCLOCK_PROF]) && cputime_eq(sig->it_prof_expires, cputime_zero) && sig->rlim[RLIMIT_CPU].rlim_cur == RLIM_INFINITY && + sig->rlim[RLIMIT_MCPU].rlim_cur == RLIM_INFINITY && list_empty(&timers[CPUCLOCK_VIRT]) && cputime_eq(sig->it_virt_expires, cputime_zero) && list_empty(&timers[CPUCLOCK_SCHED])) @@ -1156,6 +1161,21 @@ static void check_process_timers(struct } } + if (sig->rlim[RLIMIT_MCPU].rlim_cur != RLIM_INFINITY) { + unsigned long pusecs = cputime_to_msecs(ptime); + cputime_t x; + if (pusecs >= sig->rlim[RLIMIT_MCPU].rlim_max || + pusecs >= sig->rlim[RLIMIT_MCPU].rlim_cur) { + __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); + return; + } + x = msecs_to_cputime(sig->rlim[RLIMIT_MCPU].rlim_cur); + if (cputime_eq(prof_expires, cputime_zero) || + cputime_lt(x, prof_expires)) { + prof_expires = x; + } + } + if (!cputime_eq(prof_expires, cputime_zero) || !cputime_eq(virt_expires, cputime_zero) || sched_expires != 0) { @@ -1387,6 +1407,10 @@ void set_process_cpu_timer(struct task_s if (tsk->signal->rlim[RLIMIT_CPU].rlim_cur < cputime_to_secs(*newval)) return; + if (tsk->signal->rlim[RLIMIT_MCPU].rlim_cur + < cputime_to_msecs(*newval)) + return; + } /* @@ -1574,3 +1598,9 @@ static __init int init_posix_cpu_timers( return 0; } __initcall(init_posix_cpu_timers); + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruNp linux-2.6.15.5/kernel/posix-timers.c linux-2.6.15.5-cher1/kernel/posix-timers.c --- linux-2.6.15.5/kernel/posix-timers.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/posix-timers.c Thu Mar 2 12:58:20 2006 @@ -588,6 +588,9 @@ sys_timer_create(clockid_t which_clock, sigevent_t event; int it_id_set = IT_ID_NOT_SET; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (invalid_clockid(which_clock)) return -EINVAL; @@ -819,6 +822,9 @@ sys_timer_gettime(timer_t timer_id, stru struct itimerspec cur_setting; unsigned long flags; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + timr = lock_timer(timer_id, &flags); if (!timr) return -EINVAL; @@ -849,6 +855,9 @@ sys_timer_getoverrun(timer_t timer_id) int overrun; long flags; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + timr = lock_timer(timer_id, &flags); if (!timr) return -EINVAL; @@ -1020,6 +1029,9 @@ sys_timer_settime(timer_t timer_id, int long flag; struct itimerspec *rtn = old_setting ? &old_spec : NULL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!new_setting) return -EINVAL; @@ -1089,6 +1101,9 @@ sys_timer_delete(timer_t timer_id) int error; retry_delete: #endif + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + timer = lock_timer(timer_id, &flags); if (!timer) return -EINVAL; @@ -1247,6 +1262,9 @@ sys_clock_settime(clockid_t which_clock, { struct timespec new_tp; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (invalid_clockid(which_clock)) return -EINVAL; if (copy_from_user(&new_tp, tp, sizeof (*tp))) @@ -1261,6 +1279,9 @@ sys_clock_gettime(clockid_t which_clock, struct timespec kernel_tp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (invalid_clockid(which_clock)) return -EINVAL; error = CLOCK_DISPATCH(which_clock, clock_get, @@ -1278,6 +1299,9 @@ sys_clock_getres(clockid_t which_clock, struct timespec rtn_tp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (invalid_clockid(which_clock)) return -EINVAL; @@ -1404,6 +1428,9 @@ sys_clock_nanosleep(clockid_t which_cloc &(current_thread_info()->restart_block); int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (invalid_clockid(which_clock)) return -EINVAL; @@ -1532,3 +1559,9 @@ clock_nanosleep_restart(struct restart_b return -EFAULT; return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/printk.c linux-2.6.15.5-cher1/kernel/printk.c --- linux-2.6.15.5/kernel/printk.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/printk.c Thu Mar 2 12:58:20 2006 @@ -353,6 +353,9 @@ out: asmlinkage long sys_syslog(int type, char __user *buf, int len) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + return do_syslog(type, buf, len); } @@ -1049,3 +1052,9 @@ int printk_ratelimit(void) printk_ratelimit_burst); } EXPORT_SYMBOL(printk_ratelimit); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/ptrace.c linux-2.6.15.5-cher1/kernel/ptrace.c --- linux-2.6.15.5/kernel/ptrace.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/ptrace.c Thu Mar 2 12:58:20 2006 @@ -466,10 +466,20 @@ asmlinkage long sys_ptrace(long request, struct task_struct *child; long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* * This lock_kernel fixes a subtle race with suid exec */ lock_kernel(); + + if (request == PTRACE_MEMLIMIT) { + current->flags |= PF_MEMLIMITON; + ret = 0; + goto out; + } + ret = ptrace_get_task_struct(request, pid, &child); if (!child) goto out; @@ -494,3 +504,9 @@ asmlinkage long sys_ptrace(long request, return ret; } #endif /* __ARCH_SYS_PTRACE */ + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/sched.c linux-2.6.15.5-cher1/kernel/sched.c --- linux-2.6.15.5/kernel/sched.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/sched.c Thu Mar 2 12:58:20 2006 @@ -3604,6 +3604,9 @@ asmlinkage long sys_nice(int increment) int retval; long nice; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* * Setpriority might change our priority at the same moment. * We don't have to worry. Conceptually one call occurs first @@ -3817,6 +3820,9 @@ do_sched_setscheduler(pid_t pid, int pol asmlinkage long sys_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + return do_sched_setscheduler(pid, policy, param); } @@ -3827,6 +3833,9 @@ asmlinkage long sys_sched_setscheduler(p */ asmlinkage long sys_sched_setparam(pid_t pid, struct sched_param __user *param) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + return do_sched_setscheduler(pid, -1, param); } @@ -3842,6 +3851,9 @@ asmlinkage long sys_sched_getscheduler(p if (pid < 0) goto out_nounlock; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = -ESRCH; read_lock(&tasklist_lock); p = find_process_by_pid(pid); @@ -3870,6 +3882,9 @@ asmlinkage long sys_sched_getparam(pid_t if (!param || pid < 0) goto out_nounlock; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + read_lock(&tasklist_lock); p = find_process_by_pid(pid); retval = -ESRCH; @@ -3958,6 +3973,9 @@ asmlinkage long sys_sched_setaffinity(pi cpumask_t new_mask; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = get_user_cpu_mask(user_mask_ptr, len, &new_mask); if (retval) return retval; @@ -4017,6 +4035,9 @@ asmlinkage long sys_sched_getaffinity(pi int ret; cpumask_t mask; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (len < sizeof(cpumask_t)) return -EINVAL; @@ -4210,6 +4231,9 @@ asmlinkage long sys_sched_get_priority_m { int ret = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (policy) { case SCHED_FIFO: case SCHED_RR: @@ -4233,6 +4257,9 @@ asmlinkage long sys_sched_get_priority_m { int ret = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (policy) { case SCHED_FIFO: case SCHED_RR: @@ -4262,6 +4289,9 @@ long sys_sched_rr_get_interval(pid_t pid if (pid < 0) goto out_nounlock; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = -ESRCH; read_lock(&tasklist_lock); p = find_process_by_pid(pid); @@ -5745,3 +5775,9 @@ void set_curr_task(int cpu, task_t *p) } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/signal.c linux-2.6.15.5-cher1/kernel/signal.c --- linux-2.6.15.5/kernel/signal.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/signal.c Thu Mar 2 12:58:20 2006 @@ -1191,6 +1191,18 @@ EXPORT_SYMBOL_GPL(kill_proc_info_as_uid) static int kill_something_info(int sig, struct siginfo *info, int pid) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) { + if (!pid) { + pid = current->pid; + } else if (pid == -1) { + return -EPERM; + } else if (pid < 0) { + if (current->signal->pgrp != -pid) + return -EPERM; + pid = current->pid; + } + } + if (!pid) { return kill_pg_info(sig, info, process_group(current)); } else if (pid == -1) { @@ -2300,6 +2312,9 @@ asmlinkage long sys_tgkill(int tgid, int if (pid <= 0 || tgid <= 0) return -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + return do_tkill(tgid, pid, sig); } @@ -2313,6 +2328,9 @@ sys_tkill(int pid, int sig) if (pid <= 0) return -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + return do_tkill(0, pid, sig); } @@ -2330,6 +2348,11 @@ sys_rt_sigqueueinfo(int pid, int sig, si return -EPERM; info.si_signo = sig; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) { + if (pid <= 0 || pid != current->pid) + return -EPERM; + } + /* POSIX.1b doesn't mention process groups. */ return kill_proc_info(sig, &info, pid); } @@ -2615,6 +2638,9 @@ sys_signal(int sig, __sighandler_t handl asmlinkage long sys_pause(void) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + current->state = TASK_INTERRUPTIBLE; schedule(); return -ERESTARTNOHAND; @@ -2630,3 +2656,9 @@ void __init signals_init(void) __alignof__(struct sigqueue), SLAB_PANIC, NULL, NULL); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/sys.c linux-2.6.15.5-cher1/kernel/sys.c --- linux-2.6.15.5/kernel/sys.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/sys.c Thu Mar 2 12:58:20 2006 @@ -254,6 +254,9 @@ asmlinkage long sys_setpriority(int whic struct user_struct *user; int error = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (which > 2 || which < 0) goto out; @@ -314,6 +317,9 @@ asmlinkage long sys_getpriority(int whic struct user_struct *user; long niceval, retval = -ESRCH; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (which > 2 || which < 0) return -EINVAL; @@ -477,6 +483,9 @@ asmlinkage long sys_reboot(int magic1, i { char buffer[256]; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* We only trust the superuser with rebooting the system. */ if (!capable(CAP_SYS_BOOT)) return -EPERM; @@ -594,6 +603,9 @@ asmlinkage long sys_setregid(gid_t rgid, int new_egid = old_egid; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = security_task_setgid(rgid, egid, (gid_t)-1, LSM_SETID_RE); if (retval) return retval; @@ -642,6 +654,9 @@ asmlinkage long sys_setgid(gid_t gid) int old_egid = current->egid; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_ID); if (retval) return retval; @@ -718,6 +733,9 @@ asmlinkage long sys_setreuid(uid_t ruid, int old_ruid, old_euid, old_suid, new_ruid, new_euid; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = security_task_setuid(ruid, euid, (uid_t)-1, LSM_SETID_RE); if (retval) return retval; @@ -782,6 +800,9 @@ asmlinkage long sys_setuid(uid_t uid) int old_ruid, old_suid, new_ruid, new_suid; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_ID); if (retval) return retval; @@ -823,6 +844,9 @@ asmlinkage long sys_setresuid(uid_t ruid int old_suid = current->suid; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = security_task_setuid(ruid, euid, suid, LSM_SETID_RES); if (retval) return retval; @@ -864,6 +888,9 @@ asmlinkage long sys_getresuid(uid_t __us { int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!(retval = put_user(current->uid, ruid)) && !(retval = put_user(current->euid, euid))) retval = put_user(current->suid, suid); @@ -878,6 +905,9 @@ asmlinkage long sys_setresgid(gid_t rgid { int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = security_task_setgid(rgid, egid, sgid, LSM_SETID_RES); if (retval) return retval; @@ -916,6 +946,9 @@ asmlinkage long sys_getresgid(gid_t __us { int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!(retval = put_user(current->gid, rgid)) && !(retval = put_user(current->egid, egid))) retval = put_user(current->sgid, sgid); @@ -934,6 +967,9 @@ asmlinkage long sys_setfsuid(uid_t uid) { int old_fsuid; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + old_fsuid = current->fsuid; if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS)) return old_fsuid; @@ -965,6 +1001,9 @@ asmlinkage long sys_setfsgid(gid_t gid) { int old_fsgid; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + old_fsgid = current->fsgid; if (security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS)) return old_fsgid; @@ -1086,6 +1125,9 @@ asmlinkage long sys_setpgid(pid_t pid, p struct task_struct *p; int err = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!pid) pid = current->pid; if (!pgid) @@ -1160,6 +1202,9 @@ asmlinkage long sys_getpgid(pid_t pid) int retval; struct task_struct *p; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + read_lock(&tasklist_lock); p = find_task_by_pid(pid); @@ -1192,6 +1237,9 @@ asmlinkage long sys_getsid(pid_t pid) int retval; struct task_struct *p; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + read_lock(&tasklist_lock); p = find_task_by_pid(pid); @@ -1211,6 +1259,9 @@ asmlinkage long sys_setsid(void) struct pid *pid; int err = -EPERM; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!thread_group_leader(current)) return -EINVAL; @@ -1415,6 +1466,8 @@ asmlinkage long sys_getgroups(int gidset * SMP: Nobody else can change our grouplist. Thus we are * safe. */ + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; if (gidsetsize < 0) return -EINVAL; @@ -1447,6 +1500,9 @@ asmlinkage long sys_setgroups(int gidset struct group_info *group_info; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SETGID)) return -EPERM; if ((unsigned)gidsetsize > NGROUPS_MAX) @@ -1516,6 +1572,9 @@ asmlinkage long sys_sethostname(char __u int errno; char tmp[__NEW_UTS_LEN]; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (len < 0 || len > __NEW_UTS_LEN) @@ -1561,6 +1620,9 @@ asmlinkage long sys_setdomainname(char _ int errno; char tmp[__NEW_UTS_LEN]; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (len < 0 || len > __NEW_UTS_LEN) @@ -1619,6 +1681,9 @@ asmlinkage long sys_setrlimit(unsigned i struct rlimit new_rlim, *old_rlim; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (resource >= RLIM_NLIMITS) return -EINVAL; if(copy_from_user(&new_rlim, rlim, sizeof(*rlim))) @@ -1652,6 +1717,18 @@ asmlinkage long sys_setrlimit(unsigned i spin_unlock_irq(¤t->sighand->siglock); read_unlock(&tasklist_lock); } + if (resource == RLIMIT_MCPU && new_rlim.rlim_cur != RLIM_INFINITY && + (cputime_eq(current->signal->it_prof_expires, cputime_zero) || + new_rlim.rlim_cur <= cputime_to_msecs( + current->signal->it_prof_expires))) { + cputime_t cputime = msecs_to_cputime(new_rlim.rlim_cur); + read_lock(&tasklist_lock); + spin_lock_irq(¤t->sighand->siglock); + set_process_cpu_timer(current, CPUCLOCK_PROF, + &cputime, NULL); + spin_unlock_irq(¤t->sighand->siglock); + read_unlock(&tasklist_lock); + } return 0; } @@ -1756,6 +1833,8 @@ asmlinkage long sys_getrusage(int who, s asmlinkage long sys_umask(int mask) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return current->fs->umask; mask = xchg(¤t->fs->umask, mask & S_IRWXUGO); return mask; } @@ -1765,6 +1844,9 @@ asmlinkage long sys_prctl(int option, un { long error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = security_task_prctl(option, arg2, arg3, arg4, arg5); if (error) return error; @@ -1856,3 +1938,9 @@ asmlinkage long sys_prctl(int option, un } return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/sysctl.c linux-2.6.15.5-cher1/kernel/sysctl.c --- linux-2.6.15.5/kernel/sysctl.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/sysctl.c Thu Mar 2 12:58:20 2006 @@ -1085,6 +1085,9 @@ asmlinkage long sys_sysctl(struct __sysc struct __sysctl_args tmp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (copy_from_user(&tmp, args, sizeof(tmp))) return -EFAULT; @@ -2447,3 +2450,9 @@ EXPORT_SYMBOL(sysctl_jiffies); EXPORT_SYMBOL(sysctl_ms_jiffies); EXPORT_SYMBOL(sysctl_string); EXPORT_SYMBOL(unregister_sysctl_table); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/time.c linux-2.6.15.5-cher1/kernel/time.c --- linux-2.6.15.5/kernel/time.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/time.c Thu Mar 2 12:58:20 2006 @@ -82,6 +82,9 @@ asmlinkage long sys_stime(time_t __user struct timespec tv; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (get_user(tv.tv_sec, tptr)) return -EFAULT; @@ -184,6 +187,9 @@ asmlinkage long sys_settimeofday(struct struct timespec new_ts; struct timezone new_tz; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (tv) { if (copy_from_user(&user_tv, tv, sizeof(*tv))) return -EFAULT; @@ -403,6 +409,9 @@ asmlinkage long sys_adjtimex(struct time struct timex txc; /* Local copy of parameter */ int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* Copy the user data space into the kernel copy * structure. But bear in mind that the structures * may change @@ -600,3 +609,9 @@ EXPORT_SYMBOL(get_jiffies_64); #endif EXPORT_SYMBOL(jiffies); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/timer.c linux-2.6.15.5-cher1/kernel/timer.c --- linux-2.6.15.5/kernel/timer.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/timer.c Thu Mar 2 12:58:20 2006 @@ -1184,6 +1184,9 @@ asmlinkage long sys_sysinfo(struct sysin unsigned int mem_unit, bitcount; unsigned long seq; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + memset((char *)&val, 0, sizeof(struct sysinfo)); do { @@ -1576,3 +1579,9 @@ unsigned long msleep_interruptible(unsig } EXPORT_SYMBOL(msleep_interruptible); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/kernel/uid16.c linux-2.6.15.5-cher1/kernel/uid16.c --- linux-2.6.15.5/kernel/uid16.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/kernel/uid16.c Thu Mar 2 12:58:20 2006 @@ -130,6 +130,9 @@ asmlinkage long sys_getgroups16(int gids { int i = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (gidsetsize < 0) return -EINVAL; @@ -155,6 +158,9 @@ asmlinkage long sys_setgroups16(int gids struct group_info *group_info; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SETGID)) return -EPERM; if ((unsigned)gidsetsize > NGROUPS_MAX) @@ -194,3 +200,9 @@ asmlinkage long sys_getegid16(void) { return high2lowgid(current->egid); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/mm/fadvise.c linux-2.6.15.5-cher1/mm/fadvise.c --- linux-2.6.15.5/mm/fadvise.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/mm/fadvise.c Thu Mar 2 12:58:20 2006 @@ -25,7 +25,7 @@ */ asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice) { - struct file *file = fget(fd); + struct file *file; struct address_space *mapping; struct backing_dev_info *bdi; loff_t endbyte; @@ -34,6 +34,10 @@ asmlinkage long sys_fadvise64_64(int fd, unsigned long nrpages; int ret = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + file = fget(fd); if (!file) return -EBADF; @@ -113,3 +117,9 @@ asmlinkage long sys_fadvise64(int fd, lo } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/mm/filemap.c linux-2.6.15.5-cher1/mm/filemap.c --- linux-2.6.15.5/mm/filemap.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/mm/filemap.c Thu Mar 2 12:58:20 2006 @@ -1127,6 +1127,9 @@ asmlinkage ssize_t sys_readahead(int fd, ssize_t ret; struct file *file; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + ret = -EBADF; file = fget(fd); if (file) { @@ -2268,3 +2271,9 @@ generic_file_direct_IO(int rw, struct ki } return retval; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/mm/fremap.c linux-2.6.15.5-cher1/mm/fremap.c --- linux-2.6.15.5/mm/fremap.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/mm/fremap.c Thu Mar 2 12:58:20 2006 @@ -149,6 +149,9 @@ asmlinkage long sys_remap_file_pages(uns int err = -EINVAL; int has_write_lock = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (__prot) return err; /* @@ -221,3 +224,8 @@ asmlinkage long sys_remap_file_pages(uns return err; } +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/mm/madvise.c linux-2.6.15.5-cher1/mm/madvise.c --- linux-2.6.15.5/mm/madvise.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/mm/madvise.c Thu Mar 2 12:58:20 2006 @@ -210,6 +210,9 @@ asmlinkage long sys_madvise(unsigned lon int error = -EINVAL; size_t len; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + down_write(¤t->mm->mmap_sem); if (start & ~PAGE_MASK) @@ -272,3 +275,9 @@ out: up_write(¤t->mm->mmap_sem); return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/mm/mempolicy.c linux-2.6.15.5-cher1/mm/mempolicy.c --- linux-2.6.15.5/mm/mempolicy.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/mm/mempolicy.c Thu Mar 2 12:58:20 2006 @@ -583,6 +583,9 @@ asmlinkage long sys_mbind(unsigned long nodemask_t nodes; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + err = get_nodes(&nodes, nmask, maxnode); if (err) return err; @@ -596,6 +599,9 @@ asmlinkage long sys_set_mempolicy(int mo int err; nodemask_t nodes; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (mode < 0 || mode > MPOL_MAX) return -EINVAL; err = get_nodes(&nodes, nmask, maxnode); @@ -613,6 +619,9 @@ asmlinkage long sys_get_mempolicy(int __ int err, pval; nodemask_t nodes; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (nmask != NULL && maxnode < MAX_NUMNODES) return -EINVAL; @@ -642,6 +651,9 @@ asmlinkage long compat_sys_get_mempolicy unsigned long nr_bits, alloc_size; DECLARE_BITMAP(bm, MAX_NUMNODES); + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES); alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; @@ -668,6 +680,9 @@ asmlinkage long compat_sys_set_mempolicy unsigned long nr_bits, alloc_size; DECLARE_BITMAP(bm, MAX_NUMNODES); + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES); alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; @@ -692,6 +707,9 @@ asmlinkage long compat_sys_mbind(compat_ unsigned long nr_bits, alloc_size; nodemask_t bm; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES); alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; @@ -1272,3 +1290,9 @@ void numa_policy_rebind(const nodemask_t { rebind_policy(current->mempolicy, old, new); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/mm/mincore.c linux-2.6.15.5-cher1/mm/mincore.c --- linux-2.6.15.5/mm/mincore.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/mm/mincore.c Thu Mar 2 12:58:20 2006 @@ -114,6 +114,9 @@ asmlinkage long sys_mincore(unsigned lon int unmapped_error = 0; long error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* check the arguments */ if (start & ~PAGE_CACHE_MASK) goto einval; @@ -186,3 +189,9 @@ einval: enomem: return -ENOMEM; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/mm/mlock.c linux-2.6.15.5-cher1/mm/mlock.c --- linux-2.6.15.5/mm/mlock.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/mm/mlock.c Thu Mar 2 12:58:20 2006 @@ -126,6 +126,9 @@ asmlinkage long sys_mlock(unsigned long unsigned long lock_limit; int error = -ENOMEM; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!can_do_mlock()) return -EPERM; @@ -150,6 +153,9 @@ asmlinkage long sys_munlock(unsigned lon { int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + down_write(¤t->mm->mmap_sem); len = PAGE_ALIGN(len + (start & ~PAGE_MASK)); start &= PAGE_MASK; @@ -188,6 +194,9 @@ asmlinkage long sys_mlockall(int flags) unsigned long lock_limit; int ret = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE))) goto out; @@ -213,6 +222,9 @@ asmlinkage long sys_munlockall(void) { int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + down_write(¤t->mm->mmap_sem); ret = do_mlockall(0); up_write(¤t->mm->mmap_sem); @@ -251,3 +263,9 @@ void user_shm_unlock(size_t size, struct spin_unlock(&shmlock_user_lock); free_uid(user); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/mm/mmap.c linux-2.6.15.5-cher1/mm/mmap.c --- linux-2.6.15.5/mm/mmap.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/mm/mmap.c Thu Mar 2 12:58:20 2006 @@ -233,8 +233,13 @@ asmlinkage unsigned long sys_brk(unsigne /* Check against rlimit.. */ rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; - if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim) + if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim) { + if ((current->flags & PF_MEMLIMITON)) { + current->flags |= PF_MEMLIMITERR; + send_sig(SIGKILL, current, 0); + } goto out; + } /* Check against existing mmap mappings. */ if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) @@ -1457,8 +1462,13 @@ static int acct_stack_growth(struct vm_a return -ENOMEM; /* Stack limit test */ - if (size > rlim[RLIMIT_STACK].rlim_cur) + if (size > rlim[RLIMIT_STACK].rlim_cur) { + if ((current->flags & PF_MEMLIMITON)) { + current->flags |= PF_MEMLIMITERR; + send_sig(SIGKILL, current, 0); + } return -ENOMEM; + } /* mlock limit tests */ if (vma->vm_flags & VM_LOCKED) { @@ -2056,7 +2066,18 @@ int may_expand_vm(struct mm_struct *mm, lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT; - if (cur + npages > lim) + if (cur + npages > lim) { + if ((current->flags & PF_MEMLIMITON)) { + current->flags |= PF_MEMLIMITERR; + send_sig(SIGKILL, current, 0); + } return 0; + } return 1; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/mm/mprotect.c linux-2.6.15.5-cher1/mm/mprotect.c --- linux-2.6.15.5/mm/mprotect.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/mm/mprotect.c Thu Mar 2 12:58:20 2006 @@ -187,6 +187,9 @@ sys_mprotect(unsigned long start, size_t if (grows == (PROT_GROWSDOWN|PROT_GROWSUP)) /* can't be both */ return -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (start & ~PAGE_MASK) return -EINVAL; if (!len) @@ -280,3 +283,9 @@ out: up_write(¤t->mm->mmap_sem); return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/mm/mremap.c linux-2.6.15.5-cher1/mm/mremap.c --- linux-2.6.15.5/mm/mremap.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/mm/mremap.c Thu Mar 2 12:58:20 2006 @@ -407,8 +407,17 @@ asmlinkage unsigned long sys_mremap(unsi { unsigned long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + down_write(¤t->mm->mmap_sem); ret = do_mremap(addr, old_len, new_len, flags, new_addr); up_write(¤t->mm->mmap_sem); return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/mm/swapfile.c linux-2.6.15.5-cher1/mm/swapfile.c --- linux-2.6.15.5/mm/swapfile.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/mm/swapfile.c Thu Mar 2 12:58:20 2006 @@ -1061,7 +1061,9 @@ asmlinkage long sys_swapoff(const char _ char * pathname; int i, type, prev; int err; - + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1300,6 +1302,8 @@ asmlinkage long sys_swapon(const char __ struct inode *inode = NULL; int did_down = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; if (!capable(CAP_SYS_ADMIN)) return -EPERM; spin_lock(&swap_lock); @@ -1676,3 +1680,9 @@ int valid_swaphandles(swp_entry_t entry, spin_unlock(&swap_lock); return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/net/socket.c linux-2.6.15.5-cher1/net/socket.c --- linux-2.6.15.5/net/socket.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/net/socket.c Thu Mar 2 12:58:20 2006 @@ -1191,6 +1191,9 @@ asmlinkage long sys_socket(int family, i int retval; struct socket *sock; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = sock_create(family, type, protocol, &sock); if (retval < 0) goto out; @@ -1217,6 +1220,9 @@ asmlinkage long sys_socketpair(int famil struct socket *sock1, *sock2; int fd1, fd2, err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* * Obtain the first socket and check if the underlying protocol * supports the socketpair call. @@ -1288,6 +1294,9 @@ asmlinkage long sys_bind(int fd, struct char address[MAX_SOCK_ADDR]; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if((sock = sockfd_lookup(fd,&err))!=NULL) { if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) { @@ -1317,6 +1326,9 @@ asmlinkage long sys_listen(int fd, int b struct socket *sock; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((sock = sockfd_lookup(fd, &err)) != NULL) { if ((unsigned) backlog > sysctl_somaxconn) backlog = sysctl_somaxconn; @@ -1352,6 +1364,9 @@ asmlinkage long sys_accept(int fd, struc int err, len; char address[MAX_SOCK_ADDR]; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1422,6 +1437,9 @@ asmlinkage long sys_connect(int fd, stru char address[MAX_SOCK_ADDR]; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1452,6 +1470,9 @@ asmlinkage long sys_getsockname(int fd, char address[MAX_SOCK_ADDR]; int len, err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1482,6 +1503,9 @@ asmlinkage long sys_getpeername(int fd, char address[MAX_SOCK_ADDR]; int len, err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((sock = sockfd_lookup(fd, &err))!=NULL) { err = security_socket_getpeername(sock); @@ -1513,6 +1537,9 @@ asmlinkage long sys_sendto(int fd, void struct msghdr msg; struct iovec iov; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1567,6 +1594,9 @@ asmlinkage long sys_recvfrom(int fd, voi char address[MAX_SOCK_ADDR]; int err,err2; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1613,6 +1643,9 @@ asmlinkage long sys_setsockopt(int fd, i int err; struct socket *sock; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (optlen < 0) return -EINVAL; @@ -1643,6 +1676,9 @@ asmlinkage long sys_getsockopt(int fd, i int err; struct socket *sock; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((sock = sockfd_lookup(fd, &err))!=NULL) { err = security_socket_getsockopt(sock, level, @@ -1671,6 +1707,9 @@ asmlinkage long sys_shutdown(int fd, int int err; struct socket *sock; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((sock = sockfd_lookup(fd, &err))!=NULL) { err = security_socket_shutdown(sock, how); @@ -1710,6 +1749,9 @@ asmlinkage long sys_sendmsg(int fd, stru struct msghdr msg_sys; int err, ctl_len, iov_size, total_len; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + err = -EFAULT; if (MSG_CMSG_COMPAT & flags) { if (get_compat_msghdr(&msg_sys, msg_compat)) @@ -1811,6 +1853,9 @@ asmlinkage long sys_recvmsg(int fd, stru struct sockaddr __user *uaddr; int __user *uaddr_len; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (MSG_CMSG_COMPAT & flags) { if (get_compat_msghdr(&msg_sys, msg_compat)) return -EFAULT; @@ -1913,6 +1958,9 @@ asmlinkage long sys_socketcall(int call, unsigned long a0,a1; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if(call<1||call>SYS_RECVMSG) return -EINVAL; @@ -2100,3 +2148,9 @@ EXPORT_SYMBOL(sock_wake_async); EXPORT_SYMBOL(sockfd_lookup); EXPORT_SYMBOL(kernel_sendmsg); EXPORT_SYMBOL(kernel_recvmsg); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.15.5/security/keys/keyctl.c linux-2.6.15.5-cher1/security/keys/keyctl.c --- linux-2.6.15.5/security/keys/keyctl.c Thu Mar 2 01:37:27 2006 +++ linux-2.6.15.5-cher1/security/keys/keyctl.c Thu Mar 2 12:58:20 2006 @@ -39,6 +39,9 @@ asmlinkage long sys_add_key(const char _ void *payload; long dlen, ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + ret = -EINVAL; if (plen > 32767) goto error; @@ -137,6 +140,9 @@ asmlinkage long sys_request_key(const ch char type[32], *description, *callout_info; long dlen, ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* pull the type into kernel space */ ret = strncpy_from_user(type, _type, sizeof(type) - 1); if (ret < 0) @@ -977,6 +983,9 @@ long keyctl_set_reqkey_keyring(int reqke asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (option) { case KEYCTL_GET_KEYRING_ID: return keyctl_get_keyring_ID((key_serial_t) arg2, @@ -1048,3 +1057,9 @@ asmlinkage long sys_keyctl(int option, u } } /* end sys_keyctl() */ + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */