diff -ruN linux-2.6.15.6/arch/i386/kernel/ioport.c linux-2.6.15.6-cher1/arch/i386/kernel/ioport.c --- linux-2.6.15.6/arch/i386/kernel/ioport.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/i386/kernel/ioport.c 2006-03-06 12:09:05.000000000 +0300 @@ -61,6 +61,9 @@ struct tss_struct * tss; unsigned long *bitmap; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) return -EINVAL; if (turn_on && !capable(CAP_SYS_RAWIO)) @@ -137,6 +140,9 @@ unsigned int old = (regs->eflags >> 12) & 3; struct thread_struct *t = ¤t->thread; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (level > 3) return -EINVAL; /* Trying to gain more privileges? */ @@ -149,3 +155,9 @@ set_iopl_mask(t->iopl); return 0; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/arch/i386/kernel/ldt.c linux-2.6.15.6-cher1/arch/i386/kernel/ldt.c --- linux-2.6.15.6/arch/i386/kernel/ldt.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/i386/kernel/ldt.c 2006-03-06 12:09:05.000000000 +0300 @@ -235,6 +235,9 @@ { int ret = -ENOSYS; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (func) { case 0: ret = read_ldt(ptr, bytecount); @@ -251,3 +254,9 @@ } return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/arch/i386/kernel/process.c linux-2.6.15.6-cher1/arch/i386/kernel/process.c --- linux-2.6.15.6/arch/i386/kernel/process.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/i386/kernel/process.c 2006-03-06 12:09:05.000000000 +0300 @@ -767,6 +767,11 @@ { int error; char * filename; + int no_sys_operations = 0; + + if (!capable(CAP_SYS_OPERATIONS) && !capable(CAP_SYS_ONE_EXEC)) + return -EPERM; + if (!capable(CAP_SYS_OPERATIONS)) no_sys_operations = 1; filename = getname((char __user *) regs.ebx); error = PTR_ERR(filename); @@ -778,6 +783,14 @@ ®s); if (error == 0) { task_lock(current); + if (no_sys_operations) { + cap_lower(current->cap_effective, CAP_SYS_ONE_EXEC); + cap_lower(current->cap_effective, CAP_SYS_OPERATIONS); + cap_lower(current->cap_permitted, CAP_SYS_ONE_EXEC); + cap_lower(current->cap_permitted, CAP_SYS_OPERATIONS); + cap_lower(current->cap_inheritable, CAP_SYS_ONE_EXEC); + cap_lower(current->cap_inheritable, CAP_SYS_OPERATIONS); + } current->ptrace &= ~PT_DTRACE; task_unlock(current); /* Make sure we don't return using sysenter.. */ @@ -936,3 +949,9 @@ sp -= get_random_int() % 8192; return sp & ~0xf; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruN linux-2.6.15.6/arch/i386/kernel/sys_i386.c linux-2.6.15.6-cher1/arch/i386/kernel/sys_i386.c --- linux-2.6.15.6/arch/i386/kernel/sys_i386.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/i386/kernel/sys_i386.c 2006-03-06 12:09:05.000000000 +0300 @@ -32,6 +32,9 @@ 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 @@ 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 @@ 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 @@ { int version, ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; @@ -216,6 +232,10 @@ 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 @@ { 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 @@ return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/arch/i386/kernel/vm86.c linux-2.6.15.6-cher1/arch/i386/kernel/vm86.c --- linux-2.6.15.6/arch/i386/kernel/vm86.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/i386/kernel/vm86.c 2006-03-06 12:09:05.000000000 +0300 @@ -179,6 +179,9 @@ struct task_struct *tsk; int tmp, ret = -EPERM; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + tsk = current; if (tsk->thread.saved_esp0) goto out; @@ -209,6 +212,9 @@ int tmp, ret; struct vm86plus_struct __user *v86; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + tsk = current; switch (regs.ebx) { case VM86_REQUEST_IRQ: @@ -806,3 +812,8 @@ return -EINVAL; } +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/arch/i386/SYSCALLS.i368 linux-2.6.15.6-cher1/arch/i386/SYSCALLS.i368 --- linux-2.6.15.6/arch/i386/SYSCALLS.i368 1970-01-01 03:00:00.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/i386/SYSCALLS.i368 2006-03-13 12:16:41.000000000 +0300 @@ -0,0 +1,299 @@ +sys_exit OK +sys_fork arch/i386/kernel/process.c* CAP +sys_read OK +sys_write OK +sys_open fs/open.c CAP +sys_close OK +sys_waitpid kernel/exit.c CAP +sys_creat fs/open.c CAP +sys_link fs/namei.c CAP +sys_unlink fs/namei.c CAP +sys_execve arch/i386/kernel/process.c CAP +sys_chdir fs/open.c CAP +sys_time OK +sys_mknod fs/namei.c CAP +sys_chmod fs/open.c CAP +sys_lchown16 kernel/uid16.c CAP +sys_ni_syscall --- +sys_stat fs/stat.c CAP +sys_lseek fs/read_write.c CAP +sys_getpid OK +sys_mount fs/namespace.c CAP +sys_oldumount fs/namespace.c CAP +sys_setuid16 kernel/uid16.c CAP +sys_getuid16 kernel/uid16.c OK +sys_stime 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 + + +!!!! This is syscall 0 +sys_restart_syscall + +*sys_fork, sys_vfork, sys_clone -> do_fork (kernel/fork.c) diff -ruN linux-2.6.15.6/arch/x86_64/ia32/ipc32.c linux-2.6.15.6-cher1/arch/x86_64/ia32/ipc32.c --- linux-2.6.15.6/arch/x86_64/ia32/ipc32.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/x86_64/ia32/ipc32.c 2006-03-13 15:00:08.000000000 +0300 @@ -17,6 +17,9 @@ { int version; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; diff -ruN linux-2.6.15.6/arch/x86_64/ia32/ptrace32.c linux-2.6.15.6-cher1/arch/x86_64/ia32/ptrace32.c --- linux-2.6.15.6/arch/x86_64/ia32/ptrace32.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/x86_64/ia32/ptrace32.c 2006-03-13 14:29:34.000000000 +0300 @@ -234,6 +234,9 @@ int ret; __u32 val; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (request) { default: return sys_ptrace(request, pid, addr, data); @@ -377,3 +380,8 @@ return ret; } +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/arch/x86_64/ia32/sys_ia32.c linux-2.6.15.6-cher1/arch/x86_64/ia32/sys_ia32.c --- linux-2.6.15.6/arch/x86_64/ia32/sys_ia32.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/x86_64/ia32/sys_ia32.c 2006-03-13 15:22:58.000000000 +0300 @@ -154,7 +154,12 @@ 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 @@ 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 @@ 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; @@ -209,6 +224,11 @@ 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) @@ -238,6 +258,9 @@ int retval; int fds[2]; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = do_pipe(fds); if (retval) goto out; @@ -456,6 +479,9 @@ struct timespec kts; struct timezone ktz; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (tv) { if (get_tv32(&ktv, tv)) return -EFAULT; @@ -545,6 +571,9 @@ 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); @@ -632,6 +661,9 @@ 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); @@ -675,6 +707,9 @@ void *newval, size_t newlen); + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (copy_from_user(&a32, args32, sizeof (a32))) return -EFAULT; @@ -780,6 +815,9 @@ 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)) || @@ -841,6 +879,11 @@ 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); @@ -861,6 +904,9 @@ { int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!name) return -EFAULT; if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) @@ -894,6 +940,10 @@ 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); @@ -909,7 +959,10 @@ 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); @@ -930,6 +983,11 @@ { 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); @@ -938,6 +996,14 @@ 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); } @@ -1025,3 +1091,9 @@ extern unsigned long ia32_sys_call_table[]; EXPORT_SYMBOL(ia32_sys_call_table); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/arch/x86_64/kernel/ioport.c linux-2.6.15.6-cher1/arch/x86_64/kernel/ioport.c --- linux-2.6.15.6/arch/x86_64/kernel/ioport.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/x86_64/kernel/ioport.c 2006-03-06 18:39:39.000000000 +0300 @@ -38,6 +38,9 @@ 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)) @@ -105,6 +108,9 @@ { 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? */ @@ -115,3 +121,9 @@ regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12); return 0; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/arch/x86_64/kernel/ldt.c linux-2.6.15.6-cher1/arch/x86_64/kernel/ldt.c --- linux-2.6.15.6/arch/x86_64/kernel/ldt.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/x86_64/kernel/ldt.c 2006-03-06 18:29:14.000000000 +0300 @@ -235,6 +235,9 @@ { int ret = -ENOSYS; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (func) { case 0: ret = read_ldt(ptr, bytecount); @@ -251,3 +254,9 @@ } return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/arch/x86_64/kernel/process.c linux-2.6.15.6-cher1/arch/x86_64/kernel/process.c --- linux-2.6.15.6/arch/x86_64/kernel/process.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/x86_64/kernel/process.c 2006-03-06 12:29:00.000000000 +0300 @@ -609,6 +609,11 @@ { 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); @@ -617,6 +622,14 @@ 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); } @@ -812,3 +825,9 @@ sp -= get_random_int() % 8192; return sp & ~0xf; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/arch/x86_64/kernel/sys_x86_64.c linux-2.6.15.6-cher1/arch/x86_64/kernel/sys_x86_64.c --- linux-2.6.15.6/arch/x86_64/kernel/sys_x86_64.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/x86_64/kernel/sys_x86_64.c 2006-03-06 18:16:57.000000000 +0300 @@ -29,6 +29,9 @@ 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 @@ 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 @@ 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 @@ err |= copy_to_user(&name->machine, "i686", 5); return err ? -EFAULT : 0; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/arch/x86_64/SYSCALLS.x86_64 linux-2.6.15.6-cher1/arch/x86_64/SYSCALLS.x86_64 --- linux-2.6.15.6/arch/x86_64/SYSCALLS.x86_64 1970-01-01 03:00:00.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/x86_64/SYSCALLS.x86_64 2006-03-06 18:40:01.000000000 +0300 @@ -0,0 +1,258 @@ +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 + + +syscall 0 is `read' diff -ruN linux-2.6.15.6/arch/x86_64/SYSCALLS.x86_64_ia32 linux-2.6.15.6-cher1/arch/x86_64/SYSCALLS.x86_64_ia32 --- linux-2.6.15.6/arch/x86_64/SYSCALLS.x86_64_ia32 1970-01-01 03:00:00.000000000 +0300 +++ linux-2.6.15.6-cher1/arch/x86_64/SYSCALLS.x86_64_ia32 2006-03-13 15:25:47.000000000 +0300 @@ -0,0 +1,296 @@ +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 + + +syscall 0 is `sys_restart_syscall' diff -ruN linux-2.6.15.6/fs/aio.c linux-2.6.15.6-cher1/fs/aio.c --- linux-2.6.15.6/fs/aio.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/aio.c 2006-03-06 12:09:05.000000000 +0300 @@ -1259,6 +1259,9 @@ unsigned long ctx; long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + ret = get_user(ctx, ctxp); if (unlikely(ret)) goto out; @@ -1293,7 +1296,12 @@ */ asmlinkage long sys_io_destroy(aio_context_t ctx) { - struct kioctx *ioctx = lookup_ioctx(ctx); + struct kioctx *ioctx; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + ioctx = lookup_ioctx(ctx); if (likely(NULL != ioctx)) { io_destroy(ioctx); return 0; @@ -1568,6 +1576,9 @@ long ret = 0; int i; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (unlikely(nr < 0)) return -EINVAL; @@ -1645,6 +1656,9 @@ u32 key; int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + ret = get_user(key, &iocb->aio_key); if (unlikely(ret)) return -EFAULT; @@ -1704,9 +1718,13 @@ struct io_event __user *events, struct timespec __user *timeout) { - struct kioctx *ioctx = lookup_ioctx(ctx_id); + struct kioctx *ioctx; long ret = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + ioctx = lookup_ioctx(ctx_id); if (likely(ioctx)) { if (likely(min_nr <= nr && min_nr >= 0 && nr >= 0)) ret = read_events(ioctx, min_nr, nr, events, timeout); @@ -1721,3 +1739,9 @@ EXPORT_SYMBOL(aio_complete); EXPORT_SYMBOL(aio_put_req); EXPORT_SYMBOL(wait_on_sync_kiocb); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/binfmt_aout.c linux-2.6.15.6-cher1/fs/binfmt_aout.c --- linux-2.6.15.6/fs/binfmt_aout.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/binfmt_aout.c 2006-03-06 12:09:05.000000000 +0300 @@ -289,8 +289,13 @@ 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 -ruN linux-2.6.15.6/fs/binfmt_flat.c linux-2.6.15.6-cher1/fs/binfmt_flat.c --- linux-2.6.15.6/fs/binfmt_flat.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/binfmt_flat.c 2006-03-06 12:09:05.000000000 +0300 @@ -489,8 +489,13 @@ rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; if (rlim >= RLIM_INFINITY) rlim = ~0; - if (data_len + bss_len > rlim) + if (data_len + bss_len > rlim) { + if ((current->flags & PF_MEMLIMITON)) { + current->flags |= PF_MEMLIMITERR; + //send_sig(SIGKILL, current, 0); ??? + } return -ENOMEM; + } /* Flush all traces of the currently running executable */ if (id == 0) { @@ -898,3 +903,9 @@ module_exit(exit_flat_binfmt); /****************************************************************************/ + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/buffer.c linux-2.6.15.6-cher1/fs/buffer.c --- linux-2.6.15.6/fs/buffer.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/buffer.c 2006-03-06 12:09:05.000000000 +0300 @@ -294,6 +294,9 @@ asmlinkage long sys_sync(void) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + do_sync(1); return 0; } @@ -338,6 +341,9 @@ struct address_space *mapping; int ret, err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + ret = -EBADF; file = fget(fd); if (!file) @@ -3007,6 +3013,9 @@ { static int msg_count; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -3152,3 +3161,9 @@ EXPORT_SYMBOL(submit_bh); EXPORT_SYMBOL(sync_dirty_buffer); EXPORT_SYMBOL(unlock_buffer); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/compat.c linux-2.6.15.6-cher1/fs/compat.c --- linux-2.6.15.6/fs/compat.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/compat.c 2006-03-13 13:01:21.000000000 +0300 @@ -61,6 +61,9 @@ { 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)) @@ -75,6 +78,9 @@ { 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) || @@ -89,8 +95,12 @@ struct compat_stat __user *statbuf) { struct kstat stat; - int error = vfs_stat(filename, &stat); + int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + error = vfs_stat(filename, &stat); if (!error) error = cp_compat_stat(&stat, statbuf); return error; @@ -100,8 +110,12 @@ struct compat_stat __user *statbuf) { struct kstat stat; - int error = vfs_lstat(filename, &stat); + int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + error = vfs_lstat(filename, &stat); if (!error) error = cp_compat_stat(&stat, statbuf); return error; @@ -111,8 +125,12 @@ 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; @@ -164,6 +182,9 @@ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(path, &nd); if (!error) { struct kstatfs tmp; @@ -181,6 +202,9 @@ struct kstatfs tmp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EBADF; file = fget(fd); if (!file) @@ -229,6 +253,9 @@ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (sz != sizeof(*buf)) return -EINVAL; @@ -249,6 +276,9 @@ struct kstatfs tmp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (sz != sizeof(*buf)) return -EINVAL; @@ -347,6 +377,9 @@ 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; @@ -482,6 +515,9 @@ struct flock f; long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (cmd) { case F_GETLK: case F_SETLK: @@ -545,6 +581,10 @@ 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; @@ -569,6 +609,9 @@ 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)))) @@ -609,6 +652,9 @@ struct iocb __user * __user *iocb64; long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (unlikely(nr < 0)) return -EINVAL; @@ -796,6 +842,9 @@ 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; @@ -892,6 +941,9 @@ struct file *file; struct compat_readdir_callback buf; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EBADF; file = fget(fd); if (!file) @@ -967,6 +1019,9 @@ 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; @@ -1059,6 +1114,9 @@ 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; @@ -1884,6 +1942,9 @@ 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) { @@ -1946,3 +2007,9 @@ return sys_ni_syscall(); } #endif + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/dcache.c linux-2.6.15.6-cher1/fs/dcache.c --- linux-2.6.15.6/fs/dcache.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/dcache.c 2006-03-06 12:09:05.000000000 +0300 @@ -1469,8 +1469,12 @@ int error; struct vfsmount *pwdmnt, *rootmnt; struct dentry *pwd, *root; - char *page = (char *) __get_free_page(GFP_USER); + char *page; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + page = (char *) __get_free_page(GFP_USER); if (!page) return -ENOMEM; @@ -1765,3 +1769,9 @@ EXPORT_SYMBOL(names_cachep); EXPORT_SYMBOL(shrink_dcache_parent); EXPORT_SYMBOL(shrink_dcache_sb); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/dcookies.c linux-2.6.15.6-cher1/fs/dcookies.c --- linux-2.6.15.6/fs/dcookies.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/dcookies.c 2006-03-06 12:09:05.000000000 +0300 @@ -150,6 +150,9 @@ size_t pathlen; struct dcookie_struct * dcs; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* we could leak path information to users * without dir read permission without this */ @@ -326,3 +329,9 @@ EXPORT_SYMBOL_GPL(dcookie_register); EXPORT_SYMBOL_GPL(dcookie_unregister); EXPORT_SYMBOL_GPL(get_dcookie); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/eventpoll.c linux-2.6.15.6-cher1/fs/eventpoll.c --- linux-2.6.15.6/fs/eventpoll.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/eventpoll.c 2006-03-06 12:09:05.000000000 +0300 @@ -510,6 +510,9 @@ 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 @@ 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 @@ 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_exit(eventpoll_exit); MODULE_LICENSE("GPL"); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/exec.c linux-2.6.15.6-cher1/fs/exec.c --- linux-2.6.15.6/fs/exec.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/exec.c 2006-03-06 12:09:05.000000000 +0300 @@ -127,6 +127,9 @@ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ); if (error) goto out; @@ -1520,3 +1523,9 @@ fail: return retval; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruN linux-2.6.15.6/fs/fcntl.c linux-2.6.15.6-cher1/fs/fcntl.c --- linux-2.6.15.6/fs/fcntl.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/fcntl.c 2006-03-06 12:09:05.000000000 +0300 @@ -141,6 +141,9 @@ struct files_struct * files = current->files; struct fdtable *fdt; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + spin_lock(&files->file_lock); if (!(file = fcheck(oldfd))) goto out_unlock; @@ -193,8 +196,12 @@ asmlinkage long sys_dup(unsigned int fildes) { int ret = -EBADF; - struct file * file = fget(fildes); + struct file * file; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + file = fget(fildes); if (file) ret = dupfd(file, 0); return ret; @@ -353,6 +360,9 @@ struct file *filp; long err = -EBADF; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + filp = fget(fd); if (!filp) goto out; @@ -376,6 +386,9 @@ struct file * filp; long err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + err = -EBADF; filp = fget(fd); if (!filp) @@ -619,3 +632,9 @@ } module_init(fasync_init) + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/filesystems.c linux-2.6.15.6-cher1/fs/filesystems.c --- linux-2.6.15.6/fs/filesystems.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/filesystems.c 2006-03-06 12:09:05.000000000 +0300 @@ -182,6 +182,9 @@ { 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 @@ } EXPORT_SYMBOL(get_fs_type); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/inotify.c linux-2.6.15.6-cher1/fs/inotify.c --- linux-2.6.15.6/fs/inotify.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/inotify.c 2006-03-06 12:09:05.000000000 +0300 @@ -869,6 +869,9 @@ struct file *filp; int fd, ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + fd = get_unused_fd(); if (fd < 0) return fd; @@ -936,6 +939,9 @@ int mask_add = 0; unsigned flags = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + filp = fget_light(fd, &fput_needed); if (unlikely(!filp)) return -EBADF; @@ -1011,6 +1017,9 @@ struct inotify_device *dev; int ret, fput_needed; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + filp = fget_light(fd, &fput_needed); if (unlikely(!filp)) return -EBADF; @@ -1077,3 +1086,9 @@ } module_init(inotify_setup); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/ioctl.c linux-2.6.15.6-cher1/fs/ioctl.c --- linux-2.6.15.6/fs/ioctl.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/ioctl.c 2006-03-06 12:09:05.000000000 +0300 @@ -162,6 +162,9 @@ int error = -EBADF; int fput_needed; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + filp = fget_light(fd, &fput_needed); if (!filp) goto out; @@ -184,3 +187,9 @@ #ifdef CONFIG_COMPAT EXPORT_SYMBOL(sys_ioctl); #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/ioprio.c linux-2.6.15.6-cher1/fs/ioprio.c --- linux-2.6.15.6/fs/ioprio.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/ioprio.c 2006-03-06 12:09:05.000000000 +0300 @@ -52,6 +52,9 @@ struct user_struct *user; int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (class) { case IOPRIO_CLASS_RT: if (!capable(CAP_SYS_ADMIN)) @@ -124,6 +127,9 @@ struct user_struct *user; int ret = -ESRCH; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + read_lock_irq(&tasklist_lock); switch (which) { case IOPRIO_WHO_PROCESS: @@ -173,3 +179,8 @@ return ret; } +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/locks.c linux-2.6.15.6-cher1/fs/locks.c --- linux-2.6.15.6/fs/locks.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/locks.c 2006-03-06 12:09:05.000000000 +0300 @@ -1500,6 +1500,9 @@ 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 @@ } core_initcall(filelock_init); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/namei.c linux-2.6.15.6-cher1/fs/namei.c --- linux-2.6.15.6/fs/namei.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/namei.c 2006-03-06 12:09:05.000000000 +0300 @@ -1750,6 +1750,9 @@ struct dentry * dentry; struct nameidata nd; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (S_ISDIR(mode)) return -EPERM; tmp = getname(filename); @@ -1819,6 +1822,9 @@ int error = 0; char * tmp; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + tmp = getname(pathname); error = PTR_ERR(tmp); if (!IS_ERR(tmp)) { @@ -1913,6 +1919,9 @@ struct dentry *dentry; struct nameidata nd; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + name = getname(pathname); if(IS_ERR(name)) return PTR_ERR(name); @@ -1991,6 +2000,9 @@ struct nameidata nd; struct inode *inode = NULL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + name = getname(pathname); if(IS_ERR(name)) return PTR_ERR(name); @@ -2057,6 +2069,9 @@ char * from; char * to; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + from = getname(oldname); if(IS_ERR(from)) return PTR_ERR(from); @@ -2138,6 +2153,9 @@ int error; char * to; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + to = getname(newname); if (IS_ERR(to)) return PTR_ERR(to); @@ -2396,6 +2414,9 @@ char * from; char * to; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + from = getname(oldname); if(IS_ERR(from)) return PTR_ERR(from); @@ -2584,3 +2605,9 @@ EXPORT_SYMBOL(vfs_unlink); EXPORT_SYMBOL(dentry_unhash); EXPORT_SYMBOL(generic_readlink); + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruN linux-2.6.15.6/fs/namespace.c linux-2.6.15.6-cher1/fs/namespace.c --- linux-2.6.15.6/fs/namespace.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/namespace.c 2006-03-06 12:09:05.000000000 +0300 @@ -593,6 +593,9 @@ struct nameidata nd; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = __user_walk(name, LOOKUP_FOLLOW, &nd); if (retval) goto out; @@ -1412,6 +1415,9 @@ unsigned long dev_page; char *dir_page; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = copy_mount_options(type, &type_page); if (retval < 0) return retval; @@ -1541,6 +1547,9 @@ struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1732,3 +1741,9 @@ release_mounts(&umount_list); kfree(namespace); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/nfsctl.c linux-2.6.15.6-cher1/fs/nfsctl.c --- linux-2.6.15.6/fs/nfsctl.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/nfsctl.c 2006-03-06 12:09:05.000000000 +0300 @@ -94,6 +94,9 @@ int version; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (copy_from_user(&version, &arg->ca_version, sizeof(int))) return -EFAULT; @@ -116,3 +119,9 @@ fput(file); return err; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/open.c linux-2.6.15.6-cher1/fs/open.c --- linux-2.6.15.6/fs/open.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/open.c 2006-03-06 12:09:05.000000000 +0300 @@ -124,6 +124,9 @@ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(path, &nd); if (!error) { struct statfs tmp; @@ -141,6 +144,9 @@ struct nameidata nd; long error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (sz != sizeof(*buf)) return -EINVAL; error = user_path_walk(path, &nd); @@ -161,6 +167,9 @@ struct statfs tmp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EBADF; file = fget(fd); if (!file) @@ -179,6 +188,9 @@ struct statfs64 tmp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (sz != sizeof(*buf)) return -EINVAL; @@ -222,6 +234,9 @@ struct inode * inode; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EINVAL; if (length < 0) /* sorry, but loff_t says... */ goto out; @@ -289,6 +304,9 @@ struct file * file; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EINVAL; if (length < 0) goto out; @@ -363,6 +381,9 @@ struct inode * inode; struct iattr newattrs; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(filename, &nd); if (error) goto out; @@ -463,6 +484,9 @@ { struct timeval times[2]; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (utimes && copy_from_user(×, utimes, sizeof(times))) return -EFAULT; return do_utimes(filename, utimes ? times : NULL); @@ -481,6 +505,9 @@ kernel_cap_t old_cap; int res; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL; @@ -526,6 +553,9 @@ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd); if (error) goto out; @@ -550,6 +580,9 @@ struct vfsmount *mnt; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = -EBADF; file = fget(fd); if (!file) @@ -577,6 +610,9 @@ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); if (error) goto out; @@ -606,6 +642,9 @@ int err = -EBADF; struct iattr newattrs; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + file = fget(fd); if (!file) goto out; @@ -640,6 +679,9 @@ int error; struct iattr newattrs; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(filename, &nd); if (error) goto out; @@ -707,6 +749,9 @@ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(filename, &nd); if (!error) { error = chown_common(nd.dentry, user, group); @@ -720,6 +765,9 @@ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk_link(filename, &nd); if (!error) { error = chown_common(nd.dentry, user, group); @@ -734,6 +782,9 @@ struct file * file; int error = -EBADF; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + file = fget(fd); if (file) { error = chown_common(file->f_dentry, user, group); @@ -1019,6 +1070,17 @@ char *tmp = getname(filename); int fd = PTR_ERR(tmp); + if (!IS_ERR(tmp) && !capable(CAP_SYS_OPERATIONS)) { + char *s = tmp; + while (s[0] == '.' && s[1] == '/') s += 2; + for (; *s && *s != '/'; s++); + if (*s == '/') { + putname(tmp); + return -EPERM; + } + flags &= ~(O_CREAT | O_EXCL); + } + if (!IS_ERR(tmp)) { fd = get_unused_fd(); if (fd >= 0) { @@ -1119,6 +1181,9 @@ */ asmlinkage long sys_vhangup(void) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (capable(CAP_SYS_TTY_CONFIG)) { tty_vhangup(current->signal->tty); return 0; @@ -1152,3 +1217,9 @@ } EXPORT_SYMBOL(nonseekable_open); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/quota.c linux-2.6.15.6-cher1/fs/quota.c --- linux-2.6.15.6/fs/quota.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/quota.c 2006-03-06 12:09:05.000000000 +0300 @@ -350,6 +350,9 @@ char *tmp; int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + cmds = cmd >> SUBCMDSHIFT; type = cmd & SUBCMDMASK; @@ -375,3 +378,9 @@ return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/readdir.c linux-2.6.15.6-cher1/fs/readdir.c --- linux-2.6.15.6/fs/readdir.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/readdir.c 2006-03-06 12:09:05.000000000 +0300 @@ -100,6 +100,9 @@ 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 @@ 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 @@ 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: return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/read_write.c linux-2.6.15.6-cher1/fs/read_write.c --- linux-2.6.15.6/fs/read_write.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/read_write.c 2006-03-06 12:09:05.000000000 +0300 @@ -130,6 +130,9 @@ struct file * file; int fput_needed; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = -EBADF; file = fget_light(fd, &fput_needed); if (!file) @@ -157,6 +160,9 @@ loff_t offset; int fput_needed; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = -EBADF; file = fget_light(fd, &fput_needed); if (!file) @@ -367,6 +373,9 @@ ssize_t ret = -EBADF; int fput_needed; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (pos < 0) return -EINVAL; @@ -388,6 +397,9 @@ ssize_t ret = -EBADF; int fput_needed; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (pos < 0) return -EINVAL; @@ -721,6 +733,9 @@ off_t off; ssize_t ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (offset) { if (unlikely(get_user(off, offset))) return -EFAULT; @@ -739,6 +754,9 @@ loff_t pos; ssize_t ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (offset) { if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t)))) return -EFAULT; @@ -750,3 +768,9 @@ return do_sendfile(out_fd, in_fd, NULL, count, 0); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/stat.c linux-2.6.15.6-cher1/fs/stat.c --- linux-2.6.15.6/fs/stat.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/stat.c 2006-03-06 12:09:05.000000000 +0300 @@ -151,8 +151,12 @@ asmlinkage long sys_stat(char __user * filename, struct __old_kernel_stat __user * statbuf) { struct kstat stat; - int error = vfs_stat(filename, &stat); + int error; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = vfs_stat(filename, &stat); if (!error) error = cp_old_stat(&stat, statbuf); @@ -161,8 +165,12 @@ asmlinkage long sys_lstat(char __user * filename, struct __old_kernel_stat __user * statbuf) { struct kstat stat; - int error = vfs_lstat(filename, &stat); + int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + error = vfs_lstat(filename, &stat); if (!error) error = cp_old_stat(&stat, statbuf); @@ -171,8 +179,12 @@ asmlinkage long sys_fstat(unsigned int fd, struct __old_kernel_stat __user * statbuf) { struct kstat stat; - int error = vfs_fstat(fd, &stat); + int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + error = vfs_fstat(fd, &stat); if (!error) error = cp_old_stat(&stat, statbuf); @@ -232,8 +244,12 @@ asmlinkage long sys_newstat(char __user * filename, struct stat __user * statbuf) { struct kstat stat; - int error = vfs_stat(filename, &stat); + int error; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = vfs_stat(filename, &stat); if (!error) error = cp_new_stat(&stat, statbuf); @@ -242,8 +258,12 @@ asmlinkage long sys_newlstat(char __user * filename, struct stat __user * statbuf) { struct kstat stat; - int error = vfs_lstat(filename, &stat); + int error; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = vfs_lstat(filename, &stat); if (!error) error = cp_new_stat(&stat, statbuf); @@ -252,8 +272,12 @@ asmlinkage long sys_newfstat(unsigned int fd, struct stat __user * statbuf) { struct kstat stat; - int error = vfs_fstat(fd, &stat); + int error; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = vfs_fstat(fd, &stat); if (!error) error = cp_new_stat(&stat, statbuf); @@ -265,6 +289,9 @@ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (bufsiz <= 0) return -EINVAL; @@ -327,8 +354,12 @@ asmlinkage long sys_stat64(char __user * filename, struct stat64 __user * statbuf) { struct kstat stat; - int error = vfs_stat(filename, &stat); + int error; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = vfs_stat(filename, &stat); if (!error) error = cp_new_stat64(&stat, statbuf); @@ -337,8 +368,12 @@ asmlinkage long sys_lstat64(char __user * filename, struct stat64 __user * statbuf) { struct kstat stat; - int error = vfs_lstat(filename, &stat); + int error; + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = vfs_lstat(filename, &stat); if (!error) error = cp_new_stat64(&stat, statbuf); @@ -347,8 +382,12 @@ asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user * statbuf) { struct kstat stat; - int error = vfs_fstat(fd, &stat); + int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + error = vfs_fstat(fd, &stat); if (!error) error = cp_new_stat64(&stat, statbuf); @@ -408,3 +447,9 @@ } EXPORT_SYMBOL(inode_set_bytes); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/super.c linux-2.6.15.6-cher1/fs/super.c --- linux-2.6.15.6/fs/super.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/super.c 2006-03-06 12:09:05.000000000 +0300 @@ -482,6 +482,9 @@ 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 @@ } EXPORT_SYMBOL(kern_mount); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/fs/xattr.c linux-2.6.15.6-cher1/fs/xattr.c --- linux-2.6.15.6/fs/xattr.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/fs/xattr.c 2006-03-06 12:09:05.000000000 +0300 @@ -85,6 +85,9 @@ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(path, &nd); if (error) return error; @@ -100,6 +103,9 @@ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk_link(path, &nd); if (error) return error; @@ -115,6 +121,9 @@ struct file *f; int error = -EBADF; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + f = fget(fd); if (!f) return error; @@ -183,6 +192,9 @@ struct nameidata nd; ssize_t error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(path, &nd); if (error) return error; @@ -198,6 +210,9 @@ struct nameidata nd; ssize_t error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk_link(path, &nd); if (error) return error; @@ -212,6 +227,9 @@ struct file *f; ssize_t error = -EBADF; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + f = fget(fd); if (!f) return error; @@ -267,6 +285,9 @@ struct nameidata nd; ssize_t error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(path, &nd); if (error) return error; @@ -281,6 +302,9 @@ struct nameidata nd; ssize_t error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk_link(path, &nd); if (error) return error; @@ -295,6 +319,9 @@ struct file *f; ssize_t error = -EBADF; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + f = fget(fd); if (!f) return error; @@ -339,6 +366,9 @@ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk(path, &nd); if (error) return error; @@ -353,6 +383,9 @@ struct nameidata nd; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = user_path_walk_link(path, &nd); if (error) return error; @@ -367,6 +400,9 @@ struct file *f; int error = -EBADF; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + f = fget(fd); if (!f) return error; @@ -502,3 +538,9 @@ EXPORT_SYMBOL(generic_listxattr); EXPORT_SYMBOL(generic_setxattr); EXPORT_SYMBOL(generic_removexattr); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/include/asm-generic/resource.h linux-2.6.15.6-cher1/include/asm-generic/resource.h --- linux-2.6.15.6/include/asm-generic/resource.h 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/include/asm-generic/resource.h 2006-03-06 12:09:05.000000000 +0300 @@ -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 -ruN linux-2.6.15.6/include/linux/capability.h linux-2.6.15.6-cher1/include/linux/capability.h --- linux-2.6.15.6/include/linux/capability.h 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/include/linux/capability.h 2006-03-06 12:09:05.000000000 +0300 @@ -287,6 +287,15 @@ #define CAP_AUDIT_CONTROL 30 +/* The following two capability bits are added by cher */ +/* Allow open/close and most of the file operations */ + +#define CAP_SYS_OPERATIONS 29 + +/* Allow one time exec (effective when CAP_SYS_OPERATIONS dropped) */ + +#define CAP_SYS_ONE_EXEC 30 + #ifdef __KERNEL__ /* * Bounding set @@ -347,10 +356,10 @@ 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 -ruN linux-2.6.15.6/include/linux/ptrace.h linux-2.6.15.6-cher1/include/linux/ptrace.h --- linux-2.6.15.6/include/linux/ptrace.h 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/include/linux/ptrace.h 2006-03-06 12:09:05.000000000 +0300 @@ -29,6 +29,8 @@ #define PTRACE_GETSIGINFO 0x4202 #define PTRACE_SETSIGINFO 0x4203 +#define PTRACE_MEMLIMIT 0x4280 + /* options set using PTRACE_SETOPTIONS */ #define PTRACE_O_TRACESYSGOOD 0x00000001 #define PTRACE_O_TRACEFORK 0x00000002 diff -ruN linux-2.6.15.6/include/linux/sched.h linux-2.6.15.6-cher1/include/linux/sched.h --- linux-2.6.15.6/include/linux/sched.h 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/include/linux/sched.h 2006-03-06 12:09:05.000000000 +0300 @@ -909,6 +909,9 @@ #define PF_BORROWED_MM 0x00400000 /* I am a kthread doing use_mm */ #define PF_RANDOMIZE 0x00800000 /* randomize virtual address space */ +#define PF_MEMLIMITON 0x01000000 /* Memory limit detection enabled */ +#define PF_MEMLIMITERR 0x02000000 /* Killed for memory limit error */ + /* * Only the _current_ task can read/write to tsk->flags, but other * tasks can access tsk->flags in readonly mode for example diff -ruN linux-2.6.15.6/ipc/compat_mq.c linux-2.6.15.6-cher1/ipc/compat_mq.c --- linux-2.6.15.6/ipc/compat_mq.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/ipc/compat_mq.c 2006-03-13 13:06:07.000000000 +0300 @@ -51,6 +51,10 @@ 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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ } return 0; } + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/ipc/mqueue.c linux-2.6.15.6-cher1/ipc/mqueue.c --- linux-2.6.15.6/ipc/mqueue.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/ipc/mqueue.c 2006-03-06 12:09:05.000000000 +0300 @@ -655,6 +655,9 @@ char *name; int fd, error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (IS_ERR(name = getname(u_name))) return PTR_ERR(name); @@ -717,6 +720,9 @@ struct dentry *dentry; struct inode *inode = NULL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + name = getname(u_name); if (IS_ERR(name)) return PTR_ERR(name); @@ -812,6 +818,9 @@ long timeout; int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX)) return -EINVAL; @@ -894,6 +903,9 @@ struct mqueue_inode_info *info; struct ext_wait_queue wait; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + timeout = prepare_timeout(u_abs_timeout); ret = -EBADF; @@ -973,6 +985,9 @@ struct mqueue_inode_info *info; struct sk_buff *nc; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + nc = NULL; sock = NULL; if (u_notification != NULL) { @@ -1091,6 +1106,9 @@ struct inode *inode; struct mqueue_inode_info *info; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (u_mqstat != NULL) { if (copy_from_user(&mqstat, u_mqstat, sizeof(struct mq_attr))) return -EFAULT; @@ -1259,3 +1277,9 @@ } __initcall(init_mqueue_fs); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/ipc/msg.c linux-2.6.15.6-cher1/ipc/msg.c --- linux-2.6.15.6/ipc/msg.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/ipc/msg.c 2006-03-06 18:21:11.000000000 +0300 @@ -207,6 +207,9 @@ 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); @@ -333,6 +336,9 @@ struct msq_setbuf setbuf; struct kern_ipc_perm *ipcp; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (msqid < 0 || cmd < 0) return -EINVAL; @@ -558,6 +564,9 @@ 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)) @@ -670,6 +679,9 @@ 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); @@ -832,3 +844,9 @@ msq->q_ctime); } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/ipc/sem.c linux-2.6.15.6-cher1/ipc/sem.c --- linux-2.6.15.6/ipc/sem.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/ipc/sem.c 2006-03-06 18:18:15.000000000 +0300 @@ -211,6 +211,9 @@ 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); @@ -862,6 +865,9 @@ int err = -EINVAL; int version; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (semid < 0) return -EINVAL; @@ -1060,6 +1066,9 @@ 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) @@ -1350,3 +1359,9 @@ sma->sem_ctime); } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/ipc/shm.c linux-2.6.15.6-cher1/ipc/shm.c --- linux-2.6.15.6/ipc/shm.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/ipc/shm.c 2006-03-06 18:11:41.000000000 +0300 @@ -263,6 +263,9 @@ 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); @@ -421,6 +424,9 @@ struct shmid_kernel *shp; int err, version; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (cmd < 0 || shmid < 0) { err = -EINVAL; goto out; @@ -788,6 +794,9 @@ unsigned long ret; long err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + err = do_shmat(shmid, shmaddr, shmflg, &ret); if (err) return err; @@ -807,6 +816,9 @@ loff_t size = 0; int retval = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + down_write(&mm->mmap_sem); /* @@ -909,3 +921,9 @@ shp->shm_ctim); } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/acct.c linux-2.6.15.6-cher1/kernel/acct.c --- linux-2.6.15.6/kernel/acct.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/acct.c 2006-03-06 12:09:05.000000000 +0300 @@ -252,6 +252,9 @@ { int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SYS_PACCT)) return -EPERM; @@ -602,3 +605,9 @@ tsk->acct_vm_mem1 = 0; } } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/capability.c linux-2.6.15.6-cher1/kernel/capability.c --- linux-2.6.15.6/kernel/capability.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/capability.c 2006-03-06 12:09:05.000000000 +0300 @@ -48,6 +48,9 @@ task_t *target; struct __user_cap_data_struct data; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (get_user(version, &header->version)) return -EFAULT; @@ -175,6 +178,9 @@ int ret; pid_t pid; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (get_user(version, &header->version)) return -EFAULT; @@ -232,3 +238,9 @@ return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/compat.c linux-2.6.15.6-cher1/kernel/compat.c --- linux-2.6.15.6/kernel/compat.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/compat.c 2006-03-13 13:07:57.000000000 +0300 @@ -268,6 +268,9 @@ int ret; mm_segment_t old_fs = get_fs (); + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (resource >= RLIM_NLIMITS) return -EINVAL; @@ -387,6 +390,9 @@ 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 { @@ -421,6 +427,9 @@ 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); @@ -463,6 +472,9 @@ 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; @@ -478,6 +490,9 @@ 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); @@ -522,6 +537,9 @@ 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)) @@ -544,6 +562,9 @@ 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, @@ -561,6 +582,9 @@ 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(); @@ -578,6 +602,9 @@ 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, @@ -595,6 +622,9 @@ 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, @@ -613,6 +643,9 @@ mm_segment_t oldfs; struct timespec in, out; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (get_compat_timespec(&in, rqtp)) return -EFAULT; @@ -841,6 +874,9 @@ struct timespec tv; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (get_user(tv.tv_sec, tptr)) return -EFAULT; @@ -855,3 +891,9 @@ } #endif /* __ARCH_WANT_COMPAT_SYS_TIME */ + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/exec_domain.c linux-2.6.15.6-cher1/kernel/exec_domain.c --- linux-2.6.15.6/kernel/exec_domain.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/exec_domain.c 2006-03-06 12:09:05.000000000 +0300 @@ -194,6 +194,9 @@ { u_long old = current->personality; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return (long) old; + if (personality != 0xffffffff) { set_personality(personality); if (current->personality != personality) @@ -207,3 +210,9 @@ EXPORT_SYMBOL(register_exec_domain); EXPORT_SYMBOL(unregister_exec_domain); EXPORT_SYMBOL(__set_personality); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/exit.c linux-2.6.15.6-cher1/kernel/exit.c --- linux-2.6.15.6/kernel/exit.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/exit.c 2006-03-06 12:09:05.000000000 +0300 @@ -1115,7 +1115,7 @@ status = (p->signal->flags & SIGNAL_GROUP_EXIT) ? p->signal->group_exit_code : p->exit_code; if (!retval && stat_addr) - retval = put_user(status, stat_addr); + retval = put_user(status | (((p->flags & PF_MEMLIMITERR))?0x10000:0), stat_addr); if (!retval && infop) retval = put_user(SIGCHLD, &infop->si_signo); if (!retval && infop) @@ -1517,6 +1517,9 @@ { long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (options & ~(WNOHANG|WNOWAIT|WEXITED|WSTOPPED|WCONTINUED)) return -EINVAL; if (!(options & (WEXITED|WSTOPPED|WCONTINUED))) @@ -1551,6 +1554,9 @@ { long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (options & ~(WNOHANG|WUNTRACED|WCONTINUED| __WNOTHREAD|__WCLONE|__WALL)) return -EINVAL; @@ -1573,3 +1579,9 @@ } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruN linux-2.6.15.6/kernel/fork.c linux-2.6.15.6-cher1/kernel/fork.c --- linux-2.6.15.6/kernel/fork.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/fork.c 2006-03-06 12:09:05.000000000 +0300 @@ -829,6 +829,10 @@ tsk->it_prof_expires = secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur); } + if (sig->rlim[RLIMIT_MCPU].rlim_cur != RLIM_INFINITY) { + tsk->it_prof_expires = + msecs_to_cputime(sig->rlim[RLIMIT_MCPU].rlim_cur); + } return 0; } @@ -839,6 +843,7 @@ new_flags &= ~(PF_SUPERPRIV | PF_NOFREEZE); new_flags |= PF_FORKNOEXEC; + new_flags |= (p->flags & PF_MEMLIMITON); if (!(clone_flags & CLONE_PTRACE)) p->ptrace = 0; p->flags = new_flags; @@ -1102,6 +1107,7 @@ !cputime_eq(current->signal->it_prof_expires, cputime_zero) || current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY || + current->signal->rlim[RLIMIT_MCPU].rlim_cur != RLIM_INFINITY || !list_empty(¤t->signal->cpu_timers[0]) || !list_empty(¤t->signal->cpu_timers[1]) || !list_empty(¤t->signal->cpu_timers[2])) { @@ -1237,8 +1243,12 @@ { struct task_struct *p; int trace = 0; - long pid = alloc_pidmap(); + long pid; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + pid = alloc_pidmap(); if (pid < 0) return -EAGAIN; if (unlikely(current->ptrace)) { @@ -1311,3 +1321,9 @@ sizeof(struct mm_struct), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruN linux-2.6.15.6/kernel/kexec.c linux-2.6.15.6-cher1/kernel/kexec.c --- linux-2.6.15.6/kernel/kexec.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/kexec.c 2006-03-13 13:07:23.000000000 +0300 @@ -915,6 +915,9 @@ 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; @@ -1007,6 +1010,9 @@ 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. */ @@ -1060,3 +1066,9 @@ xchg(&kexec_lock, 0); } } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/module.c linux-2.6.15.6-cher1/kernel/module.c --- linux-2.6.15.6/kernel/module.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/module.c 2006-03-06 12:09:05.000000000 +0300 @@ -575,6 +575,9 @@ char name[MODULE_NAME_LEN]; int ret, forced = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SYS_MODULE)) return -EPERM; @@ -1883,6 +1886,9 @@ struct module *mod; int ret = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* Must have permission */ if (!capable(CAP_SYS_MODULE)) return -EPERM; @@ -2221,3 +2227,9 @@ void struct_module(struct module *mod) { return; } EXPORT_SYMBOL(struct_module); #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/posix-cpu-timers.c linux-2.6.15.6-cher1/kernel/posix-cpu-timers.c --- linux-2.6.15.6/kernel/posix-cpu-timers.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/posix-cpu-timers.c 2006-03-06 12:09:05.000000000 +0300 @@ -648,6 +648,10 @@ if (i != RLIM_INFINITY && i <= cputime_to_secs(timer->it.cpu.expires.cpu)) break; + i = p->signal->rlim[RLIMIT_MCPU].rlim_cur; + if (i != RLIM_INFINITY && + i <= cputime_to_msecs(timer->it.cpu.expires.cpu)) + break; goto rebalance; case CPUCLOCK_SCHED: rebalance: @@ -1029,6 +1033,7 @@ if (list_empty(&timers[CPUCLOCK_PROF]) && cputime_eq(sig->it_prof_expires, cputime_zero) && sig->rlim[RLIMIT_CPU].rlim_cur == RLIM_INFINITY && + sig->rlim[RLIMIT_MCPU].rlim_cur == RLIM_INFINITY && list_empty(&timers[CPUCLOCK_VIRT]) && cputime_eq(sig->it_virt_expires, cputime_zero) && list_empty(&timers[CPUCLOCK_SCHED])) @@ -1156,6 +1161,21 @@ } } + if (sig->rlim[RLIMIT_MCPU].rlim_cur != RLIM_INFINITY) { + unsigned long pusecs = cputime_to_msecs(ptime); + cputime_t x; + if (pusecs >= sig->rlim[RLIMIT_MCPU].rlim_max || + pusecs >= sig->rlim[RLIMIT_MCPU].rlim_cur) { + __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); + return; + } + x = msecs_to_cputime(sig->rlim[RLIMIT_MCPU].rlim_cur); + if (cputime_eq(prof_expires, cputime_zero) || + cputime_lt(x, prof_expires)) { + prof_expires = x; + } + } + if (!cputime_eq(prof_expires, cputime_zero) || !cputime_eq(virt_expires, cputime_zero) || sched_expires != 0) { @@ -1387,6 +1407,10 @@ if (tsk->signal->rlim[RLIMIT_CPU].rlim_cur < cputime_to_secs(*newval)) return; + if (tsk->signal->rlim[RLIMIT_MCPU].rlim_cur + < cputime_to_msecs(*newval)) + return; + } /* @@ -1574,3 +1598,9 @@ return 0; } __initcall(init_posix_cpu_timers); + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruN linux-2.6.15.6/kernel/posix-timers.c linux-2.6.15.6-cher1/kernel/posix-timers.c --- linux-2.6.15.6/kernel/posix-timers.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/posix-timers.c 2006-03-06 12:09:05.000000000 +0300 @@ -588,6 +588,9 @@ sigevent_t event; int it_id_set = IT_ID_NOT_SET; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (invalid_clockid(which_clock)) return -EINVAL; @@ -819,6 +822,9 @@ struct itimerspec cur_setting; unsigned long flags; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + timr = lock_timer(timer_id, &flags); if (!timr) return -EINVAL; @@ -849,6 +855,9 @@ int overrun; long flags; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + timr = lock_timer(timer_id, &flags); if (!timr) return -EINVAL; @@ -1020,6 +1029,9 @@ long flag; struct itimerspec *rtn = old_setting ? &old_spec : NULL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!new_setting) return -EINVAL; @@ -1089,6 +1101,9 @@ int error; retry_delete: #endif + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + timer = lock_timer(timer_id, &flags); if (!timer) return -EINVAL; @@ -1247,6 +1262,9 @@ { struct timespec new_tp; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (invalid_clockid(which_clock)) return -EINVAL; if (copy_from_user(&new_tp, tp, sizeof (*tp))) @@ -1261,6 +1279,9 @@ struct timespec kernel_tp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (invalid_clockid(which_clock)) return -EINVAL; error = CLOCK_DISPATCH(which_clock, clock_get, @@ -1278,6 +1299,9 @@ struct timespec rtn_tp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (invalid_clockid(which_clock)) return -EINVAL; @@ -1404,6 +1428,9 @@ &(current_thread_info()->restart_block); int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (invalid_clockid(which_clock)) return -EINVAL; @@ -1532,3 +1559,9 @@ return -EFAULT; return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/printk.c linux-2.6.15.6-cher1/kernel/printk.c --- linux-2.6.15.6/kernel/printk.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/printk.c 2006-03-06 12:09:05.000000000 +0300 @@ -353,6 +353,9 @@ 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 @@ printk_ratelimit_burst); } EXPORT_SYMBOL(printk_ratelimit); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/ptrace.c linux-2.6.15.6-cher1/kernel/ptrace.c --- linux-2.6.15.6/kernel/ptrace.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/ptrace.c 2006-03-06 12:09:05.000000000 +0300 @@ -466,10 +466,20 @@ struct task_struct *child; long ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* * This lock_kernel fixes a subtle race with suid exec */ lock_kernel(); + + if (request == PTRACE_MEMLIMIT) { + current->flags |= PF_MEMLIMITON; + ret = 0; + goto out; + } + ret = ptrace_get_task_struct(request, pid, &child); if (!child) goto out; @@ -494,3 +504,9 @@ return ret; } #endif /* __ARCH_SYS_PTRACE */ + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/sched.c linux-2.6.15.6-cher1/kernel/sched.c --- linux-2.6.15.6/kernel/sched.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/sched.c 2006-03-06 12:09:05.000000000 +0300 @@ -3604,6 +3604,9 @@ int retval; long nice; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* * Setpriority might change our priority at the same moment. * We don't have to worry. Conceptually one call occurs first @@ -3817,6 +3820,9 @@ asmlinkage long sys_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + return do_sched_setscheduler(pid, policy, param); } @@ -3827,6 +3833,9 @@ */ asmlinkage long sys_sched_setparam(pid_t pid, struct sched_param __user *param) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + return do_sched_setscheduler(pid, -1, param); } @@ -3842,6 +3851,9 @@ if (pid < 0) goto out_nounlock; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = -ESRCH; read_lock(&tasklist_lock); p = find_process_by_pid(pid); @@ -3870,6 +3882,9 @@ if (!param || pid < 0) goto out_nounlock; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + read_lock(&tasklist_lock); p = find_process_by_pid(pid); retval = -ESRCH; @@ -3958,6 +3973,9 @@ cpumask_t new_mask; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = get_user_cpu_mask(user_mask_ptr, len, &new_mask); if (retval) return retval; @@ -4017,6 +4035,9 @@ int ret; cpumask_t mask; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (len < sizeof(cpumask_t)) return -EINVAL; @@ -4210,6 +4231,9 @@ { int ret = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (policy) { case SCHED_FIFO: case SCHED_RR: @@ -4233,6 +4257,9 @@ { int ret = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (policy) { case SCHED_FIFO: case SCHED_RR: @@ -4262,6 +4289,9 @@ if (pid < 0) goto out_nounlock; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = -ESRCH; read_lock(&tasklist_lock); p = find_process_by_pid(pid); @@ -5745,3 +5775,9 @@ } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/signal.c linux-2.6.15.6-cher1/kernel/signal.c --- linux-2.6.15.6/kernel/signal.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/signal.c 2006-03-06 12:09:05.000000000 +0300 @@ -1191,6 +1191,18 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) { + if (!pid) { + pid = current->pid; + } else if (pid == -1) { + return -EPERM; + } else if (pid < 0) { + if (current->signal->pgrp != -pid) + return -EPERM; + pid = current->pid; + } + } + if (!pid) { return kill_pg_info(sig, info, process_group(current)); } else if (pid == -1) { @@ -2300,6 +2312,9 @@ if (pid <= 0 || tgid <= 0) return -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + return do_tkill(tgid, pid, sig); } @@ -2313,6 +2328,9 @@ if (pid <= 0) return -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + return do_tkill(0, pid, sig); } @@ -2330,6 +2348,11 @@ return -EPERM; info.si_signo = sig; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) { + if (pid <= 0 || pid != current->pid) + return -EPERM; + } + /* POSIX.1b doesn't mention process groups. */ return kill_proc_info(sig, &info, pid); } @@ -2615,6 +2638,9 @@ asmlinkage long sys_pause(void) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + current->state = TASK_INTERRUPTIBLE; schedule(); return -ERESTARTNOHAND; @@ -2630,3 +2656,9 @@ __alignof__(struct sigqueue), SLAB_PANIC, NULL, NULL); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/sys.c linux-2.6.15.6-cher1/kernel/sys.c --- linux-2.6.15.6/kernel/sys.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/sys.c 2006-03-06 12:09:05.000000000 +0300 @@ -254,6 +254,9 @@ struct user_struct *user; int error = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (which > 2 || which < 0) goto out; @@ -314,6 +317,9 @@ struct user_struct *user; long niceval, retval = -ESRCH; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (which > 2 || which < 0) return -EINVAL; @@ -477,6 +483,9 @@ { char buffer[256]; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* We only trust the superuser with rebooting the system. */ if (!capable(CAP_SYS_BOOT)) return -EPERM; @@ -594,6 +603,9 @@ int new_egid = old_egid; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = security_task_setgid(rgid, egid, (gid_t)-1, LSM_SETID_RE); if (retval) return retval; @@ -642,6 +654,9 @@ int old_egid = current->egid; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_ID); if (retval) return retval; @@ -718,6 +733,9 @@ int old_ruid, old_euid, old_suid, new_ruid, new_euid; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = security_task_setuid(ruid, euid, (uid_t)-1, LSM_SETID_RE); if (retval) return retval; @@ -782,6 +800,9 @@ int old_ruid, old_suid, new_ruid, new_suid; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_ID); if (retval) return retval; @@ -823,6 +844,9 @@ int old_suid = current->suid; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = security_task_setuid(ruid, euid, suid, LSM_SETID_RES); if (retval) return retval; @@ -864,6 +888,9 @@ { int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!(retval = put_user(current->uid, ruid)) && !(retval = put_user(current->euid, euid))) retval = put_user(current->suid, suid); @@ -878,6 +905,9 @@ { int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = security_task_setgid(rgid, egid, sgid, LSM_SETID_RES); if (retval) return retval; @@ -916,6 +946,9 @@ { int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!(retval = put_user(current->gid, rgid)) && !(retval = put_user(current->egid, egid))) retval = put_user(current->sgid, sgid); @@ -934,6 +967,9 @@ { int old_fsuid; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + old_fsuid = current->fsuid; if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS)) return old_fsuid; @@ -965,6 +1001,9 @@ { int old_fsgid; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + old_fsgid = current->fsgid; if (security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS)) return old_fsgid; @@ -1086,6 +1125,9 @@ struct task_struct *p; int err = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!pid) pid = current->pid; if (!pgid) @@ -1160,6 +1202,9 @@ int retval; struct task_struct *p; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + read_lock(&tasklist_lock); p = find_task_by_pid(pid); @@ -1192,6 +1237,9 @@ int retval; struct task_struct *p; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + read_lock(&tasklist_lock); p = find_task_by_pid(pid); @@ -1211,6 +1259,9 @@ struct pid *pid; int err = -EPERM; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!thread_group_leader(current)) return -EINVAL; @@ -1415,6 +1466,8 @@ * SMP: Nobody else can change our grouplist. Thus we are * safe. */ + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; if (gidsetsize < 0) return -EINVAL; @@ -1447,6 +1500,9 @@ struct group_info *group_info; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SETGID)) return -EPERM; if ((unsigned)gidsetsize > NGROUPS_MAX) @@ -1516,6 +1572,9 @@ int errno; char tmp[__NEW_UTS_LEN]; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (len < 0 || len > __NEW_UTS_LEN) @@ -1561,6 +1620,9 @@ int errno; char tmp[__NEW_UTS_LEN]; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (len < 0 || len > __NEW_UTS_LEN) @@ -1619,6 +1681,9 @@ struct rlimit new_rlim, *old_rlim; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (resource >= RLIM_NLIMITS) return -EINVAL; if(copy_from_user(&new_rlim, rlim, sizeof(*rlim))) @@ -1652,6 +1717,18 @@ spin_unlock_irq(¤t->sighand->siglock); read_unlock(&tasklist_lock); } + if (resource == RLIMIT_MCPU && new_rlim.rlim_cur != RLIM_INFINITY && + (cputime_eq(current->signal->it_prof_expires, cputime_zero) || + new_rlim.rlim_cur <= cputime_to_msecs( + current->signal->it_prof_expires))) { + cputime_t cputime = msecs_to_cputime(new_rlim.rlim_cur); + read_lock(&tasklist_lock); + spin_lock_irq(¤t->sighand->siglock); + set_process_cpu_timer(current, CPUCLOCK_PROF, + &cputime, NULL); + spin_unlock_irq(¤t->sighand->siglock); + read_unlock(&tasklist_lock); + } return 0; } @@ -1756,6 +1833,8 @@ asmlinkage long sys_umask(int mask) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return current->fs->umask; mask = xchg(¤t->fs->umask, mask & S_IRWXUGO); return mask; } @@ -1765,6 +1844,9 @@ { long error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + error = security_task_prctl(option, arg2, arg3, arg4, arg5); if (error) return error; @@ -1856,3 +1938,9 @@ } return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/sysctl.c linux-2.6.15.6-cher1/kernel/sysctl.c --- linux-2.6.15.6/kernel/sysctl.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/sysctl.c 2006-03-06 12:09:05.000000000 +0300 @@ -1085,6 +1085,9 @@ struct __sysctl_args tmp; int error; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (copy_from_user(&tmp, args, sizeof(tmp))) return -EFAULT; @@ -2447,3 +2450,9 @@ EXPORT_SYMBOL(sysctl_ms_jiffies); EXPORT_SYMBOL(sysctl_string); EXPORT_SYMBOL(unregister_sysctl_table); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/time.c linux-2.6.15.6-cher1/kernel/time.c --- linux-2.6.15.6/kernel/time.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/time.c 2006-03-06 12:09:05.000000000 +0300 @@ -82,6 +82,9 @@ struct timespec tv; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (get_user(tv.tv_sec, tptr)) return -EFAULT; @@ -184,6 +187,9 @@ struct timespec new_ts; struct timezone new_tz; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (tv) { if (copy_from_user(&user_tv, tv, sizeof(*tv))) return -EFAULT; @@ -403,6 +409,9 @@ struct timex txc; /* Local copy of parameter */ int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* Copy the user data space into the kernel copy * structure. But bear in mind that the structures * may change @@ -600,3 +609,9 @@ #endif EXPORT_SYMBOL(jiffies); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/timer.c linux-2.6.15.6-cher1/kernel/timer.c --- linux-2.6.15.6/kernel/timer.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/timer.c 2006-03-06 12:09:05.000000000 +0300 @@ -1184,6 +1184,9 @@ unsigned int mem_unit, bitcount; unsigned long seq; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + memset((char *)&val, 0, sizeof(struct sysinfo)); do { @@ -1576,3 +1579,9 @@ } EXPORT_SYMBOL(msleep_interruptible); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/kernel/uid16.c linux-2.6.15.6-cher1/kernel/uid16.c --- linux-2.6.15.6/kernel/uid16.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/kernel/uid16.c 2006-03-06 12:09:05.000000000 +0300 @@ -130,6 +130,9 @@ { int i = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (gidsetsize < 0) return -EINVAL; @@ -155,6 +158,9 @@ struct group_info *group_info; int retval; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!capable(CAP_SETGID)) return -EPERM; if ((unsigned)gidsetsize > NGROUPS_MAX) @@ -194,3 +200,9 @@ { return high2lowgid(current->egid); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/Makefile linux-2.6.15.6-cher1/Makefile --- linux-2.6.15.6/Makefile 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/Makefile 2006-03-06 12:09:18.000000000 +0300 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 15 -EXTRAVERSION = .6 +EXTRAVERSION = .6-cher1 NAME=Sliding Snow Leopard # *DOCUMENTATION* diff -ruN linux-2.6.15.6/mm/fadvise.c linux-2.6.15.6-cher1/mm/fadvise.c --- linux-2.6.15.6/mm/fadvise.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/mm/fadvise.c 2006-03-06 12:09:05.000000000 +0300 @@ -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 @@ unsigned long nrpages; int ret = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + + file = fget(fd); if (!file) return -EBADF; @@ -113,3 +117,9 @@ } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/mm/filemap.c linux-2.6.15.6-cher1/mm/filemap.c --- linux-2.6.15.6/mm/filemap.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/mm/filemap.c 2006-03-06 12:09:05.000000000 +0300 @@ -1127,6 +1127,9 @@ ssize_t ret; struct file *file; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + ret = -EBADF; file = fget(fd); if (file) { @@ -2268,3 +2271,9 @@ } return retval; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/mm/fremap.c linux-2.6.15.6-cher1/mm/fremap.c --- linux-2.6.15.6/mm/fremap.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/mm/fremap.c 2006-03-06 12:09:05.000000000 +0300 @@ -149,6 +149,9 @@ int err = -EINVAL; int has_write_lock = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (__prot) return err; /* @@ -221,3 +224,8 @@ return err; } +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/mm/madvise.c linux-2.6.15.6-cher1/mm/madvise.c --- linux-2.6.15.6/mm/madvise.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/mm/madvise.c 2006-03-06 12:09:05.000000000 +0300 @@ -210,6 +210,9 @@ int error = -EINVAL; size_t len; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + down_write(¤t->mm->mmap_sem); if (start & ~PAGE_MASK) @@ -272,3 +275,9 @@ up_write(¤t->mm->mmap_sem); return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/mm/mempolicy.c linux-2.6.15.6-cher1/mm/mempolicy.c --- linux-2.6.15.6/mm/mempolicy.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/mm/mempolicy.c 2006-03-06 12:09:05.000000000 +0300 @@ -583,6 +583,9 @@ nodemask_t nodes; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + err = get_nodes(&nodes, nmask, maxnode); if (err) return err; @@ -596,6 +599,9 @@ int err; nodemask_t nodes; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (mode < 0 || mode > MPOL_MAX) return -EINVAL; err = get_nodes(&nodes, nmask, maxnode); @@ -613,6 +619,9 @@ int err, pval; nodemask_t nodes; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (nmask != NULL && maxnode < MAX_NUMNODES) return -EINVAL; @@ -642,6 +651,9 @@ unsigned long nr_bits, alloc_size; DECLARE_BITMAP(bm, MAX_NUMNODES); + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES); alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; @@ -668,6 +680,9 @@ unsigned long nr_bits, alloc_size; DECLARE_BITMAP(bm, MAX_NUMNODES); + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES); alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; @@ -692,6 +707,9 @@ unsigned long nr_bits, alloc_size; nodemask_t bm; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES); alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; @@ -1272,3 +1290,9 @@ { rebind_policy(current->mempolicy, old, new); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/mm/mincore.c linux-2.6.15.6-cher1/mm/mincore.c --- linux-2.6.15.6/mm/mincore.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/mm/mincore.c 2006-03-06 12:09:05.000000000 +0300 @@ -114,6 +114,9 @@ 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 @@ enomem: return -ENOMEM; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/mm/mlock.c linux-2.6.15.6-cher1/mm/mlock.c --- linux-2.6.15.6/mm/mlock.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/mm/mlock.c 2006-03-06 12:09:05.000000000 +0300 @@ -126,6 +126,9 @@ unsigned long lock_limit; int error = -ENOMEM; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!can_do_mlock()) return -EPERM; @@ -150,6 +153,9 @@ { int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + down_write(¤t->mm->mmap_sem); len = PAGE_ALIGN(len + (start & ~PAGE_MASK)); start &= PAGE_MASK; @@ -188,6 +194,9 @@ unsigned long lock_limit; int ret = -EINVAL; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE))) goto out; @@ -213,6 +222,9 @@ { int ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + down_write(¤t->mm->mmap_sem); ret = do_mlockall(0); up_write(¤t->mm->mmap_sem); @@ -251,3 +263,9 @@ spin_unlock(&shmlock_user_lock); free_uid(user); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/mm/mmap.c linux-2.6.15.6-cher1/mm/mmap.c --- linux-2.6.15.6/mm/mmap.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/mm/mmap.c 2006-03-06 12:09:05.000000000 +0300 @@ -233,8 +233,13 @@ /* Check against rlimit.. */ rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; - if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim) + if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim) { + if ((current->flags & PF_MEMLIMITON)) { + current->flags |= PF_MEMLIMITERR; + send_sig(SIGKILL, current, 0); + } goto out; + } /* Check against existing mmap mappings. */ if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) @@ -1457,8 +1462,13 @@ return -ENOMEM; /* Stack limit test */ - if (size > rlim[RLIMIT_STACK].rlim_cur) + if (size > rlim[RLIMIT_STACK].rlim_cur) { + if ((current->flags & PF_MEMLIMITON)) { + current->flags |= PF_MEMLIMITERR; + send_sig(SIGKILL, current, 0); + } return -ENOMEM; + } /* mlock limit tests */ if (vma->vm_flags & VM_LOCKED) { @@ -2056,7 +2066,18 @@ 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 -ruN linux-2.6.15.6/mm/mprotect.c linux-2.6.15.6-cher1/mm/mprotect.c --- linux-2.6.15.6/mm/mprotect.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/mm/mprotect.c 2006-03-06 12:09:05.000000000 +0300 @@ -187,6 +187,9 @@ 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 @@ up_write(¤t->mm->mmap_sem); return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/mm/mremap.c linux-2.6.15.6-cher1/mm/mremap.c --- linux-2.6.15.6/mm/mremap.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/mm/mremap.c 2006-03-06 12:09:05.000000000 +0300 @@ -407,8 +407,17 @@ { 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 -ruN linux-2.6.15.6/mm/swapfile.c linux-2.6.15.6-cher1/mm/swapfile.c --- linux-2.6.15.6/mm/swapfile.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/mm/swapfile.c 2006-03-06 12:09:05.000000000 +0300 @@ -1061,7 +1061,9 @@ char * pathname; int i, type, prev; int err; - + + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1300,6 +1302,8 @@ struct inode *inode = NULL; int did_down = 0; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; if (!capable(CAP_SYS_ADMIN)) return -EPERM; spin_lock(&swap_lock); @@ -1676,3 +1680,9 @@ spin_unlock(&swap_lock); return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/net/compat.c linux-2.6.15.6-cher1/net/compat.c --- linux-2.6.15.6/net/compat.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/net/compat.c 2006-03-13 12:43:53.000000000 +0300 @@ -535,6 +535,9 @@ 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 @@ } return ret; } + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/net/socket.c linux-2.6.15.6-cher1/net/socket.c --- linux-2.6.15.6/net/socket.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/net/socket.c 2006-03-06 12:09:05.000000000 +0300 @@ -1191,6 +1191,9 @@ int retval; struct socket *sock; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + retval = sock_create(family, type, protocol, &sock); if (retval < 0) goto out; @@ -1217,6 +1220,9 @@ struct socket *sock1, *sock2; int fd1, fd2, err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* * Obtain the first socket and check if the underlying protocol * supports the socketpair call. @@ -1288,6 +1294,9 @@ char address[MAX_SOCK_ADDR]; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if((sock = sockfd_lookup(fd,&err))!=NULL) { if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) { @@ -1317,6 +1326,9 @@ struct socket *sock; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((sock = sockfd_lookup(fd, &err)) != NULL) { if ((unsigned) backlog > sysctl_somaxconn) backlog = sysctl_somaxconn; @@ -1352,6 +1364,9 @@ int err, len; char address[MAX_SOCK_ADDR]; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1422,6 +1437,9 @@ char address[MAX_SOCK_ADDR]; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1452,6 +1470,9 @@ char address[MAX_SOCK_ADDR]; int len, err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1482,6 +1503,9 @@ char address[MAX_SOCK_ADDR]; int len, err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((sock = sockfd_lookup(fd, &err))!=NULL) { err = security_socket_getpeername(sock); @@ -1513,6 +1537,9 @@ struct msghdr msg; struct iovec iov; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1567,6 +1594,9 @@ char address[MAX_SOCK_ADDR]; int err,err2; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1613,6 +1643,9 @@ int err; struct socket *sock; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (optlen < 0) return -EINVAL; @@ -1643,6 +1676,9 @@ int err; struct socket *sock; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((sock = sockfd_lookup(fd, &err))!=NULL) { err = security_socket_getsockopt(sock, level, @@ -1671,6 +1707,9 @@ int err; struct socket *sock; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if ((sock = sockfd_lookup(fd, &err))!=NULL) { err = security_socket_shutdown(sock, how); @@ -1710,6 +1749,9 @@ struct msghdr msg_sys; int err, ctl_len, iov_size, total_len; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + err = -EFAULT; if (MSG_CMSG_COMPAT & flags) { if (get_compat_msghdr(&msg_sys, msg_compat)) @@ -1811,6 +1853,9 @@ struct sockaddr __user *uaddr; int __user *uaddr_len; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if (MSG_CMSG_COMPAT & flags) { if (get_compat_msghdr(&msg_sys, msg_compat)) return -EFAULT; @@ -1913,6 +1958,9 @@ unsigned long a0,a1; int err; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + if(call<1||call>SYS_RECVMSG) return -EINVAL; @@ -2100,3 +2148,9 @@ EXPORT_SYMBOL(sockfd_lookup); EXPORT_SYMBOL(kernel_sendmsg); EXPORT_SYMBOL(kernel_recvmsg); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.6.15.6/security/keys/keyctl.c linux-2.6.15.6-cher1/security/keys/keyctl.c --- linux-2.6.15.6/security/keys/keyctl.c 2006-03-05 22:07:54.000000000 +0300 +++ linux-2.6.15.6-cher1/security/keys/keyctl.c 2006-03-06 12:09:05.000000000 +0300 @@ -39,6 +39,9 @@ void *payload; long dlen, ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + ret = -EINVAL; if (plen > 32767) goto error; @@ -137,6 +140,9 @@ char type[32], *description, *callout_info; long dlen, ret; + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + /* pull the type into kernel space */ ret = strncpy_from_user(type, _type, sizeof(type) - 1); if (ret < 0) @@ -977,6 +983,9 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { + if (unlikely(!capable(CAP_SYS_OPERATIONS))) + return -EPERM; + switch (option) { case KEYCTL_GET_KEYRING_ID: return keyctl_get_keyring_ID((key_serial_t) arg2, @@ -1048,3 +1057,9 @@ } } /* end sys_keyctl() */ + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */