diff -ruNp linux-2.6.16.12/arch/i386/kernel/ioport.c linux-2.6.16.12-cher1/arch/i386/kernel/ioport.c --- linux-2.6.16.12/arch/i386/kernel/ioport.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/arch/i386/kernel/ioport.c 2006-05-02 08:14:10.000000000 +0400 @@ -62,6 +62,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)) @@ -138,6 +141,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? */ @@ -150,3 +156,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.16.12/arch/i386/kernel/ldt.c linux-2.6.16.12-cher1/arch/i386/kernel/ldt.c --- linux-2.6.16.12/arch/i386/kernel/ldt.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/arch/i386/kernel/ldt.c 2006-05-02 08:14:10.000000000 +0400 @@ -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.16.12/arch/i386/kernel/process.c linux-2.6.16.12-cher1/arch/i386/kernel/process.c --- linux-2.6.16.12/arch/i386/kernel/process.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/arch/i386/kernel/process.c 2006-05-02 08:14:10.000000000 +0400 @@ -742,6 +742,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); @@ -753,6 +758,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.. */ @@ -911,3 +924,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.16.12/arch/i386/kernel/sys_i386.c linux-2.6.16.12-cher1/arch/i386/kernel/sys_i386.c --- linux-2.6.16.12/arch/i386/kernel/sys_i386.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/arch/i386/kernel/sys_i386.c 2006-05-02 08:14:10.000000000 +0400 @@ -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.16.12/arch/i386/kernel/vm86.c linux-2.6.16.12-cher1/arch/i386/kernel/vm86.c --- linux-2.6.16.12/arch/i386/kernel/vm86.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/arch/i386/kernel/vm86.c 2006-05-02 08:14:10.000000000 +0400 @@ -181,6 +181,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; @@ -211,6 +214,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: @@ -815,3 +821,8 @@ static int do_vm86_irq_handling(int subf return -EINVAL; } +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/arch/i386/SYSCALLS.i368 linux-2.6.16.12-cher1/arch/i386/SYSCALLS.i368 --- linux-2.6.16.12/arch/i386/SYSCALLS.i368 1970-01-01 03:00:00.000000000 +0300 +++ linux-2.6.16.12-cher1/arch/i386/SYSCALLS.i368 2006-05-02 08:14:10.000000000 +0400 @@ -0,0 +1,317 @@ +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 kernel/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 +sys_migrate_pages mm/mempolicy.c CAP +sys_openat fs/namei.c CAP +sys_mkdirat fs/namei.c CAP +sys_mknodat fs/namei.c CAP +sys_fchownat fs/open.c CAP +sys_futimesat fs/open.c CAP +sys_fstatat64 fs/stat.c CAP +sys_unlinkat fs/namei.c CAP +sys_renameat fs/namei.c CAP +sys_linkat fs/namei.c CAP +sys_symlinkat fs/namei.c CAP +sys_readlinkat fs/stat.c CAP +sys_fchmodat fs/open.c CAP +sys_faccessat fs/open.c CAP +sys_pselect6 +sys_ppoll +sys_unshare kernel/fork.c CAP + + +!!!! This is syscall 0 +sys_restart_syscall +syscall table in arch/i386/kernel/syscall_table.S + +*sys_fork, sys_vfork, sys_clone -> do_fork (kernel/fork.c) diff -ruNp linux-2.6.16.12/arch/x86_64/ia32/ipc32.c linux-2.6.16.12-cher1/arch/x86_64/ia32/ipc32.c --- linux-2.6.16.12/arch/x86_64/ia32/ipc32.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/arch/x86_64/ia32/ipc32.c 2006-05-02 08:14:11.000000000 +0400 @@ -17,6 +17,9 @@ sys32_ipc(u32 call, int first, int secon { int version; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; diff -ruNp linux-2.6.16.12/arch/x86_64/ia32/ptrace32.c linux-2.6.16.12-cher1/arch/x86_64/ia32/ptrace32.c --- linux-2.6.16.12/arch/x86_64/ia32/ptrace32.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/arch/x86_64/ia32/ptrace32.c 2006-05-02 08:14:11.000000000 +0400 @@ -207,6 +207,9 @@ asmlinkage long sys32_ptrace(long reques int ret; __u32 val; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (request) { default: return sys_ptrace(request, pid, addr, data); @@ -358,3 +361,8 @@ asmlinkage long sys32_ptrace(long reques return ret; } +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/arch/x86_64/ia32/sys_ia32.c linux-2.6.16.12-cher1/arch/x86_64/ia32/sys_ia32.c --- linux-2.6.16.12/arch/x86_64/ia32/sys_ia32.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/arch/x86_64/ia32/sys_ia32.c 2006-05-02 08:14:11.000000000 +0400 @@ -154,7 +154,12 @@ asmlinkage long sys32_stat64(char __user * filename, struct stat64 __user *statbuf) { struct kstat stat; - int ret = vfs_stat(filename, &stat); + int ret; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + ret = vfs_stat(filename, &stat); if (!ret) ret = cp_stat64(statbuf, &stat); return ret; @@ -164,7 +169,12 @@ asmlinkage long sys32_lstat64(char __user * filename, struct stat64 __user *statbuf) { struct kstat stat; - int ret = vfs_lstat(filename, &stat); + int ret; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + ret = vfs_lstat(filename, &stat); if (!ret) ret = cp_stat64(statbuf, &stat); return ret; @@ -174,7 +184,12 @@ asmlinkage long sys32_fstat64(unsigned int fd, struct stat64 __user *statbuf) { struct kstat stat; - int ret = vfs_fstat(fd, &stat); + int ret; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + ret = vfs_fstat(fd, &stat); if (!ret) ret = cp_stat64(statbuf, &stat); return ret; @@ -187,6 +202,9 @@ sys32_fstatat(unsigned int dfd, char __u struct kstat stat; int error = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) goto out; @@ -231,6 +249,11 @@ sys32_mmap(struct mmap_arg_struct __user if (a.offset & ~PAGE_MASK) return -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) { + if (!(a.flags & MAP_ANONYMOUS)) return -EPERM; + a.fd = -1; + } + if (!(a.flags & MAP_ANONYMOUS)) { file = fget(a.fd); if (!file) @@ -260,6 +283,9 @@ sys32_pipe(int __user *fd) int retval; int fds[2]; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = do_pipe(fds); if (retval) goto out; @@ -478,6 +504,9 @@ sys32_settimeofday(struct compat_timeval struct timespec kts; struct timezone ktz; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (tv) { if (get_tv32(&ktv, tv)) return -EFAULT; @@ -567,6 +596,9 @@ sys32_sysinfo(struct sysinfo32 __user *i mm_segment_t old_fs = get_fs (); int bitcount = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + set_fs (KERNEL_DS); ret = sys_sysinfo(&s); set_fs (old_fs); @@ -654,6 +686,9 @@ sys32_rt_sigqueueinfo(int pid, int sig, int ret; mm_segment_t old_fs = get_fs(); + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (copy_siginfo_from_user32(&info, uinfo)) return -EFAULT; set_fs (KERNEL_DS); @@ -697,6 +732,9 @@ sys32_sysctl(struct sysctl_ia32 __user * void *newval, size_t newlen); + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (copy_from_user(&a32, args32, sizeof (a32))) return -EFAULT; @@ -802,6 +840,9 @@ sys32_adjtimex(struct timex32 __user *ut struct timex txc; int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + memset(&txc, 0, sizeof(struct timex)); if (!access_ok(VERIFY_READ, utp, sizeof(struct timex32)) || @@ -863,6 +904,11 @@ asmlinkage long sys32_mmap2(unsigned lon unsigned long error; struct file * file = NULL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) { + if (!(flags & MAP_ANONYMOUS)) return -EPERM; + fd = -1; + } + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); if (!(flags & MAP_ANONYMOUS)) { file = fget(fd); @@ -882,7 +928,10 @@ asmlinkage long sys32_mmap2(unsigned lon asmlinkage long sys32_olduname(struct oldold_utsname __user * name) { int error; - +/* + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; +*/ if (!name) return -EFAULT; if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) @@ -916,6 +965,10 @@ asmlinkage long sys32_olduname(struct ol long sys32_uname(struct old_utsname __user * name) { int err; +/* + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; +*/ if (!name) return -EFAULT; down_read(&uts_sem); @@ -931,7 +984,10 @@ long sys32_ustat(unsigned dev, struct us struct ustat u; mm_segment_t seg; int ret; - + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + seg = get_fs(); set_fs(KERNEL_DS); ret = sys_ustat(dev,&u); @@ -952,6 +1008,11 @@ asmlinkage long sys32_execve(char __user { long 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(name); error = PTR_ERR(filename); @@ -960,6 +1021,14 @@ asmlinkage long sys32_execve(char __user error = compat_do_execve(filename, argv, envp, regs); 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); } @@ -1028,3 +1097,9 @@ __initcall(ia32_init); extern unsigned long ia32_sys_call_table[]; EXPORT_SYMBOL(ia32_sys_call_table); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/arch/x86_64/kernel/ioport.c linux-2.6.16.12-cher1/arch/x86_64/kernel/ioport.c --- linux-2.6.16.12/arch/x86_64/kernel/ioport.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/arch/x86_64/kernel/ioport.c 2006-05-02 08:14:11.000000000 +0400 @@ -39,6 +39,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)) @@ -106,6 +109,9 @@ asmlinkage long sys_iopl(unsigned int le { unsigned int old = (regs->eflags >> 12) & 3; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (level > 3) return -EINVAL; /* Trying to gain more privileges? */ @@ -116,3 +122,9 @@ asmlinkage long sys_iopl(unsigned int le regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12); return 0; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/arch/x86_64/kernel/ldt.c linux-2.6.16.12-cher1/arch/x86_64/kernel/ldt.c --- linux-2.6.16.12/arch/x86_64/kernel/ldt.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/arch/x86_64/kernel/ldt.c 2006-05-02 08:14:11.000000000 +0400 @@ -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.16.12/arch/x86_64/kernel/process.c linux-2.6.16.12-cher1/arch/x86_64/kernel/process.c --- linux-2.6.16.12/arch/x86_64/kernel/process.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/arch/x86_64/kernel/process.c 2006-05-02 08:14:11.000000000 +0400 @@ -643,6 +643,11 @@ long sys_execve(char __user *name, char { long 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(name); error = PTR_ERR(filename); @@ -651,6 +656,14 @@ long sys_execve(char __user *name, char error = do_execve(filename, argv, envp, ®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); } @@ -845,3 +858,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.16.12/arch/x86_64/kernel/sys_x86_64.c linux-2.6.16.12-cher1/arch/x86_64/kernel/sys_x86_64.c --- linux-2.6.16.12/arch/x86_64/kernel/sys_x86_64.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/arch/x86_64/kernel/sys_x86_64.c 2006-05-02 08:14:11.000000000 +0400 @@ -29,6 +29,9 @@ asmlinkage long sys_pipe(int __user *fil 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))) @@ -43,6 +46,11 @@ asmlinkage long sys_mmap(unsigned long a long error; struct file * file; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) { + if (!(flags & MAP_ANONYMOUS)) return -EPERM; + fd = -1; + } + error = -EINVAL; if (off & ~PAGE_MASK) goto out; @@ -147,6 +155,10 @@ full_search: asmlinkage long sys_uname(struct new_utsname __user * name) { int err; +/* + 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); @@ -154,3 +166,9 @@ asmlinkage long sys_uname(struct new_uts err |= copy_to_user(&name->machine, "i686", 5); return err ? -EFAULT : 0; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/arch/x86_64/SYSCALLS.x86_64 linux-2.6.16.12-cher1/arch/x86_64/SYSCALLS.x86_64 --- linux-2.6.16.12/arch/x86_64/SYSCALLS.x86_64 1970-01-01 03:00:00.000000000 +0300 +++ linux-2.6.16.12-cher1/arch/x86_64/SYSCALLS.x86_64 2006-05-02 08:14:11.000000000 +0400 @@ -0,0 +1,276 @@ +sys_write OK +sys_open fs/open.c CAP +sys_close OK +sys_newstat fs/stat.c CAP +sys_newfstat fs/stat.c CAP +sys_newlstat fs/stat.c CAP +sys_poll OK +sys_lseek fs/read_write.c CAP +sys_mmap arch/x86_64/kernel/sys_x86_64.c CAP +sys_mprotect mm/mprotect.c CAP +sys_munmap OK +sys_brk OK +sys_rt_sigaction OK +sys_rt_sigprocmask OK +stub_rt_sigreturn OK +sys_ioctl fs/ioctl.c CAP +sys_pread64 fs/read_write.c CAP +sys_pwrite64 fs/read_write.c CAP +sys_readv OK +sys_writev OK +sys_access fs/open.c CAP +sys_pipe arch/x86_64/kernel/sys_x86_64.c CAP +sys_select OK +sys_sched_yield kernel/sched.c OK +sys_mremap mm/mremap.c CAP +sys_msync OK +sys_mincore mm/mincore.c CAP +sys_madvise mm/madvise.c CAP +sys_shmget ipc/shm.c CAP +sys_shmat ipc/shm.c CAP +sys_shmctl ipc/shm.c CAP +sys_dup fs/fcntl.c CAP +sys_dup2 fs/fcntl.c CAP +sys_pause kernel/signal.c CAP +sys_nanosleep OK +sys_getitimer OK +sys_alarm kernel/timer.c OK +sys_setitimer OK +sys_getpid OK +sys_sendfile64 fs/read_write.c CAP +sys_socket net/socket.c CAP +sys_connect net/socket.c CAP +sys_accept net/socket.c CAP +sys_sendto net/socket.c CAP +sys_recvfrom net/socket.c CAP +sys_sendmsg net/socket.c CAP +sys_recvmsg net/socket.c CAP +sys_shutdown net/socket.c CAP +sys_bind net/socket.c CAP +sys_listen net/socket.c CAP +sys_getsockname net/socket.c CAP +sys_getpeername net/socket.c CAP +sys_socketpair net/socket.c CAP +sys_setsockopt net/socket.c CAP +sys_getsockopt net/socket.c CAP +stub_clone arch/x86_64/kernel/entry.S (1) CAP +stub_fork arch/x86_64/kernel/entry.S (1) CAP +stub_vfork arch/x86_64/kernel/entry.S (1) CAP +stub_execve arch/x86_64/kernel/entry.S (2) CAP +sys_exit OK +sys_wait4 kernel/exit.c CAP +sys_kill kernel/signal.c CAP +sys_uname arch/x86_64/kernel/sys_x86_64.c CAP +sys_semget ipc/sem.c CAP +sys_semop ipc/sem.c CAP +sys_semctl ipc/sem.c CAP +sys_shmdt ipc/shm.c CAP +sys_msgget ipc/msg.c CAP +sys_msgsnd ipc/msg.c CAP +sys_msgrcv ipc/msg.c CAP +sys_msgctl ipc/msg.c CAP +sys_fcntl fs/fcntl.c CAP +sys_flock fs/locks.c CAP +sys_fsync fs/buffer.c CAP +sys_fdatasync fs/buffer.c CAP +sys_truncate fs/open.c CAP +sys_ftruncate fs/open.c CAP +sys_getdents fs/readdir.c CAP +sys_getcwd fs/dcache.c CAP +sys_chdir fs/open.c CAP +sys_fchdir fs/open.c CAP +sys_rename fs/namei.c CAP +sys_mkdir fs/namei.c CAP +sys_rmdir fs/namei.c CAP +sys_creat fs/open.c CAP +sys_link fs/namei.c CAP +sys_unlink fs/namei.c CAP +sys_symlink fs/namei.c CAP +sys_readlink fs/stat.c CAP +sys_chmod fs/open.c CAP +sys_fchmod fs/open.c CAP +sys_chown fs/open.c CAP +sys_fchown fs/open.c CAP +sys_lchown fs/open.c CAP +sys_umask kernel/sys.c CAP +sys_gettimeofday OK +sys_getrlimit kernel/sys.c OK +sys_getrusage kernel/sys.c OK +sys_sysinfo kernel/timer.c CAP +sys_times OK +sys_ptrace kernel/ptrace.c CAP +sys_getuid kernel/timer.c OK +sys_syslog kernel/printk.c CAP +sys_getgid OK +sys_setuid kernel/sys.c CAP +sys_setgid kernel/sys.c CAP +sys_geteuid OK +sys_getegid OK +sys_setpgid kernel/sys.c CAP +sys_getppid OK +sys_getpgrp kernel/sys.c OK +sys_setsid kernel/sys.c CAP +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_setresuid kernel/sys.c CAP +sys_getresuid kernel/sys.c CAP +sys_setresgid kernel/sys.c CAP +sys_getresgid kernel/sys.c CAP +sys_getpgid kernel/sys.c CAP +sys_setfsuid kernel/sys.c CAP +sys_setfsgid kernel/sys.c CAP +sys_getsid kernel/sys.c CAP +sys_capget kernel/capability.c CAP +sys_capset kernel/capability.c CAP +sys_rt_sigpending OK +sys_rt_sigtimedwait OK +sys_rt_sigqueueinfo kernel/signal.c CAP +stub_rt_sigsuspend OK +stub_sigaltstack OK +sys_utime fs/open.c CAP +sys_mknod fs/namei.c CAP +sys_ni_syscall --- +sys_personality kernel/exec_domain.c CAP +sys_ustat fs/super.c CAP +sys_statfs fs/open.c CAP +sys_fstatfs fs/open.c CAP +sys_sysfs fs/filesystems.c CAP +sys_getpriority kernel/sys.c CAP +sys_setpriority kernel/sys.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_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_mlock mm/mlock.c CAP +sys_munlock mm/mlock.c CAP +sys_mlockall mm/mlock.c CAP +sys_munlockall mm/mlock.c CAP +sys_vhangup fs/open.c CAP +sys_modify_ldt arch/x86_64/kernel/ldt.c CAP +sys_pivot_root fs/namespace.c CAP +sys_sysctl kernel/sysctl.c CAP +sys_prctl kernel/sys.c CAP +sys_arch_prctl OK +sys_adjtimex kernel/time.c CAP +sys_setrlimit kernel/sys.c CAP +sys_chroot fs/open.c CAP +sys_sync fs/buffer.c CAP +sys_acct kernel/acct.c CAP +sys_settimeofday kernel/time.c CAP +sys_mount fs/namespace.c CAP +sys_umount fs/namespace.c CAP +sys_swapon mm/swapfile.c CAP +sys_swapoff mm/swapfile.c CAP +sys_reboot kernel/sys.c CAP +sys_sethostname kernel/sys.c CAP +sys_setdomainname kernel/sys.c CAP +stub_iopl arch/x86_64/kernel/ioport.c CAP +sys_ioperm arch/x86_64/kernel/ioport.c CAP +sys_ni_syscall --- +sys_init_module kernel/module.c CAP +sys_delete_module kernel/module.c CAP +sys_ni_syscall --- +sys_ni_syscall --- +sys_quotactl fs/quota.c CAP +sys_nfsservctl fs/nfsctl.c CAP +sys_ni_syscall --- +sys_ni_syscall --- +sys_ni_syscall --- +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_time OK +sys_futex OK +sys_sched_setaffinity kernel/sched.c CAP +sys_sched_getaffinity kernel/sched.c CAP +sys_ni_syscall --- +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_ni_syscall --- +sys_lookup_dcookie fs/dcookies.c CAP +sys_epoll_create fs/eventpoll.c CAP +sys_ni_syscall --- +sys_ni_syscall --- +sys_remap_file_pages fs/fremap.c CAP +sys_getdents64 fs/readdir.c CAP +sys_set_tid_address OK +sys_restart_syscall OK +sys_semtimedop ipc/sem.c CAP +sys_fadvise64 mm/fadvise.c CAP +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_exit_group OK +sys_epoll_wait fs/eventpoll.c CAP +sys_epoll_ctl fs/eventpoll.c CAP +sys_tgkill kernel/signal.c CAP +sys_utimes fs/open.c CAP +sys_ni_syscall --- +sys_mbind mm/mempolicy.c CAP +sys_set_mempolicy mm/mempolicy.c CAP +sys_get_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_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 +sys_migrate_pages mm/mempolicy.c CAP +sys_openat fs/namei.c CAP +sys_mkdirat fs/namei.c CAP +sys_mknodat fs/namei.c CAP +sys_fchownat fs/open.c CAP +sys_futimesat fs/open.c CAP +sys_newfstatat fs/stat.c CAP +sys_unlinkat fs/namei.c CAP +sys_renameat fs/namei.c CAP +sys_linkat fs/namei.c CAP +sys_symlinkat fs/namei.c CAP +sys_readlinkat fs/stat.c CAP +sys_fchmodat fs/open.c CAP +sys_faccessat fs/open.c CAP +sys_ni_syscall (pselect6) +sys_ni_syscall (ppoll) +sys_unshare kernel/fork.c CAP + + +syscall 0 is `read' +syscall numbers is include/asm-x86_64/unistd.h diff -ruNp linux-2.6.16.12/arch/x86_64/SYSCALLS.x86_64_ia32 linux-2.6.16.12-cher1/arch/x86_64/SYSCALLS.x86_64_ia32 --- linux-2.6.16.12/arch/x86_64/SYSCALLS.x86_64_ia32 1970-01-01 03:00:00.000000000 +0300 +++ linux-2.6.16.12-cher1/arch/x86_64/SYSCALLS.x86_64_ia32 2006-05-02 08:14:11.000000000 +0400 @@ -0,0 +1,314 @@ +sys_exit OK +stub32_fork arch/x86_64/ia32/ia32entry.S CAP +sys_read OK +sys_write OK +compat_sys_open fs/compat.c CAP +sys_close OK +sys32_waitpid arch/x86_64/ia32/sys_ia32.c CAP +sys_creat fs/open.c CAP +sys_link fs/namei.c CAP +sys_unlink fs/namei.c CAP +stub32_execve arch/x86_64/ia32/ia32entry.S CAP +sys_chdir fs/open.c CAP +compat_sys_time kernel/compat.c OK +sys_mknod fs/namei.c CAP +sys_chmod fs/open.c CAP +sys_lchown16 kernel/uid16.c CAP +quiet_ni_syscall --- +sys_stat fs/stat.c CAP +sys32_lseek arch/x86_64/ia32/sys_ia32.c CAP +sys_getpid OK +compat_sys_mount fs/compat.c CAP +sys_oldumount fs/namespace.c CAP +sys_setuid16 kernel/uid16.c CAP +sys_getuid16 kernel/uid16.c OK +compat_sys_stime kernel/compat.c CAP +sys32_ptrace arch/x86_64/ia32/ptrace32.c CAP +sys_alarm kernel/timer.c OK +sys_fstat fs/stat.c CAP +sys_pause kernel/signal.c CAP +compat_sys_utime fs/compat.c CAP +quiet_ni_syscall --- +quiet_ni_syscall --- +sys_access fs/open.c CAP +sys_nice kernel/sched.c CAP +quiet_ni_syscall --- +sys_sync fs/buffer.c CAP +sys32_kill arch/x86_64/ia32/sys_ia32.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 +sys32_pipe arch/x86_64/ia32/sys_ia32.c CAP +compat_sys_times OK +quiet_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 +quiet_ni_syscall --- +compat_sys_ioctl fs/compat.c CAP +compat_sys_fcntl64 fs/compat.c CAP +quiet_ni_syscall --- +sys_setpgid kernel/sys.c CAP +quiet_ni_syscall --- +sys32_olduname arch/x86_64/ia32/sys_ia32.c CAP +sys_umask kernel/sys.c CAP +sys_chroot fs/open.c CAP +sys32_ustat arch/x86_64/ia32/sys_ia32.c CAP +sys_dup2 fs/fcntl.c CAP +sys_getppid OK +sys_getpgrp kernel/sys.c OK +sys_setsid kernel/sys.c CAP +sys32_sigaction OK +sys_sgetmask OK +sys_ssetmask OK +sys_setreuid16 kernel/uid16.c CAP +sys_setregid16 kernel/uid16.c CAP +stub32_sigsuspend OK +compat_sys_sigpending OK +sys_sethostname kernel/sys.c CAP +compat_sys_setrlimit kernel/compat.c CAP +compat_sys_old_getrlimit OK +compat_sys_getrusage OK +sys32_gettimeofday OK +sys32_settimeofday arch/x86_64/ia32/sys_ia32.c CAP +sys_getgroups16 kernel/uid16.c CAP +sys_setgroups16 kernel/uid16.c CAP +sys32_old_select 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 +compat_sys_old_readdir fs/compat.c CAP +sys32_mmap arch/x86_64/ia32/sys_ia32.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 +quiet_ni_syscall --- +compat_sys_statfs fs/compat.c CAP +compat_sys_fstatfs fs/compat.c CAP +sys_ioperm arch/x86_64/kernel/ioport.c CAP +compat_sys_socketcall net/compat.c CAP +sys_syslog kernel/printk.c CAP +compat_sys_setitimer OK +compat_sys_getitimer OK +compat_sys_newstat fs/compat.c CAP +compat_sys_newlstat fs/compat.c CAP +compat_sys_newfstat fs/compat.c CAP +sys32_uname arch/x86_64/ia32/sys_ia32.c CAP +stub32_iopl arch/x86_64/ia32/ia32entry.S CAP +sys_vhangup fs/open.c CAP +quiet_ni_syscall --- +sys32_vm86_warning OK +compat_sys_wait4 kernel/compat.c CAP +sys_swapoff mm/swapfile.c CAP +sys32_sysinfo arch/x86_64/ia32/sys_ia32.c CAP +sys32_ipc arch/x86_64/ia32/ipc32.c CAP +sys_fsync fs/buffer.c CAP +stub32_sigreturn OK +stub32_clone arch/x86_64/ia32/sys_ia32.c CAP +sys_setdomainname kernel/sys.c CAP +sys_uname arch/x86_64/kernel/sys_x86_64.c CAP +sys_modify_ldt arch/x86_64/kernel/ldt.c CAP +sys32_adjtimex arch/x86_64/ia32/sys_ia32.c CAP +sys32_mprotect arch/x86_64/ia32/sys_ia32.c CAP +compat_sys_sigprocmask OK +quiet_ni_syscall --- +sys_init_module kernel/module.c CAP +sys_delete_module kernel/module.c CAP +quiet_ni_syscall --- +sys_quotactl fs/quota.c CAP +sys_getpgid kernel/sys.c CAP +sys_fchdir fs/open.c CAP +quiet_ni_syscall --- +sys_sysfs fs/filesystems.c CAP +sys_personality kernel/exec_domain.c CAP +quiet_ni_syscall --- +sys_setfsuid16 kernel/uid16.c CAP +sys_setfsgid16 kernel/uid16.c CAP +sys_llseek fs/read_write.c CAP +compat_sys_getdents fs/compat.c CAP +compat_sys_select OK +sys_flock fs/locks.c CAP +sys_msync OK +compat_sys_readv OK +compat_sys_writev OK +sys_getsid kernel/sys.c CAP +sys_fdatasync fs/buffer.c CAP +sys32_sysctl arch/x86_64/ia32/sys_ia32.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 +compat_sys_nanosleep OK +sys_mremap mm/mremap.c CAP +sys_setresuid16 kernel/uid16.c CAP +sys_getresuid16 OK +sys32_vm86_warning OK +quiet_ni_syscall --- +sys_poll OK +compat_sys_nfsservctl fs/compat.c OK +sys_setresgid16 kernel/uid16.c CAP +sys_getresgid16 OK +sys_prctl kernel/sys.c CAP +stub32_rt_sigreturn OK +sys32_rt_sigaction OK +sys32_rt_sigprocmask OK +sys32_rt_sigpending OK +compat_sys_rt_sigtimedwait OK +sys32_rt_sigqueueinfo arch/x86_64/ia32/sys_ia32.c CAP +stub32_rt_sigsuspend OK +sys32_pread arch/x86_64/ia32/sys_ia32.c CAP +sys32_pwrite arch/x86_64/ia32/sys_ia32.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 +stub32_sigaltstack OK +sys32_sendfile arch/x86_64/ia32/sys_ia32.c CAP +quiet_ni_syscall --- +quiet_ni_syscall --- +stub32_vfork arch/x86_64/ia32/ia32entry.S CAP +compat_sys_getrlimit OK +sys32_mmap2 arch/x86_64/ia32/sys_ia32.c CAP +sys32_truncate64 arch/x86_64/ia32/sys_ia32.c CAP +sys32_ftruncate64 arch/x86_64/ia32/sys_ia32.c CAP +sys32_stat64 arch/x86_64/ia32/sys_ia32.c CAP +sys32_lstat64 arch/x86_64/ia32/sys_ia32.c CAP +sys32_fstat64 arch/x86_64/ia32/sys_ia32.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 +compat_sys_getdents64 fs/compat.c CAP +compat_sys_fcntl64 fs/compat.c CAP +quiet_ni_syscall --- +quiet_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 +compat_sys_futex OK +compat_sys_sched_setaffinity kernel/compat.c CAP +compat_sys_sched_getaffinity kernel/compat.c CAP +sys32_set_thread_area OK +sys32_get_thread_area OK +compat_sys_io_setup fs/compat.c CAP +sys_io_destroy fs/aio.c CAP +compat_sys_io_getevents fs/compat.c CAP +compat_sys_io_submit fs/compat.c CAP +sys_io_cancel fs/aio.c CAP +sys_fadvise64 mm/fadvise.c CAP +quiet_ni_syscall --- +sys_exit_group OK +sys32_lookup_dcookie arch/x86_64/ia32/sys_ia32.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 +sys32_timer_create arch/x86_64/ia32/sys_ia32.c CAP +compat_sys_timer_settime kernel/compat.c CAP +compat_sys_timer_gettime kernel/compat.c CAP +sys_timer_getoverrun kernel/posix-timers.c CAP +sys_timer_delete kernel/posix-timers.c CAP +compat_sys_clock_settime kernel/compat.c CAP +compat_sys_clock_gettime kernel/compat.c CAP +compat_sys_clock_getres kernel/compat.c CAP +compat_sys_clock_nanosleep kernel/compat.c CAP +compat_sys_statfs64 fs/compat.c CAP +compat_sys_fstatfs64 fs/compat.c CAP +sys_tgkill kernel/signal.c CAP +compat_sys_utimes fs/compat.c CAP +sys32_fadvise64_64 arch/x86_64/ia32/sys_ia32.c CAP +quiet_ni_syscall --- +sys_mbind mm/mempolicy.c CAP +compat_sys_get_mempolicy mm/mempolicy.c CAP +sys_set_mempolicy mm/mempolicy.c CAP +compat_sys_mq_open ipc/compat_mq.c CAP +sys_mq_unlink ipc/mqueue.c CAP +compat_sys_mq_timedsend ipc/compat_mq.c CAP +compat_sys_mq_timedreceive ipc/compat_mq.c CAP +compat_sys_mq_notify ipc/compat_mq.c CAP +compat_sys_mq_getsetattr ipc/compat_mq.c CAP +compat_sys_kexec_load kernel/kexec.c CAP +compat_sys_waitid kernel/compat.c CAP +quiet_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 +sys_migrate_pages mm/mempolicy.c CAP +compat_sys_openat fs/compat.c CAP +sys_mkdirat fs/namei.c CAP +sys_mknodat fs/namei.c CAP +sys_fchownat fs/open.c CAP +compat_sys_futimesat fs/compat.c CAP +sys32_fstatat arch/x86_64/ia32/sys_ia32.c CAP +sys_unlinkat fs/namei.c CAP +sys_renameat fs/namei.c CAP +sys_linkat fs/namei.c CAP +sys_symlinkat fs/namei.c CAP +sys_readlinkat fs/stat.c CAP +sys_fchmodat fs/open.c CAP +sys_faccessat fs/open.c CAP +sys_ni_syscall (pselect6) +sys_ni_syscall (ppoll) +sys_unshare kernel/fork.c CAP + + +syscall 0 is `sys_restart_syscall' +syscall table in arch/x86_64/ia32/ia32entry.S diff -ruNp linux-2.6.16.12/fs/aio.c linux-2.6.16.12-cher1/fs/aio.c --- linux-2.6.16.12/fs/aio.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/aio.c 2006-05-02 08:14:11.000000000 +0400 @@ -1258,6 +1258,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; @@ -1292,7 +1295,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; @@ -1567,6 +1575,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; @@ -1644,6 +1655,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; @@ -1703,9 +1717,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); @@ -1720,3 +1738,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.16.12/fs/binfmt_aout.c linux-2.6.16.12-cher1/fs/binfmt_aout.c --- linux-2.6.16.12/fs/binfmt_aout.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/binfmt_aout.c 2006-05-02 08:14:11.000000000 +0400 @@ -287,8 +287,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.16.12/fs/binfmt_flat.c linux-2.6.16.12-cher1/fs/binfmt_flat.c --- linux-2.6.16.12/fs/binfmt_flat.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/binfmt_flat.c 2006-05-02 08:14:11.000000000 +0400 @@ -490,8 +490,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) { @@ -899,3 +904,9 @@ core_initcall(init_flat_binfmt); module_exit(exit_flat_binfmt); /****************************************************************************/ + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/fs/buffer.c linux-2.6.16.12-cher1/fs/buffer.c --- linux-2.6.16.12/fs/buffer.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/buffer.c 2006-05-02 08:14:11.000000000 +0400 @@ -289,6 +289,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; } @@ -333,6 +336,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) @@ -3034,6 +3040,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; @@ -3242,3 +3251,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.16.12/fs/compat.c linux-2.6.16.12-cher1/fs/compat.c --- linux-2.6.16.12/fs/compat.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/compat.c 2006-05-02 08:14:11.000000000 +0400 @@ -63,6 +63,9 @@ asmlinkage long compat_sys_utime(char __ { struct timeval tv[2]; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (t) { if (get_user(tv[0].tv_sec, &t->actime) || get_user(tv[1].tv_sec, &t->modtime)) @@ -77,6 +80,9 @@ asmlinkage long compat_sys_futimesat(uns { struct timeval tv[2]; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (t) { if (get_user(tv[0].tv_sec, &t[0].tv_sec) || get_user(tv[0].tv_usec, &t[0].tv_usec) || @@ -96,8 +102,12 @@ asmlinkage long compat_sys_newstat(char struct compat_stat __user *statbuf) { struct kstat stat; - int error = vfs_stat_fd(AT_FDCWD, filename, &stat); + int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + error = vfs_stat_fd(AT_FDCWD, filename, &stat); if (!error) error = cp_compat_stat(&stat, statbuf); return error; @@ -107,9 +117,13 @@ asmlinkage long compat_sys_newlstat(char struct compat_stat __user *statbuf) { struct kstat stat; - int error = vfs_lstat_fd(AT_FDCWD, filename, &stat); + int error; - if (!error) + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + error = vfs_lstat_fd(AT_FDCWD, filename, &stat); + if (!error) error = cp_compat_stat(&stat, statbuf); return error; } @@ -120,6 +134,9 @@ asmlinkage long compat_sys_newfstatat(un struct kstat stat; int error = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) goto out; @@ -139,8 +156,12 @@ asmlinkage long compat_sys_newfstat(unsi struct compat_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_compat_stat(&stat, statbuf); return error; @@ -192,6 +213,9 @@ asmlinkage long compat_sys_statfs(const struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(path, &nd); if (!error) { struct kstatfs tmp; @@ -209,6 +233,9 @@ asmlinkage long compat_sys_fstatfs(unsig struct kstatfs tmp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EBADF; file = fget(fd); if (!file) @@ -257,6 +284,9 @@ asmlinkage long compat_sys_statfs64(cons struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (sz != sizeof(*buf)) return -EINVAL; @@ -277,6 +307,9 @@ asmlinkage long compat_sys_fstatfs64(uns struct kstatfs tmp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (sz != sizeof(*buf)) return -EINVAL; @@ -375,6 +408,9 @@ asmlinkage long compat_sys_ioctl(unsigne struct ioctl_trans *t; int fput_needed; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + filp = fget_light(fd, &fput_needed); if (!filp) goto out; @@ -510,6 +546,9 @@ asmlinkage long compat_sys_fcntl64(unsig struct flock f; long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (cmd) { case F_GETLK: case F_SETLK: @@ -587,6 +626,10 @@ compat_sys_io_setup(unsigned nr_reqs, u3 aio_context_t ctx64; mm_segment_t oldfs = get_fs(); + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (unlikely(get_user(ctx64, ctx32p))) return -EFAULT; @@ -611,6 +654,9 @@ compat_sys_io_getevents(aio_context_t ct struct timespec t; struct timespec __user *ut = NULL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + ret = -EFAULT; if (unlikely(!access_ok(VERIFY_WRITE, events, nr * sizeof(struct io_event)))) @@ -651,6 +697,9 @@ compat_sys_io_submit(aio_context_t ctx_i struct iocb __user * __user *iocb64; long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (unlikely(nr < 0)) return -EINVAL; @@ -838,6 +887,9 @@ asmlinkage long compat_sys_mount(char __ char *dir_page; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = copy_mount_options (type, &type_page); if (retval < 0) goto out; @@ -934,6 +986,9 @@ asmlinkage long compat_sys_old_readdir(u struct file *file; struct compat_readdir_callback buf; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EBADF; file = fget(fd); if (!file) @@ -1009,6 +1064,9 @@ asmlinkage long compat_sys_getdents(unsi struct compat_getdents_callback buf; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EFAULT; if (!access_ok(VERIFY_WRITE, dirent, count)) goto out; @@ -1101,6 +1159,9 @@ asmlinkage long compat_sys_getdents64(un struct compat_getdents_callback64 buf; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EFAULT; if (!access_ok(VERIFY_WRITE, dirent, count)) goto out; @@ -1332,6 +1393,9 @@ compat_sys_open(const char __user *filen asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename, int flags, int mode) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + return do_sys_open(dfd, filename, flags, mode); } @@ -2137,6 +2201,9 @@ asmlinkage long compat_sys_nfsservctl(in mm_segment_t oldfs; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + karg = kmalloc(sizeof(*karg), GFP_USER); kres = kmalloc(sizeof(*kres), GFP_USER); if(!karg || !kres) { @@ -2199,3 +2266,9 @@ long asmlinkage compat_sys_nfsservctl(in return sys_ni_syscall(); } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/fs/dcache.c linux-2.6.16.12-cher1/fs/dcache.c --- linux-2.6.16.12/fs/dcache.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/dcache.c 2006-05-02 08:14:11.000000000 +0400 @@ -1471,8 +1471,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; @@ -1767,3 +1771,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.16.12/fs/dcookies.c linux-2.6.16.12-cher1/fs/dcookies.c --- linux-2.6.16.12/fs/dcookies.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/dcookies.c 2006-05-02 08:14:11.000000000 +0400 @@ -151,6 +151,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 */ @@ -327,3 +330,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.16.12/fs/eventpoll.c linux-2.6.16.12-cher1/fs/eventpoll.c --- linux-2.6.16.12/fs/eventpoll.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/eventpoll.c 2006-05-02 08:14:11.000000000 +0400 @@ -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.16.12/fs/exec.c linux-2.6.16.12-cher1/fs/exec.c --- linux-2.6.16.12/fs/exec.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/exec.c 2006-05-02 08:14:11.000000000 +0400 @@ -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; @@ -1526,3 +1529,9 @@ fail_unlock: fail: return retval; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruNp linux-2.6.16.12/fs/fcntl.c linux-2.6.16.12-cher1/fs/fcntl.c --- linux-2.6.16.12/fs/fcntl.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/fcntl.c 2006-05-02 08:14:11.000000000 +0400 @@ -142,6 +142,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; @@ -194,8 +197,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; @@ -357,6 +364,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; @@ -380,6 +390,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) @@ -623,3 +636,9 @@ static int __init fasync_init(void) } module_init(fasync_init) + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/fs/filesystems.c linux-2.6.16.12-cher1/fs/filesystems.c --- linux-2.6.16.12/fs/filesystems.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/filesystems.c 2006-05-02 08:14:11.000000000 +0400 @@ -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.16.12/fs/inotify.c linux-2.6.16.12-cher1/fs/inotify.c --- linux-2.6.16.12/fs/inotify.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/inotify.c 2006-05-02 08:14:11.000000000 +0400 @@ -870,6 +870,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; @@ -937,6 +940,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; @@ -1012,6 +1018,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; @@ -1078,3 +1087,9 @@ static int __init inotify_setup(void) } module_init(inotify_setup); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/fs/ioctl.c linux-2.6.16.12-cher1/fs/ioctl.c --- linux-2.6.16.12/fs/ioctl.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/ioctl.c 2006-05-02 08:14:11.000000000 +0400 @@ -163,6 +163,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; @@ -185,3 +188,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.16.12/fs/ioprio.c linux-2.6.16.12-cher1/fs/ioprio.c --- linux-2.6.16.12/fs/ioprio.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/ioprio.c 2006-05-02 08:14:11.000000000 +0400 @@ -53,6 +53,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)) @@ -125,6 +128,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: @@ -174,3 +180,8 @@ asmlinkage long sys_ioprio_get(int which return ret; } +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/fs/locks.c linux-2.6.16.12-cher1/fs/locks.c --- linux-2.6.16.12/fs/locks.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/locks.c 2006-05-02 08:14:11.000000000 +0400 @@ -1499,6 +1499,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.16.12/fs/namei.c linux-2.6.16.12-cher1/fs/namei.c --- linux-2.6.16.12/fs/namei.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/namei.c 2006-05-02 08:14:11.000000000 +0400 @@ -1805,6 +1805,9 @@ asmlinkage long sys_mknodat(int dfd, con struct dentry * dentry; struct nameidata nd; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (S_ISDIR(mode)) return -EPERM; tmp = getname(filename); @@ -1879,6 +1882,9 @@ asmlinkage long sys_mkdirat(int dfd, con int error = 0; char * tmp; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + tmp = getname(pathname); error = PTR_ERR(tmp); if (!IS_ERR(tmp)) { @@ -1978,6 +1984,9 @@ static long do_rmdir(int dfd, const char 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); @@ -2061,6 +2070,9 @@ static long do_unlinkat(int dfd, const c 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); @@ -2144,6 +2156,9 @@ asmlinkage long sys_symlinkat(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); @@ -2235,6 +2250,9 @@ asmlinkage long sys_linkat(int olddfd, c if (flags != 0) return -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + to = getname(newname); if (IS_ERR(to)) return PTR_ERR(to); @@ -2500,6 +2518,9 @@ asmlinkage long sys_renameat(int olddfd, char * from; char * to; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + from = getname(oldname); if(IS_ERR(from)) return PTR_ERR(from); @@ -2703,3 +2724,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.16.12/fs/namespace.c linux-2.6.16.12-cher1/fs/namespace.c --- linux-2.6.16.12/fs/namespace.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/namespace.c 2006-05-02 08:14:11.000000000 +0400 @@ -598,6 +598,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; @@ -1438,6 +1441,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; @@ -1571,6 +1577,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; @@ -1763,3 +1772,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.16.12/fs/nfsctl.c linux-2.6.16.12-cher1/fs/nfsctl.c --- linux-2.6.16.12/fs/nfsctl.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/nfsctl.c 2006-05-02 08:14:11.000000000 +0400 @@ -95,6 +95,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; @@ -115,3 +118,9 @@ asmlinkage sys_nfsservctl(int cmd, struc fput(file); return err; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/fs/open.c linux-2.6.16.12-cher1/fs/open.c --- linux-2.6.16.12/fs/open.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/open.c 2006-05-02 08:14:11.000000000 +0400 @@ -126,6 +126,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; @@ -143,6 +146,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); @@ -163,6 +169,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) @@ -181,6 +190,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; @@ -225,6 +237,9 @@ static long do_sys_truncate(const char _ 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; @@ -292,6 +307,9 @@ static long do_sys_ftruncate(unsigned in struct file * file; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EINVAL; if (length < 0) goto out; @@ -372,6 +390,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; @@ -472,6 +493,9 @@ asmlinkage long sys_futimesat(int dfd, c { 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(dfd, filename, utimes ? times : NULL); @@ -495,6 +519,9 @@ asmlinkage long sys_faccessat(int dfd, c 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; @@ -545,6 +572,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; @@ -569,6 +599,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) @@ -596,6 +629,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; @@ -625,6 +661,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; @@ -660,6 +699,9 @@ asmlinkage long sys_fchmodat(int dfd, co int error; struct iattr newattrs; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd); if (error) goto out; @@ -732,6 +774,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); @@ -747,6 +792,9 @@ asmlinkage long sys_fchownat(int dfd, co int error = -EINVAL; int follow; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) goto out; @@ -765,6 +813,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); @@ -779,6 +830,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); @@ -1070,6 +1124,17 @@ long do_sys_open(int dfd, const char __u 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) { @@ -1106,6 +1171,9 @@ asmlinkage long sys_openat(int dfd, cons { long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (force_o_largefile()) flags |= O_LARGEFILE; @@ -1190,6 +1258,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; @@ -1223,3 +1294,9 @@ int nonseekable_open(struct inode *inode } EXPORT_SYMBOL(nonseekable_open); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/fs/quota.c linux-2.6.16.12-cher1/fs/quota.c --- linux-2.6.16.12/fs/quota.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/quota.c 2006-05-02 08:14:11.000000000 +0400 @@ -351,6 +351,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; @@ -376,3 +379,9 @@ asmlinkage long sys_quotactl(unsigned in return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/fs/readdir.c linux-2.6.16.12-cher1/fs/readdir.c --- linux-2.6.16.12/fs/readdir.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/readdir.c 2006-05-02 08:14:11.000000000 +0400 @@ -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.16.12/fs/read_write.c linux-2.6.16.12-cher1/fs/read_write.c --- linux-2.6.16.12/fs/read_write.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/read_write.c 2006-05-02 08:14:11.000000000 +0400 @@ -131,6 +131,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) @@ -158,6 +161,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) @@ -381,6 +387,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; @@ -402,6 +411,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; @@ -737,6 +749,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; @@ -755,6 +770,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; @@ -766,3 +784,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.16.12/fs/stat.c linux-2.6.16.12-cher1/fs/stat.c --- linux-2.6.16.12/fs/stat.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/stat.c 2006-05-02 08:14:11.000000000 +0400 @@ -161,8 +161,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_fd(AT_FDCWD, filename, &stat); + int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + error = vfs_stat_fd(AT_FDCWD, filename, &stat); if (!error) error = cp_old_stat(&stat, statbuf); @@ -171,8 +175,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_fd(AT_FDCWD, filename, &stat); + int error; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = vfs_lstat_fd(AT_FDCWD, filename, &stat); if (!error) error = cp_old_stat(&stat, statbuf); @@ -181,8 +189,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); @@ -242,8 +254,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_fd(AT_FDCWD, filename, &stat); + int error; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = vfs_stat_fd(AT_FDCWD, filename, &stat); if (!error) error = cp_new_stat(&stat, statbuf); @@ -253,8 +269,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_fd(AT_FDCWD, filename, &stat); + int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + error = vfs_lstat_fd(AT_FDCWD, filename, &stat); if (!error) error = cp_new_stat(&stat, statbuf); @@ -268,6 +288,9 @@ asmlinkage long sys_newfstatat(int dfd, struct kstat stat; int error = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) goto out; @@ -287,8 +310,12 @@ out: 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); @@ -301,6 +328,9 @@ asmlinkage long sys_readlinkat(int dfd, struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (bufsiz <= 0) return -EINVAL; @@ -369,8 +399,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); @@ -379,8 +413,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); @@ -389,8 +427,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); @@ -403,6 +445,9 @@ asmlinkage long sys_fstatat64(int dfd, c struct kstat stat; int error = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) goto out; @@ -470,3 +515,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.16.12/fs/super.c linux-2.6.16.12-cher1/fs/super.c --- linux-2.6.16.12/fs/super.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/super.c 2006-05-02 08:14:11.000000000 +0400 @@ -483,6 +483,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.16.12/fs/xattr.c linux-2.6.16.12-cher1/fs/xattr.c --- linux-2.6.16.12/fs/xattr.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/fs/xattr.c 2006-05-02 08:14:11.000000000 +0400 @@ -206,6 +206,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; @@ -221,6 +224,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; @@ -236,6 +242,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; @@ -288,6 +297,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; @@ -303,6 +315,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; @@ -317,6 +332,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; @@ -372,6 +390,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; @@ -386,6 +407,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; @@ -400,6 +424,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; @@ -432,6 +459,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; @@ -446,6 +476,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; @@ -460,6 +493,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; @@ -595,3 +631,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.16.12/include/asm-generic/resource.h linux-2.6.16.12-cher1/include/asm-generic/resource.h --- linux-2.6.16.12/include/asm-generic/resource.h 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/include/asm-generic/resource.h 2006-05-02 08:14:11.000000000 +0400 @@ -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.16.12/include/linux/capability.h linux-2.6.16.12-cher1/include/linux/capability.h --- linux-2.6.16.12/include/linux/capability.h 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/include/linux/capability.h 2006-05-02 08:14:11.000000000 +0400 @@ -288,6 +288,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 @@ -348,10 +357,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.16.12/include/linux/ptrace.h linux-2.6.16.12-cher1/include/linux/ptrace.h --- linux-2.6.16.12/include/linux/ptrace.h 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/include/linux/ptrace.h 2006-05-02 08:14:11.000000000 +0400 @@ -27,6 +27,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.16.12/include/linux/sched.h linux-2.6.16.12-cher1/include/linux/sched.h --- linux-2.6.16.12/include/linux/sched.h 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/include/linux/sched.h 2006-05-02 08:14:11.000000000 +0400 @@ -902,6 +902,9 @@ static inline void put_task_struct(struc call_rcu(&t->rcu, __put_task_struct_cb); } +#define PF_MEMLIMITON 0x01000000 /* Memory limit detection enabled */ +#define PF_MEMLIMITERR 0x02000000 /* Killed for memory limit error */ + /* * Per process flags */ diff -ruNp linux-2.6.16.12/ipc/compat_mq.c linux-2.6.16.12-cher1/ipc/compat_mq.c --- linux-2.6.16.12/ipc/compat_mq.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/ipc/compat_mq.c 2006-05-02 08:14:11.000000000 +0400 @@ -51,6 +51,10 @@ asmlinkage long compat_sys_mq_open(const struct compat_mq_attr __user *u_attr) { void __user *p = NULL; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (u_attr && oflag & O_CREAT) { struct mq_attr attr; p = compat_alloc_user_space(sizeof(attr)); @@ -82,6 +86,9 @@ asmlinkage long compat_sys_mq_timedsend( { struct timespec __user *u_ts; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (compat_prepare_timeout(&u_ts, u_abs_timeout)) return -EFAULT; @@ -95,6 +102,10 @@ asmlinkage ssize_t compat_sys_mq_timedre const struct compat_timespec __user *u_abs_timeout) { struct timespec __user *u_ts; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (compat_prepare_timeout(&u_ts, u_abs_timeout)) return -EFAULT; @@ -106,6 +117,10 @@ asmlinkage long compat_sys_mq_notify(mqd const struct compat_sigevent __user *u_notification) { struct sigevent __user *p = NULL; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (u_notification) { struct sigevent n; p = compat_alloc_user_space(sizeof(*p)); @@ -124,9 +139,13 @@ asmlinkage long compat_sys_mq_getsetattr struct compat_mq_attr __user *u_omqstat) { struct mq_attr mqstat; - struct mq_attr __user *p = compat_alloc_user_space(2 * sizeof(*p)); + struct mq_attr __user *p; long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + p = compat_alloc_user_space(2 * sizeof(*p)); if (u_mqstat) { if (get_compat_mq_attr(&mqstat, u_mqstat) || copy_to_user(p, &mqstat, sizeof(mqstat))) @@ -144,3 +163,9 @@ asmlinkage long compat_sys_mq_getsetattr } return 0; } + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/ipc/mqueue.c linux-2.6.16.12-cher1/ipc/mqueue.c --- linux-2.6.16.12/ipc/mqueue.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/ipc/mqueue.c 2006-05-02 08:14:11.000000000 +0400 @@ -656,6 +656,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); @@ -718,6 +721,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); @@ -813,6 +819,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; @@ -895,6 +904,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; @@ -974,6 +986,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) { @@ -1092,6 +1107,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; @@ -1260,3 +1278,9 @@ out_sysctl: } __initcall(init_mqueue_fs); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/ipc/msg.c linux-2.6.16.12-cher1/ipc/msg.c --- linux-2.6.16.12/ipc/msg.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/ipc/msg.c 2006-05-02 08:14:11.000000000 +0400 @@ -208,6 +208,9 @@ asmlinkage long sys_msgget (key_t key, i int id, ret = -EPERM; struct msg_queue *msq; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + down(&msg_ids.sem); if (key == IPC_PRIVATE) ret = newque(key, msgflg); @@ -334,6 +337,9 @@ asmlinkage long sys_msgctl (int msqid, i struct msq_setbuf setbuf; struct kern_ipc_perm *ipcp; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (msqid < 0 || cmd < 0) return -EINVAL; @@ -559,6 +565,9 @@ asmlinkage long sys_msgsnd (int msqid, s long mtype; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (msgsz > msg_ctlmax || (long) msgsz < 0 || msqid < 0) return -EINVAL; if (get_user(mtype, &msgp->mtype)) @@ -671,6 +680,9 @@ asmlinkage long sys_msgrcv (int msqid, s struct msg_msg *msg; int mode; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (msqid < 0 || (long) msgsz < 0) return -EINVAL; mode = convert_mode(&msgtyp,msgflg); @@ -833,3 +845,9 @@ static int sysvipc_msg_proc_show(struct msq->q_ctime); } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/ipc/sem.c linux-2.6.16.12-cher1/ipc/sem.c --- linux-2.6.16.12/ipc/sem.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/ipc/sem.c 2006-05-02 08:14:11.000000000 +0400 @@ -212,6 +212,9 @@ asmlinkage long sys_semget (key_t key, i int id, err = -EINVAL; struct sem_array *sma; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (nsems < 0 || nsems > sc_semmsl) return -EINVAL; down(&sem_ids.sem); @@ -863,6 +866,9 @@ asmlinkage long sys_semctl (int semid, i int err = -EINVAL; int version; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (semid < 0) return -EINVAL; @@ -1061,6 +1067,9 @@ asmlinkage long sys_semtimedop(int semid struct sem_queue queue; unsigned long jiffies_left = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (nsops < 1 || semid < 0) return -EINVAL; if (nsops > sc_semopm) @@ -1351,3 +1360,9 @@ static int sysvipc_sem_proc_show(struct sma->sem_ctime); } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/ipc/shm.c linux-2.6.16.12-cher1/ipc/shm.c --- linux-2.6.16.12/ipc/shm.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/ipc/shm.c 2006-05-02 08:14:11.000000000 +0400 @@ -272,6 +272,9 @@ asmlinkage long sys_shmget (key_t key, s struct shmid_kernel *shp; int err, id = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + down(&shm_ids.sem); if (key == IPC_PRIVATE) { err = newseg(key, shmflg, size); @@ -430,6 +433,9 @@ asmlinkage long sys_shmctl (int shmid, i struct shmid_kernel *shp; int err, version; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (cmd < 0 || shmid < 0) { err = -EINVAL; goto out; @@ -797,6 +803,9 @@ asmlinkage long sys_shmat(int shmid, cha unsigned long ret; long err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + err = do_shmat(shmid, shmaddr, shmflg, &ret); if (err) return err; @@ -816,6 +825,9 @@ asmlinkage long sys_shmdt(char __user *s loff_t size = 0; int retval = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + down_write(&mm->mmap_sem); /* @@ -918,3 +930,9 @@ static int sysvipc_shm_proc_show(struct shp->shm_ctim); } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/kernel/acct.c linux-2.6.16.12-cher1/kernel/acct.c --- linux-2.6.16.12/kernel/acct.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/acct.c 2006-05-02 08:14:11.000000000 +0400 @@ -253,6 +253,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; @@ -605,3 +608,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.16.12/kernel/capability.c linux-2.6.16.12-cher1/kernel/capability.c --- linux-2.6.16.12/kernel/capability.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/capability.c 2006-05-02 08:14:11.000000000 +0400 @@ -49,6 +49,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; @@ -176,6 +179,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; @@ -233,3 +239,9 @@ out: return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/kernel/compat.c linux-2.6.16.12-cher1/kernel/compat.c --- linux-2.6.16.12/kernel/compat.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/compat.c 2006-05-02 08:14:11.000000000 +0400 @@ -267,6 +267,9 @@ asmlinkage long compat_sys_setrlimit(uns int ret; mm_segment_t old_fs = get_fs (); + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (resource >= RLIM_NLIMITS) return -EINVAL; @@ -386,6 +389,9 @@ asmlinkage long compat_sys_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options, struct compat_rusage __user *ru) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!ru) { return sys_wait4(pid, stat_addr, options, NULL); } else { @@ -420,6 +426,9 @@ asmlinkage long compat_sys_waitid(int wh long ret; mm_segment_t old_fs = get_fs(); + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + memset(&info, 0, sizeof(info)); set_fs(KERNEL_DS); @@ -462,6 +471,9 @@ asmlinkage long compat_sys_sched_setaffi cpumask_t new_mask; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = compat_get_user_cpu_mask(user_mask_ptr, len, &new_mask); if (retval) return retval; @@ -477,6 +489,9 @@ asmlinkage long compat_sys_sched_getaffi unsigned long *k; unsigned int min_length = sizeof(cpumask_t); + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (NR_CPUS <= BITS_PER_COMPAT_LONG) min_length = sizeof(compat_ulong_t); @@ -539,6 +554,9 @@ long compat_sys_timer_settime(timer_t ti mm_segment_t oldfs; struct itimerspec newts, oldts; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!new) return -EINVAL; if (get_compat_itimerspec(&newts, new)) @@ -561,6 +579,9 @@ long compat_sys_timer_gettime(timer_t ti mm_segment_t oldfs; struct itimerspec ts; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + oldfs = get_fs(); set_fs(KERNEL_DS); err = sys_timer_gettime(timer_id, @@ -578,6 +599,9 @@ long compat_sys_clock_settime(clockid_t mm_segment_t oldfs; struct timespec ts; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (get_compat_timespec(&ts, tp)) return -EFAULT; oldfs = get_fs(); @@ -595,6 +619,9 @@ long compat_sys_clock_gettime(clockid_t mm_segment_t oldfs; struct timespec ts; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + oldfs = get_fs(); set_fs(KERNEL_DS); err = sys_clock_gettime(which_clock, @@ -612,6 +639,9 @@ long compat_sys_clock_getres(clockid_t w mm_segment_t oldfs; struct timespec ts; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + oldfs = get_fs(); set_fs(KERNEL_DS); err = sys_clock_getres(which_clock, @@ -630,6 +660,9 @@ long compat_sys_clock_nanosleep(clockid_ mm_segment_t oldfs; struct timespec in, out; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (get_compat_timespec(&in, rqtp)) return -EFAULT; @@ -856,6 +889,9 @@ asmlinkage long compat_sys_stime(compat_ struct timespec tv; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (get_user(tv.tv_sec, tptr)) return -EFAULT; @@ -898,3 +934,9 @@ asmlinkage long compat_sys_rt_sigsuspend return -ERESTARTNOHAND; } #endif /* __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND */ + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/kernel/exec_domain.c linux-2.6.16.12-cher1/kernel/exec_domain.c --- linux-2.6.16.12/kernel/exec_domain.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/exec_domain.c 2006-05-02 08:14:11.000000000 +0400 @@ -195,6 +195,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) @@ -208,3 +211,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.16.12/kernel/exit.c linux-2.6.16.12-cher1/kernel/exit.c --- linux-2.6.16.12/kernel/exit.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/exit.c 2006-05-02 08:14:11.000000000 +0400 @@ -1129,7 +1129,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) @@ -1531,6 +1531,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))) @@ -1565,6 +1568,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; @@ -1587,3 +1593,9 @@ asmlinkage long sys_waitpid(pid_t pid, i } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruNp linux-2.6.16.12/kernel/fork.c linux-2.6.16.12-cher1/kernel/fork.c --- linux-2.6.16.12/kernel/fork.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/fork.c 2006-05-02 08:14:11.000000000 +0400 @@ -877,6 +877,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; } @@ -887,6 +891,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; @@ -1161,6 +1166,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])) { @@ -1292,8 +1298,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)) { @@ -1532,6 +1542,9 @@ asmlinkage long sys_unshare(unsigned lon struct files_struct *fd, *new_fd = NULL; struct sem_undo_list *new_ulist = NULL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + check_unshare_flags(&unshare_flags); if ((err = unshare_thread(unshare_flags))) @@ -1614,3 +1627,9 @@ bad_unshare_cleanup_thread: bad_unshare_out: return err; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruNp linux-2.6.16.12/kernel/kexec.c linux-2.6.16.12-cher1/kernel/kexec.c --- linux-2.6.16.12/kernel/kexec.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/kexec.c 2006-05-02 08:14:11.000000000 +0400 @@ -919,6 +919,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; @@ -1011,6 +1014,9 @@ asmlinkage long compat_sys_kexec_load(un struct kexec_segment out, __user *ksegments; unsigned long i, result; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* Don't allow clients that don't understand the native * architecture to do anything. */ @@ -1079,3 +1085,9 @@ static int __init crash_notes_memory_ini return 0; } module_init(crash_notes_memory_init) + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/kernel/module.c linux-2.6.16.12-cher1/kernel/module.c --- linux-2.6.16.12/kernel/module.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/module.c 2006-05-02 08:14:11.000000000 +0400 @@ -576,6 +576,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; @@ -1928,6 +1931,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; @@ -2267,3 +2273,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.16.12/kernel/posix-cpu-timers.c linux-2.6.16.12-cher1/kernel/posix-cpu-timers.c --- linux-2.6.16.12/kernel/posix-cpu-timers.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/posix-cpu-timers.c 2006-05-02 08:14:11.000000000 +0400 @@ -637,6 +637,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: @@ -1018,6 +1022,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])) @@ -1145,6 +1150,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) { @@ -1376,6 +1396,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; + } /* @@ -1572,3 +1596,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.16.12/kernel/posix-timers.c linux-2.6.16.12-cher1/kernel/posix-timers.c --- linux-2.6.16.12/kernel/posix-timers.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/posix-timers.c 2006-05-02 08:14:11.000000000 +0400 @@ -436,6 +436,9 @@ sys_timer_create(const clockid_t which_c 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; @@ -645,6 +648,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; @@ -675,6 +681,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; @@ -749,6 +758,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; @@ -800,6 +812,9 @@ sys_timer_delete(timer_t timer_id) struct k_itimer *timer; long flags; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retry_delete: timer = lock_timer(timer_id, &flags); if (!timer) @@ -892,6 +907,9 @@ asmlinkage long sys_clock_settime(const { 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))) @@ -906,6 +924,9 @@ sys_clock_gettime(const clockid_t which_ 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, @@ -923,6 +944,9 @@ sys_clock_getres(const clockid_t which_c struct timespec rtn_tp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (invalid_clockid(which_clock)) return -EINVAL; @@ -953,6 +977,9 @@ sys_clock_nanosleep(const clockid_t whic { struct timespec t; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (invalid_clockid(which_clock)) return -EINVAL; @@ -965,3 +992,9 @@ sys_clock_nanosleep(const clockid_t whic return CLOCK_DISPATCH(which_clock, nsleep, (which_clock, flags, &t, rmtp)); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/kernel/printk.c linux-2.6.16.12-cher1/kernel/printk.c --- linux-2.6.16.12/kernel/printk.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/printk.c 2006-05-02 08:14:11.000000000 +0400 @@ -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.16.12/kernel/ptrace.c linux-2.6.16.12-cher1/kernel/ptrace.c --- linux-2.6.16.12/kernel/ptrace.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/ptrace.c 2006-05-02 08:14:11.000000000 +0400 @@ -471,6 +471,9 @@ 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 */ @@ -480,6 +483,12 @@ asmlinkage long sys_ptrace(long request, goto out; } + if (request == PTRACE_MEMLIMIT) { + current->flags |= PF_MEMLIMITON; + ret = 0; + goto out; + } + child = ptrace_get_task_struct(pid); if (IS_ERR(child)) { ret = PTR_ERR(child); @@ -506,3 +515,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.16.12/kernel/sched.c linux-2.6.16.12-cher1/kernel/sched.c --- linux-2.6.16.12/kernel/sched.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/sched.c 2006-05-02 08:14:11.000000000 +0400 @@ -3521,6 +3521,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 @@ -3746,6 +3749,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; + /* negative values for policy are not valid */ if (policy < 0) return -EINVAL; @@ -3760,6 +3766,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); } @@ -3775,6 +3784,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); @@ -3803,6 +3815,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; @@ -3891,6 +3906,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; @@ -3950,6 +3968,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; @@ -4145,6 +4166,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: @@ -4169,6 +4193,12 @@ asmlinkage long sys_sched_get_priority_m { int ret = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (policy) { case SCHED_FIFO: case SCHED_RR: @@ -4199,6 +4229,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); @@ -6165,3 +6198,9 @@ void set_curr_task(int cpu, task_t *p) } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/kernel/signal.c linux-2.6.16.12-cher1/kernel/signal.c --- linux-2.6.16.12/kernel/signal.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/signal.c 2006-05-02 08:14:11.000000000 +0400 @@ -1245,6 +1245,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) { @@ -2395,6 +2407,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); } @@ -2408,6 +2423,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); } @@ -2425,6 +2443,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); } @@ -2713,6 +2736,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; @@ -2754,3 +2780,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.16.12/kernel/sys.c linux-2.6.16.12-cher1/kernel/sys.c --- linux-2.6.16.12/kernel/sys.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/sys.c 2006-05-02 08:14:11.000000000 +0400 @@ -267,6 +267,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; @@ -327,6 +330,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; @@ -485,6 +491,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; @@ -608,6 +617,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; @@ -656,6 +668,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; @@ -732,6 +747,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; @@ -796,6 +814,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; @@ -837,6 +858,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; @@ -878,6 +902,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); @@ -892,6 +919,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; @@ -930,6 +960,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); @@ -948,6 +981,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; @@ -979,6 +1015,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; @@ -1101,6 +1140,9 @@ asmlinkage long sys_setpgid(pid_t pid, p struct task_struct *group_leader = current->group_leader; int err = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!pid) pid = group_leader->pid; if (!pgid) @@ -1175,6 +1217,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); @@ -1207,6 +1252,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); @@ -1227,6 +1275,9 @@ asmlinkage long sys_setsid(void) struct pid *pid; int err = -EPERM; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + down(&tty_sem); write_lock_irq(&tasklist_lock); @@ -1428,6 +1479,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; @@ -1460,6 +1513,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) @@ -1529,6 +1585,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) @@ -1574,6 +1633,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) @@ -1632,6 +1694,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))) @@ -1677,6 +1742,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; } @@ -1774,6 +1851,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; } @@ -1783,6 +1862,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; @@ -1874,3 +1956,9 @@ asmlinkage long sys_prctl(int option, un } return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/kernel/sysctl.c linux-2.6.16.12-cher1/kernel/sysctl.c --- linux-2.6.16.12/kernel/sysctl.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/sysctl.c 2006-05-02 08:14:11.000000000 +0400 @@ -1152,6 +1152,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; @@ -2514,3 +2517,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.16.12/kernel/time.c linux-2.6.16.12-cher1/kernel/time.c --- linux-2.6.16.12/kernel/time.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/time.c 2006-05-02 08:14:11.000000000 +0400 @@ -83,6 +83,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; @@ -188,6 +191,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; @@ -407,6 +413,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 @@ -685,3 +694,9 @@ EXPORT_SYMBOL(get_jiffies_64); #endif EXPORT_SYMBOL(jiffies); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/kernel/timer.c linux-2.6.16.12-cher1/kernel/timer.c --- linux-2.6.16.12/kernel/timer.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/timer.c 2006-05-02 08:14:12.000000000 +0400 @@ -1177,6 +1177,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 { @@ -1569,3 +1572,9 @@ unsigned long msleep_interruptible(unsig } EXPORT_SYMBOL(msleep_interruptible); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/kernel/uid16.c linux-2.6.16.12-cher1/kernel/uid16.c --- linux-2.6.16.12/kernel/uid16.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/kernel/uid16.c 2006-05-02 08:14:12.000000000 +0400 @@ -164,6 +164,9 @@ asmlinkage long sys_getgroups16(int gids { int i = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (gidsetsize < 0) return -EINVAL; @@ -189,6 +192,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) @@ -228,3 +234,9 @@ asmlinkage long sys_getegid16(void) { return high2lowgid(current->egid); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/Makefile linux-2.6.16.12-cher1/Makefile --- linux-2.6.16.12/Makefile 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/Makefile 2006-05-02 08:14:21.000000000 +0400 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 16 -EXTRAVERSION = .12 +EXTRAVERSION = .12-cher1 NAME=Sliding Snow Leopard # *DOCUMENTATION* diff -ruNp linux-2.6.16.12/mm/fadvise.c linux-2.6.16.12-cher1/mm/fadvise.c --- linux-2.6.16.12/mm/fadvise.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/mm/fadvise.c 2006-05-02 08:14:12.000000000 +0400 @@ -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; @@ -118,3 +122,9 @@ asmlinkage long sys_fadvise64(int fd, lo } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/mm/filemap.c linux-2.6.16.12-cher1/mm/filemap.c --- linux-2.6.16.12/mm/filemap.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/mm/filemap.c 2006-05-02 08:14:12.000000000 +0400 @@ -1149,6 +1149,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) { @@ -2312,3 +2315,9 @@ generic_file_direct_IO(int rw, struct ki } return retval; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/mm/fremap.c linux-2.6.16.12-cher1/mm/fremap.c --- linux-2.6.16.12/mm/fremap.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/mm/fremap.c 2006-05-02 08:14:12.000000000 +0400 @@ -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.16.12/mm/madvise.c linux-2.6.16.12-cher1/mm/madvise.c --- linux-2.6.16.12/mm/madvise.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/mm/madvise.c 2006-05-02 08:14:12.000000000 +0400 @@ -261,6 +261,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) @@ -323,3 +326,9 @@ out: up_write(¤t->mm->mmap_sem); return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/mm/mempolicy.c linux-2.6.16.12-cher1/mm/mempolicy.c --- linux-2.6.16.12/mm/mempolicy.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/mm/mempolicy.c 2006-05-02 08:14:12.000000000 +0400 @@ -891,6 +891,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; @@ -904,6 +907,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); @@ -923,6 +929,9 @@ asmlinkage long sys_migrate_pages(pid_t nodemask_t task_nodes; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + err = get_nodes(&old, old_nodes, maxnode); if (err) return err; @@ -981,6 +990,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; @@ -1010,6 +1022,12 @@ 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; + + 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; @@ -1060,6 +1078,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; @@ -1909,3 +1930,8 @@ out: return 0; } +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/mm/mincore.c linux-2.6.16.12-cher1/mm/mincore.c --- linux-2.6.16.12/mm/mincore.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/mm/mincore.c 2006-05-02 08:14:12.000000000 +0400 @@ -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.16.12/mm/mlock.c linux-2.6.16.12-cher1/mm/mlock.c --- linux-2.6.16.12/mm/mlock.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/mm/mlock.c 2006-05-02 08:14:12.000000000 +0400 @@ -127,6 +127,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; @@ -151,6 +154,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; @@ -189,6 +195,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; @@ -214,6 +223,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); @@ -252,3 +264,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.16.12/mm/mmap.c linux-2.6.16.12-cher1/mm/mmap.c --- linux-2.6.16.12/mm/mmap.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/mm/mmap.c 2006-05-02 08:14:12.000000000 +0400 @@ -234,8 +234,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)) @@ -1458,8 +1463,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) { @@ -2057,7 +2067,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.16.12/mm/mprotect.c linux-2.6.16.12-cher1/mm/mprotect.c --- linux-2.6.16.12/mm/mprotect.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/mm/mprotect.c 2006-05-02 08:14:12.000000000 +0400 @@ -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.16.12/mm/mremap.c linux-2.6.16.12-cher1/mm/mremap.c --- linux-2.6.16.12/mm/mremap.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/mm/mremap.c 2006-05-02 08:14:12.000000000 +0400 @@ -408,8 +408,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.16.12/mm/swapfile.c linux-2.6.16.12-cher1/mm/swapfile.c --- linux-2.6.16.12/mm/swapfile.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/mm/swapfile.c 2006-05-02 08:14:12.000000000 +0400 @@ -1099,7 +1099,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; @@ -1338,6 +1340,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); @@ -1714,3 +1718,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.16.12/net/compat.c linux-2.6.16.12-cher1/net/compat.c --- linux-2.6.16.12/net/compat.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/net/compat.c 2006-05-02 08:14:12.000000000 +0400 @@ -535,6 +535,9 @@ asmlinkage long compat_sys_socketcall(in u32 a[6]; u32 a0, a1; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (call < SYS_SOCKET || call > SYS_RECVMSG) return -EINVAL; if (copy_from_user(a, args, nas[call])) @@ -602,3 +605,9 @@ asmlinkage long compat_sys_socketcall(in } return ret; } + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruNp linux-2.6.16.12/net/socket.c linux-2.6.16.12-cher1/net/socket.c --- linux-2.6.16.12/net/socket.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/net/socket.c 2006-05-02 08:14:12.000000000 +0400 @@ -1194,6 +1194,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; @@ -1220,6 +1223,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. @@ -1291,6 +1297,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) { @@ -1320,6 +1329,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; @@ -1355,6 +1367,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; @@ -1425,6 +1440,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; @@ -1455,6 +1473,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; @@ -1485,6 +1506,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); @@ -1516,6 +1540,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; @@ -1570,6 +1597,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; @@ -1616,6 +1646,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; @@ -1646,6 +1679,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, @@ -1674,6 +1710,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); @@ -1713,6 +1752,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)) @@ -1814,6 +1856,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; @@ -1916,6 +1961,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; @@ -2105,3 +2153,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.16.12/security/keys/keyctl.c linux-2.6.16.12-cher1/security/keys/keyctl.c --- linux-2.6.16.12/security/keys/keyctl.c 2006-05-01 23:14:26.000000000 +0400 +++ linux-2.6.16.12-cher1/security/keys/keyctl.c 2006-05-02 08:14:12.000000000 +0400 @@ -40,6 +40,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; @@ -138,6 +141,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) @@ -1076,6 +1082,9 @@ error: 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, @@ -1154,3 +1163,9 @@ asmlinkage long sys_keyctl(int option, u } } /* end sys_keyctl() */ + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */