diff -ruN linux-2.4.25/Makefile linux-2.4.25-cher1/Makefile --- linux-2.4.25/Makefile 2004-02-20 18:13:40.000000000 +0300 +++ linux-2.4.25-cher1/Makefile 2004-02-20 18:14:57.000000000 +0300 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 25 -EXTRAVERSION = -ow1 +EXTRAVERSION = -cher1 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) @@ -292,7 +292,7 @@ $(NETWORKS) \ $(LIBS) \ --end-group \ - -o vmlinux + -o vmlinux -Map vmlinux.map --cref $(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map symlinks: diff -ruN linux-2.4.25/SYSCALLS linux-2.4.25-cher1/SYSCALLS --- linux-2.4.25/SYSCALLS 1970-01-01 03:00:00.000000000 +0300 +++ linux-2.4.25-cher1/SYSCALLS 2004-02-20 18:14:16.000000000 +0300 @@ -0,0 +1,252 @@ +sys_exit OK kernel/exit.c:487 +sys_fork CAP kernel/fork.c:577 +sys_read OK fs/read_write.c:168 +sys_write OK fs/read_write.c:193 +sys_open CAP fs/open.c:783 +sys_close OK fs/open.c:906 +sys_waitpid CAP kernel/exit.c:599 +sys_creat CAP fs/open.c:2043 +sys_link CAP fs/namei.c:1660 +sys_unlink CAP fs/namei.c:1505 +sys_execve CAP arch/i386/kernel/process.c:777 +sys_chdir CAP fs/open.c:405 +sys_time OK kernel/time.c:53 +sys_mknod CAP fs/namei.c:1262 +sys_chmod CAP fs/open.c:528 +sys_lchown16 CAP kernel/uid16.c:38 +sys_ni_syscall XXX +sys_stat CAP fs/stat.c:135 +sys_lseek CAP fs/read_write.c:108 +sys_getpid OK kernel/timer.c:753 +sys_mount CAP fs/namespace.c:826 +sys_oldumount CAP fs/namespace.c:393 +sys_setuid16 CAP kernel/uid16.c:78 +sys_getuid16 OK kernel/uid16.c:184 +sys_stime ROOT kernel/time.c:74 +sys_ptrace CAP arch/i386/kernel/ptrace.c:150 +sys_alarm OK kernel/timer.c:718 +sys_fstat CAP fs/stat.c:222 +sys_pause CAP arch/i386/kernel/sys_i386.c:272 +sys_utime CAP fs/open.c:268 +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_access CAP fs/open.c:362 +sys_nice OK kernel/sched.c:1037 +sys_ni_syscall XXX +sys_sync CAP fs/buffer.c:364 +sys_kill CAP kernel/signal.c:989 +sys_rename CAP fs/namei.c:1935 +sys_mkdir CAP fs/namei.c:1335 +sys_rmdir CAP fs/namei.c:1434 +sys_dup CAP fs/fcntl.c:195 +sys_pipe CAP arch/i386/kernel/sys_i386.c:29 +sys_times OK kernel/sys.c:825 +sys_ni_syscall XXX +sys_brk OK mm/mmap.c:147 +sys_setgid16 CAP kernel/uid16.c:62 +sys_getgid16 OK kernel/uid16.c:194 +sys_signal OK kernel/signal.c:1288 +sys_geteuid16 OK kernel/uid16.c:189 +sys_getegid16 OK kernel/uid16.c:199 +sys_acct ROOT kernel/acct.c:155 +sys_umount CAP fs/namespace.c:361 +sys_ni_syscall XXX +sys_ioctl CAP fs/ioctl.c:49 +sys_fcntl CAP fs/fcntl.c:345 +sys_ni_syscall XXX +sys_setpgid CAP kernel/sys.c:852 +sys_ni_syscall XXX +sys_olduname CAP arch/i386/kernel/sys_i386.c:240 +sys_umask CAP kernel/sys.c:1248 +sys_chroot CAP fs/open.c:462 +sys_ustat CAP fs/super.c:509 +sys_dup2 CAP fs/fcntl.c:138 +sys_getppid CAP kernel/timer.c:781 +sys_getpgrp OK kernel/sys.c:927 +sys_setsid CAP kernel/sys.c:955 +sys_sigaction OK arch/i386/kernel/signal.c:123 +sys_sgetmask OK kernel/signal.c:1260 +sys_ssetmask OK kernel/signal.c:1267 +sys_setreuid16 CAP kernel/uid16.c:70 +sys_setregid16 CAP kernel/uid16.c:54 +sys_sigsuspend OK arch/i386/kernel/signal.c:72 +sys_sigpending OK kernel/signal.c:1169 +sys_sethostname ROOT kernel/sys.c:1074 +sys_setrlimit CAP kernel/sys.c:1163 +sys_old_getrlimit OK kernel/sys.c:1147 +sys_getrusage OK kernel/sys.c:1241 +sys_gettimeofday OK kernel/time.c:97 +sys_settimeofday ROOT kernel/time.c:174 +sys_getgroups16 CAP kernel/uid16.c:142 +sys_setgroups16 CAP kernel/uid16.c:164 +old_select CAP arch/i386/kernel/sys_i386.c:126 +sys_symlink CAP fs/namei.c:1575 +sys_lstat CAP fs/stat.c:178 +sys_readlink CAP fs/stat.c:264 +sys_uselib CAP fs/exec.c:105 +sys_swapon ROOT mm/swapfile.c:855 +sys_reboot CAP kernel/sys.c:270 +old_readdir CAP fs/readdir.c:204 +old_mmap CAP arch/i386/kernel/sys_i386.c:97 +sys_munmap CAP mm/mmap.c:1013 +sys_truncate CAP fs/open.c:122 +sys_ftruncate CAP fs/open.c:191 +sys_fchmod CAP fs/open.c:492 +sys_fchown16 CAP kernel/uid16.c:46 +sys_getpriority OK kernel/sys.c:239 +sys_setpriority OK kernel/sys.c:197 +sys_ni_syscall XXX +sys_statfs CAP fs/open.c:40 +sys_fstatfs CAP fs/open.c:59 +sys_ioperm CAP arch/i386/kernel/ioport.c:55 +sys_socketcall CAP net/socket.c:1581 +sys_syslog CAP kernel/printk.c:295 +sys_setitimer OK kernel/itimer.c:151 +sys_getitimer OK kernel/itimer.c:79 +sys_newstat CAP fs/stat.c:154 +sys_newlstat CAP fs/stat.c:198 +sys_newfstat CAP fs/stat.c:244 +sys_uname CAP arch/i386/kernel/sys_i386.c:225 +sys_iopl CAP arch/i386/kernel/ioport.c:104 +sys_vhangup CAP fs/open.c:932 +sys_ni_syscall XXX +sys_vm86old CAP arch/i386/kernel/vm86.c:160 +sys_wait4 CAP kernel/exit.c:492 +sys_swapoff ROOT mm/swapfile.c:707 +sys_sysinfo CAP kernel/info.c:16 +sys_ipc CAP arch/i386/kernel/sys_i386.c:144 +sys_fsync CAP fs/buffer.c:402 +sys_sigreturn OK arch/i386/kernel/signal.c:252 +sys_clone CAP kernel/fork.c:577 +sys_setdomainname ROOT kernel/sys.c:1113 +sys_newuname OK kernel/sys.c:1063 +sys_modify_ldt CAP arch/i386/kernel/ldt.c:151 +sys_adjtimex ROOT kernel/time.c:398 +sys_mprotect CAP mm/mprotect.c:267 +sys_sigprocmask OK kernel/signal.c:1178 +sys_create_module ROOT kernel/module.c:292 +sys_init_module ROOT kernel/module.c:346 +sys_delete_module ROOT kernel/module.c:595 +sys_get_kernel_syms CAP kernel/module.c:956 +sys_quotactl CAP fs/dquot.c:1382 +sys_getpgid OK kernel/sys.c:908 +sys_fchdir CAP fs/open.c:429 +sys_bdflush ROOT fs/buffer.c:402 +sys_sysfs CAP fs/super.c:201 +sys_personality CAP kernel/exec_domain.c:220 +sys_ni_syscall XXX +sys_setfsuid16 CAP kernel/uid16.c:126 +sys_setfsgid16 CAP kernel/uid16.c:134 +sys_llseek CAP fs/read_write.c:133 +sys_getdents CAP fs/readdir.c:272 +sys_select OK fs/select.c:259 +sys_flock CAP fs/locks.c:1272 +sys_msync CAP mm/filemap.c:2254 +sys_readv OK fs/read_write.c:328 +sys_writev OK fs/read_write.c:348 +sys_getsid CAP kernel/sys.c:933 +sys_fdatasync CAP fs/buffer.c:443 +sys_sysctl CAP kernel/sysctl.c:362 +sys_mlock CAP mm/mlock.c:195 +sys_munlock CAP mm/mlock.c:229 +sys_mlockall CAP mm/mlock.c:272 +sys_munlockall CAP mm/mlock.c:302 +sys_sched_setparam OK kernel/sched.c:973 +sys_sched_getparam OK kernel/sched.c:998 +sys_sched_setscheduler OK kernel/sched.c:967 +sys_sched_getscheduler OK kernel/sched.c:978 +sys_sched_yield OK kernel/sched.c:1029 +sys_sched_get_priority_max OK kernel/sched.c:1089 +sys_sched_get_priority_min OK kernel/sched.c:1105 +sys_sched_rr_get_interval OK kernel/sched.c:1120 +sys_nanosleep OK kernel/timer.c:839 +sys_mremap CAP mm/mremap.c:342 +sys_setresuid16 CAP kernel/uid16.c:86 +sys_getresuid16 OK kernel/uid16.c:95 +sys_vm86 CAP arch/i386/kernel/vm86.c:192 +sys_query_module CAP kernel/module.c:884 +sys_poll OK fs/select.c:412 +sys_nfsservctl CAP fs/filesystems.c:20 +sys_setresgid16 CAP kernel/uid16.c:106 +sys_getresgid16 OK kernel/uid16.c:115 +sys_prctl CAP kernel/sys.c:1257 +sys_rt_sigreturn OK arch/i386/kernel/signal.c:282 +sys_rt_sigaction OK kernel/signal.c:1228 +sys_rt_sigprocmask OK kernel/signal.c:833 +sys_rt_sigpending OK kernel/signal.c:908 +sys_rt_sigtimedwait OK kernel/signal.c:914 +sys_rt_sigqueueinfo OK kernel/signal.c:1033 +sys_rt_sigsuspend OK arch/i386/kernel/signal.c:94 +sys_pread CAP fs/read_write.c:372 +sys_pwrite CAP fs/read_write.c:406 +sys_chown16 CAP kernel/uid16.c:30 +sys_getcwd CAP fs/dcache.c:1016 +sys_capget OK kernel/capability.c:22 +sys_capset CAP kernel/capability.c:129 +sys_sigaltstack CAP arch/i386/kernel/signal.c:155 +sys_sendfile CAP mm/filemap.c:1743 +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_vfork CAP arch/i386/kernel/process.c:769 +sys_getrlimit OK kernel/sys.c:1132 +sys_mmap2 CAP arch/i386/kernel/sys_i386.c:72 +sys_truncate64 CAP fs/open.c:122 +sys_ftruncate64 CAP fs/open.c:191 +sys_stat64 CAP fs/stat.c:353 +sys_lstat64 CAP fs/stat.c:371 +sys_fstat64 CAP fs/stat.c:389 +sys_lchown CAP fs/open.c:639 +sys_getuid OK kernel/timer.c:807 +sys_getgid OK kernel/timer.c:819 +sys_geteuid OK kernel/timer.c:813 +sys_getegid OK kernel/timer.c:825 +sys_setreuid CAP kernel/sys.c:544 +sys_setregid CAP kernel/sys.c:379 +sys_getgroups CAP kernel/sys.c:982 +sys_setgroups CAP kernel/sys.c:1011 +sys_fchown CAP fs/open.c:656 +sys_setresuid CAP kernel/sys.c:645 +sys_getresuid CAP kernel/sys.c:688 +sys_setresgid CAP kernel/sys.c:705 +sys_getresgid CAP kernel/sys.c:737 +sys_chown CAP fs/open.c:623 +sys_setuid CAP kernel/sys.c:606 +sys_setgid CAP kernel/sys.c:426 +sys_setfsuid CAP kernel/sys.c:758 +sys_setfsgid CAP kernel/sys.c:803 +sys_pivot_root ROOT fs/namespace.c:906 +sys_mincore CAP mm/filemap.c:2759 +sys_madvise CAP mm/filemap.c:2605 +sys_getdents64 CAP fs/readdir.c:358 +sys_fcntl64 CAP fs/fcntl.c:365 +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_gettid OK kernel/timer.c:834 +sys_readahead CAP mm/filemap.c:1851 +sys_setxattr CAP fs/xattr.c:99 +sys_lsetxattr CAP fs/xattr.c:116 +sys_fsetxattr CAP fs/xattr.c:133 +sys_getxattr CAP fs/xattr.c:186 +sys_lgetxattr CAP fs/xattr.c:203 +sys_fgetxattr CAP fs/xattr.c:220 +sys_listxattr CAP fs/xattr.c:266 +sys_llistxattr CAP fs/xattr.c:283 +sys_flistxattr CAP fs/xattr.c:300 +sys_removexattr CAP fs/xattr.c:343 +sys_lremovexattr CAP fs/xattr.c:360 +sys_fremovexattr CAP fs/xattr.c:377 +sys_tkill CAP kernel/signal.c:1006 +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_ni_syscall XXX +sys_ni_syscall XXX diff -ruN linux-2.4.25/arch/i386/kernel/ioport.c linux-2.4.25-cher1/arch/i386/kernel/ioport.c --- linux-2.4.25/arch/i386/kernel/ioport.c 2003-06-13 18:51:29.000000000 +0400 +++ linux-2.4.25-cher1/arch/i386/kernel/ioport.c 2004-02-20 18:14:16.000000000 +0300 @@ -57,6 +57,9 @@ struct thread_struct * t = ¤t->thread; struct tss_struct * tss = init_tss + smp_processor_id(); + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32)) return -EINVAL; if (turn_on && !capable(CAP_SYS_RAWIO)) @@ -105,6 +108,9 @@ unsigned int level = regs->ebx; unsigned int old = (regs->eflags >> 12) & 3; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (level > 3) return -EINVAL; /* Trying to gain more privileges? */ @@ -115,3 +121,9 @@ regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12); return 0; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/arch/i386/kernel/ldt.c linux-2.4.25-cher1/arch/i386/kernel/ldt.c --- linux-2.4.25/arch/i386/kernel/ldt.c 2004-02-18 16:36:30.000000000 +0300 +++ linux-2.4.25-cher1/arch/i386/kernel/ldt.c 2004-02-20 18:14:16.000000000 +0300 @@ -244,6 +244,9 @@ { int ret = -ENOSYS; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + switch (func) { case 0: ret = read_ldt(ptr, bytecount); @@ -260,3 +263,9 @@ } return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/arch/i386/kernel/process.c linux-2.4.25-cher1/arch/i386/kernel/process.c --- linux-2.4.25/arch/i386/kernel/process.c 2004-02-18 16:36:30.000000000 +0300 +++ linux-2.4.25-cher1/arch/i386/kernel/process.c 2004-02-20 18:14:16.000000000 +0300 @@ -746,14 +746,28 @@ { 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 *) regs.ebx); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, ®s); - if (error == 0) + if (error == 0) { + 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; + } putname(filename); out: return error; @@ -792,3 +806,9 @@ } #undef last_sched #undef first_sched + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruN linux-2.4.25/arch/i386/kernel/ptrace.c linux-2.4.25-cher1/arch/i386/kernel/ptrace.c --- linux-2.4.25/arch/i386/kernel/ptrace.c 2002-08-03 04:39:42.000000000 +0400 +++ linux-2.4.25-cher1/arch/i386/kernel/ptrace.c 2004-02-20 18:14:16.000000000 +0300 @@ -153,6 +153,9 @@ struct user * dummy = NULL; int i, ret; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + lock_kernel(); ret = -EPERM; if (request == PTRACE_TRACEME) { @@ -452,3 +455,9 @@ current->exit_code = 0; } } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/arch/i386/kernel/signal.c linux-2.4.25-cher1/arch/i386/kernel/signal.c --- linux-2.4.25/arch/i386/kernel/signal.c 2004-02-20 18:13:40.000000000 +0300 +++ linux-2.4.25-cher1/arch/i386/kernel/signal.c 2004-02-20 18:14:16.000000000 +0300 @@ -154,6 +154,9 @@ asmlinkage int sys_sigaltstack(const stack_t *uss, stack_t *uoss) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + struct pt_regs *regs = (struct pt_regs *) &uss; return do_sigaltstack(uss, uoss, regs->esp); } @@ -722,3 +725,9 @@ } return 0; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/arch/i386/kernel/sys_i386.c linux-2.4.25-cher1/arch/i386/kernel/sys_i386.c --- linux-2.4.25/arch/i386/kernel/sys_i386.c 2003-08-25 15:44:39.000000000 +0400 +++ linux-2.4.25-cher1/arch/i386/kernel/sys_i386.c 2004-02-20 18:14:16.000000000 +0300 @@ -31,6 +31,9 @@ int fd[2]; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = do_pipe(fd); if (!error) { if (copy_to_user(fildes, fd, 2*sizeof(int))) @@ -69,6 +72,11 @@ unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) { + if (!capable(CAP_SYS_OPERATIONS)) { + if (!(flags & MAP_ANONYMOUS)) return -EPERM; + fd = -1; + } + return do_mmap2(addr, len, prot, flags, fd, pgoff); } @@ -100,6 +108,11 @@ if (a.offset & ~PAGE_MASK) goto out; + if (!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; @@ -118,6 +131,9 @@ { struct sel_arg_struct a; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (copy_from_user(&a, arg, sizeof(a))) return -EFAULT; /* sys_select() does the appropriate kernel locking */ @@ -134,6 +150,9 @@ { int version, ret; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; @@ -213,6 +232,10 @@ asmlinkage int sys_uname(struct old_utsname * name) { int err; + + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (!name) return -EFAULT; down_read(&uts_sem); @@ -225,6 +248,9 @@ { int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (!name) return -EFAULT; if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) @@ -252,8 +278,16 @@ asmlinkage int sys_pause(void) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + current->state = TASK_INTERRUPTIBLE; schedule(); return -ERESTARTNOHAND; } +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/arch/i386/kernel/vm86.c linux-2.4.25-cher1/arch/i386/kernel/vm86.c --- linux-2.4.25/arch/i386/kernel/vm86.c 2003-08-25 15:44:39.000000000 +0400 +++ linux-2.4.25-cher1/arch/i386/kernel/vm86.c 2004-02-20 18:14:16.000000000 +0300 @@ -167,6 +167,9 @@ struct task_struct *tsk; int tmp, ret = -EPERM; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + tsk = current; if (tsk->thread.saved_esp0) goto out; @@ -196,6 +199,9 @@ struct task_struct *tsk; int tmp, ret; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + tsk = current; switch (subfunction) { case VM86_REQUEST_IRQ: @@ -787,3 +793,8 @@ return -EINVAL; } +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/fs/buffer.c linux-2.4.25-cher1/fs/buffer.c --- linux-2.4.25/fs/buffer.c 2004-02-18 16:36:31.000000000 +0300 +++ linux-2.4.25-cher1/fs/buffer.c 2004-02-20 18:14:16.000000000 +0300 @@ -421,6 +421,9 @@ asmlinkage long sys_sync(void) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + fsync_dev(0); return 0; } @@ -461,6 +464,12 @@ struct inode * inode; int ret, err; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + ret = -EBADF; file = fget(fd); if (!file) @@ -3142,3 +3151,8 @@ module_init(bdflush_init) +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/fs/dcache.c linux-2.4.25-cher1/fs/dcache.c --- linux-2.4.25/fs/dcache.c 2003-06-13 18:51:37.000000000 +0400 +++ linux-2.4.25-cher1/fs/dcache.c 2004-02-20 18:14:16.000000000 +0300 @@ -1021,8 +1021,12 @@ int error; struct vfsmount *pwdmnt, *rootmnt; struct dentry *pwd, *root; - char *page = (char *) __get_free_page(GFP_USER); + char *page; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + + page = (char *) __get_free_page(GFP_USER); if (!page) return -ENOMEM; @@ -1298,3 +1302,9 @@ cdev_cache_init(); iobuf_cache_init(); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/fs/dquot.c linux-2.4.25-cher1/fs/dquot.c --- linux-2.4.25/fs/dquot.c 2004-02-18 16:36:31.000000000 +0300 +++ linux-2.4.25-cher1/fs/dquot.c 2004-02-20 18:14:16.000000000 +0300 @@ -1263,6 +1263,9 @@ int cnt; struct quota_info *dqopt = sb_dqopt(sb); + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + lock_kernel(); if (!sb) goto out; diff -ruN linux-2.4.25/fs/exec.c linux-2.4.25-cher1/fs/exec.c --- linux-2.4.25/fs/exec.c 2004-02-20 18:13:40.000000000 +0300 +++ linux-2.4.25-cher1/fs/exec.c 2004-02-20 18:14:16.000000000 +0300 @@ -114,6 +114,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk(library, &nd); if (error) goto out; @@ -1181,3 +1184,9 @@ unlock_kernel(); return retval; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/fs/fcntl.c linux-2.4.25-cher1/fs/fcntl.c --- linux-2.4.25/fs/fcntl.c 2003-11-28 21:26:21.000000000 +0300 +++ linux-2.4.25-cher1/fs/fcntl.c 2004-02-20 18:14:16.000000000 +0300 @@ -142,6 +142,9 @@ struct file * file, *tofree; struct files_struct * files = current->files; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + write_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 (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + file = fget(fildes); if (file) ret = dupfd(file, 0); return ret; @@ -342,6 +349,9 @@ struct file * filp; long err = -EBADF; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + filp = fget(fd); if (!filp) goto out; @@ -359,6 +369,9 @@ struct file * filp; long err; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + err = -EBADF; filp = fget(fd); if (!filp) @@ -539,3 +552,9 @@ } module_init(fasync_init) + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/fs/filesystems.c linux-2.4.25-cher1/fs/filesystems.c --- linux-2.4.25/fs/filesystems.c 2002-08-03 04:39:45.000000000 +0400 +++ linux-2.4.25-cher1/fs/filesystems.c 2004-02-20 18:14:16.000000000 +0300 @@ -21,6 +21,9 @@ { int ret = -ENOSYS; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + #if defined(CONFIG_MODULES) lock_kernel(); @@ -38,3 +41,9 @@ EXPORT_SYMBOL(nfsd_linkage); #endif /* CONFIG_NFSD */ + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/fs/ioctl.c linux-2.4.25-cher1/fs/ioctl.c --- linux-2.4.25/fs/ioctl.c 2003-08-25 15:44:43.000000000 +0400 +++ linux-2.4.25-cher1/fs/ioctl.c 2004-02-20 18:14:16.000000000 +0300 @@ -52,6 +52,9 @@ unsigned int flag; int on, error = -EBADF; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + filp = fget(fd); if (!filp) goto out; @@ -124,3 +127,9 @@ out: return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/fs/locks.c linux-2.4.25-cher1/fs/locks.c --- linux-2.4.25/fs/locks.c 2004-02-18 16:36:31.000000000 +0300 +++ linux-2.4.25-cher1/fs/locks.c 2004-02-20 18:14:16.000000000 +0300 @@ -1376,6 +1376,9 @@ struct file *filp; int error, type; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = -EBADF; filp = fget(fd); if (!filp) @@ -2033,3 +2036,9 @@ } module_init(filelock_init) + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/fs/namei.c linux-2.4.25-cher1/fs/namei.c --- linux-2.4.25/fs/namei.c 2004-02-20 18:13:40.000000000 +0300 +++ linux-2.4.25-cher1/fs/namei.c 2004-02-20 18:14:16.000000000 +0300 @@ -1341,6 +1341,9 @@ struct dentry * dentry; struct nameidata nd; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (S_ISDIR(mode)) return -EPERM; tmp = getname(filename); @@ -1409,6 +1412,9 @@ int error = 0; char * tmp; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + tmp = getname(pathname); error = PTR_ERR(tmp); if (!IS_ERR(tmp)) { @@ -1507,6 +1513,9 @@ struct dentry *dentry; struct nameidata nd; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + name = getname(pathname); if(IS_ERR(name)) return PTR_ERR(name); @@ -1575,6 +1584,9 @@ struct dentry *dentry; struct nameidata nd; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + name = getname(pathname); if(IS_ERR(name)) return PTR_ERR(name); @@ -1641,6 +1653,9 @@ char * from; char * to; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + from = getname(oldname); if(IS_ERR(from)) return PTR_ERR(from); @@ -1748,6 +1763,9 @@ int error; char * to; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + to = getname(newname); error = PTR_ERR(to); if (!IS_ERR(to)) { @@ -2021,6 +2039,9 @@ char * from; char * to; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + from = getname(oldname); if(IS_ERR(from)) return PTR_ERR(from); @@ -2143,3 +2164,9 @@ readlink: page_readlink, follow_link: page_follow_link, }; + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/fs/namespace.c linux-2.4.25-cher1/fs/namespace.c --- linux-2.4.25/fs/namespace.c 2004-02-18 16:36:31.000000000 +0300 +++ linux-2.4.25-cher1/fs/namespace.c 2004-02-20 18:14:16.000000000 +0300 @@ -366,6 +366,9 @@ struct nameidata nd; int retval; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + retval = __user_walk(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &nd); if (retval) goto out; @@ -835,6 +838,9 @@ unsigned long dev_page; char *dir_page; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + retval = copy_mount_options (type, &type_page); if (retval < 0) return retval; @@ -1071,3 +1077,9 @@ init_rootfs(); init_mount_tree(); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/fs/open.c linux-2.4.25-cher1/fs/open.c --- linux-2.4.25/fs/open.c 2004-02-18 16:36:31.000000000 +0300 +++ linux-2.4.25-cher1/fs/open.c 2004-02-20 18:14:16.000000000 +0300 @@ -42,6 +42,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk(path, &nd); if (!error) { struct statfs tmp; @@ -59,6 +62,9 @@ struct statfs tmp; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = -EBADF; file = fget(fd); if (!file) @@ -121,6 +127,9 @@ struct inode * inode; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = -EINVAL; if (length < 0) /* sorry, but loff_t says... */ goto out; @@ -188,6 +197,9 @@ struct file * file; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = -EINVAL; if (length < 0) goto out; @@ -262,6 +274,9 @@ struct inode * inode; struct iattr newattrs; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk(filename, &nd); if (error) goto out; @@ -312,6 +327,9 @@ struct inode * inode; struct iattr newattrs; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk(filename, &nd); if (error) @@ -363,6 +381,9 @@ kernel_cap_t old_cap; int res; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL; @@ -401,6 +422,9 @@ int error; struct nameidata nd; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd); if (error) goto out; @@ -425,6 +449,9 @@ struct vfsmount *mnt; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = -EBADF; file = fget(fd); if (!file) @@ -452,6 +479,9 @@ int error; struct nameidata nd; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); if (error) @@ -482,6 +512,9 @@ int err = -EBADF; struct iattr newattrs; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + file = fget(fd); if (!file) goto out; @@ -514,6 +547,9 @@ int error; struct iattr newattrs; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk(filename, &nd); if (error) goto out; @@ -604,6 +640,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk(filename, &nd); if (!error) { error = chown_common(nd.dentry, user, group); @@ -617,6 +656,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk_link(filename, &nd); if (!error) { error = chown_common(nd.dentry, user, group); @@ -631,6 +673,9 @@ struct file * file; int error = -EBADF; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + file = fget(fd); if (file) { error = chown_common(file->f_dentry, user, group); @@ -805,6 +850,13 @@ #endif tmp = getname(filename); 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 == '/') return -EPERM; + flags &= ~(O_CREAT | O_EXCL); + } if (!IS_ERR(tmp)) { fd = get_unused_fd(); if (fd >= 0) { @@ -895,6 +947,9 @@ */ asmlinkage long sys_vhangup(void) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (capable(CAP_SYS_TTY_CONFIG)) { tty_vhangup(current->tty); return 0; @@ -916,3 +971,9 @@ } EXPORT_SYMBOL(generic_file_open); + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruN linux-2.4.25/fs/read_write.c linux-2.4.25-cher1/fs/read_write.c --- linux-2.4.25/fs/read_write.c 2003-08-25 15:44:43.000000000 +0400 +++ linux-2.4.25-cher1/fs/read_write.c 2004-02-20 18:14:16.000000000 +0300 @@ -110,6 +110,11 @@ off_t retval; struct file * file; + /* + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + */ + retval = -EBADF; file = fget(fd); if (!file) @@ -135,6 +140,11 @@ struct file * file; loff_t offset; + /* + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + */ + retval = -EBADF; file = fget(fd); if (!file) @@ -377,6 +387,9 @@ struct file * file; ssize_t (*read)(struct file *, char *, size_t, loff_t *); + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + ret = -EBADF; file = fget(fd); if (!file) @@ -408,6 +421,9 @@ struct file * file; ssize_t (*write)(struct file *, const char *, size_t, loff_t *); + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + ret = -EBADF; file = fget(fd); if (!file) @@ -432,3 +448,9 @@ bad_file: return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/fs/readdir.c linux-2.4.25-cher1/fs/readdir.c --- linux-2.4.25/fs/readdir.c 2004-02-18 16:36:31.000000000 +0300 +++ linux-2.4.25-cher1/fs/readdir.c 2004-02-20 18:14:16.000000000 +0300 @@ -208,6 +208,9 @@ struct file * file; struct readdir_callback buf; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = -EBADF; file = fget(fd); if (!file) @@ -277,6 +280,9 @@ struct getdents_callback buf; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = -EBADF; file = fget(fd); if (!file) @@ -360,6 +366,9 @@ struct getdents_callback64 buf; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = -EBADF; file = fget(fd); if (!file) @@ -387,3 +396,9 @@ out: return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/fs/stat.c linux-2.4.25-cher1/fs/stat.c --- linux-2.4.25/fs/stat.c 2004-02-18 16:36:31.000000000 +0300 +++ linux-2.4.25-cher1/fs/stat.c 2004-02-20 18:14:16.000000000 +0300 @@ -139,6 +139,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk(filename, &nd); if (!error) { error = do_revalidate(nd.dentry); @@ -155,6 +158,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk(filename, &nd); if (!error) { error = do_revalidate(nd.dentry); @@ -176,6 +182,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk_link(filename, &nd); if (!error) { error = do_revalidate(nd.dentry); @@ -193,6 +202,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk_link(filename, &nd); if (!error) { error = do_revalidate(nd.dentry); @@ -214,6 +226,9 @@ struct file * f; int err = -EBADF; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + f = fget(fd); if (f) { struct dentry * dentry = f->f_dentry; @@ -233,6 +248,9 @@ struct file * f; int err = -EBADF; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + f = fget(fd); if (f) { struct dentry * dentry = f->f_dentry; @@ -250,6 +268,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (bufsiz <= 0) return -EINVAL; @@ -336,6 +357,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk(filename, &nd); if (!error) { error = do_revalidate(nd.dentry); @@ -351,6 +375,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk_link(filename, &nd); if (!error) { error = do_revalidate(nd.dentry); @@ -366,6 +393,9 @@ struct file * f; int err = -EBADF; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + f = fget(fd); if (f) { struct dentry * dentry = f->f_dentry; @@ -379,3 +409,9 @@ } #endif /* LFS-64 */ + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/fs/super.c linux-2.4.25-cher1/fs/super.c --- linux-2.4.25/fs/super.c 2003-08-25 15:44:43.000000000 +0400 +++ linux-2.4.25-cher1/fs/super.c 2004-02-20 18:14:16.000000000 +0300 @@ -203,6 +203,9 @@ { int retval = -EINVAL; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + switch (option) { case 1: retval = fs_index((const char *) arg1); @@ -519,6 +522,9 @@ struct statfs sbuf; int err = -EINVAL; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + s = get_super(to_kdev_t(dev)); if (s == NULL) goto out; @@ -867,3 +873,9 @@ { return do_kern_mount(type->name, 0, (char *)type->name, NULL); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/fs/xattr.c linux-2.4.25-cher1/fs/xattr.c --- linux-2.4.25/fs/xattr.c 2002-11-29 02:53:15.000000000 +0300 +++ linux-2.4.25-cher1/fs/xattr.c 2004-02-20 18:14:16.000000000 +0300 @@ -101,6 +101,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk(path, &nd); if (error) return error; @@ -115,6 +118,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk_link(path, &nd); if (error) return error; @@ -129,6 +135,9 @@ struct file *f; int error = -EBADF; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + f = fget(fd); if (!f) return error; @@ -179,6 +188,9 @@ struct nameidata nd; ssize_t error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk(path, &nd); if (error) return error; @@ -193,6 +205,9 @@ struct nameidata nd; ssize_t error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk_link(path, &nd); if (error) return error; @@ -207,6 +222,9 @@ struct file *f; ssize_t error = -EBADF; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + f = fget(fd); if (!f) return error; @@ -250,6 +268,9 @@ struct nameidata nd; ssize_t error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk(path, &nd); if (error) return error; @@ -264,6 +285,9 @@ struct nameidata nd; ssize_t error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk_link(path, &nd); if (error) return error; @@ -278,6 +302,9 @@ struct file *f; ssize_t error = -EBADF; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + f = fget(fd); if (!f) return error; @@ -318,6 +345,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk(path, &nd); if (error) return error; @@ -332,6 +362,9 @@ struct nameidata nd; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + error = user_path_walk_link(path, &nd); if (error) return error; @@ -346,6 +379,9 @@ struct file *f; int error = -EBADF; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + f = fget(fd); if (!f) return error; @@ -353,3 +389,9 @@ fput(f); return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/include/linux/capability.h linux-2.4.25-cher1/include/linux/capability.h --- linux-2.4.25/include/linux/capability.h 2001-11-22 22:46:19.000000000 +0300 +++ linux-2.4.25-cher1/include/linux/capability.h 2004-02-20 18:14:16.000000000 +0300 @@ -279,6 +279,16 @@ #define CAP_LEASE 28 +/* 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 @@ -339,10 +349,11 @@ 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_exec_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.4.25/kernel/capability.c linux-2.4.25-cher1/kernel/capability.c --- linux-2.4.25/kernel/capability.c 2000-06-24 08:06:37.000000000 +0400 +++ linux-2.4.25-cher1/kernel/capability.c 2004-02-20 18:14:16.000000000 +0300 @@ -133,6 +133,9 @@ struct task_struct *target; int error, pid; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (get_user(version, &header->version)) return -EFAULT; @@ -214,3 +217,9 @@ spin_unlock(&task_capability_lock); return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/kernel/exec_domain.c linux-2.4.25-cher1/kernel/exec_domain.c --- linux-2.4.25/kernel/exec_domain.c 2003-08-25 15:44:44.000000000 +0400 +++ linux-2.4.25-cher1/kernel/exec_domain.c 2004-02-20 18:14:16.000000000 +0300 @@ -219,6 +219,9 @@ { u_long old = current->personality;; + if (!capable(CAP_SYS_OPERATIONS) && personality != PER_LINUX) + return -EPERM; + if (personality != 0xffffffff) { set_personality(personality); if (current->personality != personality) @@ -288,3 +291,9 @@ EXPORT_SYMBOL(abi_defhandler_libcso); EXPORT_SYMBOL(abi_traceflg); EXPORT_SYMBOL(abi_fake_utsname); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/kernel/exit.c linux-2.4.25-cher1/kernel/exit.c --- linux-2.4.25/kernel/exit.c 2004-02-20 18:13:40.000000000 +0300 +++ linux-2.4.25-cher1/kernel/exit.c 2004-02-20 18:14:16.000000000 +0300 @@ -501,6 +501,9 @@ DECLARE_WAITQUEUE(wait, current); struct task_struct *tsk; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (options & ~(WNOHANG|WUNTRACED|__WNOTHREAD|__WCLONE|__WALL)) return -EINVAL; @@ -605,3 +608,9 @@ } #endif + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/kernel/fork.c linux-2.4.25-cher1/kernel/fork.c --- linux-2.4.25/kernel/fork.c 2004-02-18 16:36:32.000000000 +0300 +++ linux-2.4.25-cher1/kernel/fork.c 2004-02-20 18:14:16.000000000 +0300 @@ -642,6 +642,9 @@ struct task_struct *p; struct completion vfork; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS)) return -EINVAL; @@ -891,3 +894,9 @@ if(!mm_cachep) panic("vma_init: Cannot alloc mm_struct SLAB cache"); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruN linux-2.4.25/kernel/info.c linux-2.4.25-cher1/kernel/info.c --- linux-2.4.25/kernel/info.c 2001-04-21 03:15:40.000000000 +0400 +++ linux-2.4.25-cher1/kernel/info.c 2004-02-20 18:14:16.000000000 +0300 @@ -17,6 +17,9 @@ { struct sysinfo val; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + memset((char *)&val, 0, sizeof(struct sysinfo)); cli(); @@ -77,3 +80,9 @@ return -EFAULT; return 0; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruN linux-2.4.25/kernel/module.c linux-2.4.25-cher1/kernel/module.c --- linux-2.4.25/kernel/module.c 2003-08-25 15:44:44.000000000 +0400 +++ linux-2.4.25-cher1/kernel/module.c 2004-02-20 18:14:16.000000000 +0300 @@ -900,6 +900,9 @@ struct module *mod; int err; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + lock_kernel(); if (name_user == NULL) mod = &kernel_module; @@ -969,6 +972,9 @@ int i; struct kernel_sym ksym; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + lock_kernel(); for (mod = module_list, i = 0; mod; mod = mod->next) { /* include the count for the module name! */ @@ -1294,3 +1300,9 @@ } #endif /* CONFIG_MODULES */ + +/** + * Local variables: + * c-basic-offset: 8 + * End: +*/ diff -ruN linux-2.4.25/kernel/printk.c linux-2.4.25-cher1/kernel/printk.c --- linux-2.4.25/kernel/printk.c 2004-02-20 18:13:40.000000000 +0300 +++ linux-2.4.25-cher1/kernel/printk.c 2004-02-20 18:14:16.000000000 +0300 @@ -305,6 +305,10 @@ if ((type != 3) && !capable(CAP_SYS_ADMIN)) return -EPERM; #endif + + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + return do_syslog(type, buf, len); } @@ -701,3 +705,9 @@ tty->driver.write(tty, 0, msg, strlen(msg)); return; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/kernel/sched.c linux-2.4.25-cher1/kernel/sched.c --- linux-2.4.25/kernel/sched.c 2003-11-28 21:26:21.000000000 +0300 +++ linux-2.4.25-cher1/kernel/sched.c 2004-02-20 18:14:16.000000000 +0300 @@ -1395,3 +1395,9 @@ atomic_inc(&init_mm.mm_count); enter_lazy_tlb(&init_mm, current, cpu); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/kernel/signal.c linux-2.4.25-cher1/kernel/signal.c --- linux-2.4.25/kernel/signal.c 2004-02-18 16:36:32.000000000 +0300 +++ linux-2.4.25-cher1/kernel/signal.c 2004-02-20 18:14:16.000000000 +0300 @@ -667,6 +667,13 @@ read_lock(&tasklist_lock); p = find_task_by_pid(pid); + + /* thread group id must match */ + if (!capable(CAP_SYS_OPERATIONS) && p->tgid != current->tgid) { + read_unlock(&tasklist_lock); + return -EPERM; + } + error = -ESRCH; if (p) { if (!thread_group_leader(p)) { @@ -691,6 +698,20 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) { + if (!capable(CAP_SYS_OPERATIONS)) { + /* never allow signal sending to process group */ + if (!pid) { + pid = current->pid; + } else if (pid == -1) { + return -EPERM; + } else if (pid < 0) { + if (current->pgrp != -pid) + return -EPERM; + pid = current->pid; + } + /* further restrictions are in kill_proc_info */ + } + if (!pid) { return kill_pg_info(sig, info, current->pgrp); } else if (pid == -1) { @@ -1046,6 +1067,13 @@ read_lock(&tasklist_lock); p = find_task_by_pid(pid); + + /* allow signal sending to the processes of the same thread group */ + if (!capable(CAP_SYS_OPERATIONS) && p->tgid != current->tgid) { + read_unlock(&tasklist_lock); + return -EPERM; + } + error = -ESRCH; if (p) { error = send_sig_info(sig, &info, p); @@ -1323,3 +1351,9 @@ return ret ? ret : (unsigned long)old_sa.sa.sa_handler; } #endif /* !alpha && !__ia64__ && !defined(__mips__) */ + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/kernel/sys.c linux-2.4.25-cher1/kernel/sys.c --- linux-2.4.25/kernel/sys.c 2003-11-28 21:26:21.000000000 +0300 +++ linux-2.4.25-cher1/kernel/sys.c 2004-02-20 18:14:16.000000000 +0300 @@ -290,6 +290,9 @@ { char buffer[256]; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + /* We only trust the superuser with rebooting the system. */ if (!capable(CAP_SYS_BOOT)) return -EPERM; @@ -399,6 +402,9 @@ int new_rgid = old_rgid; int new_egid = old_egid; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (rgid != (gid_t) -1) { if ((old_rgid == rgid) || (current->egid==rgid) || @@ -440,6 +446,9 @@ { int old_egid = current->egid; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (capable(CAP_SETGID)) { if(old_egid != gid) @@ -550,6 +559,9 @@ new_euid = old_euid = current->euid; old_suid = current->suid; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (ruid != (uid_t) -1) { new_ruid = ruid; if ((old_ruid != ruid) && @@ -606,6 +618,9 @@ int old_euid = current->euid; int old_ruid, old_suid, new_ruid, new_suid; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + old_ruid = new_ruid = current->uid; old_suid = current->suid; new_suid = old_suid; @@ -643,6 +658,9 @@ int old_euid = current->euid; int old_suid = current->suid; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (!capable(CAP_SETUID)) { if ((ruid != (uid_t) -1) && (ruid != current->uid) && (ruid != current->euid) && (ruid != current->suid)) @@ -681,6 +699,9 @@ { int retval; + if (!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); @@ -693,6 +714,9 @@ */ asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (!capable(CAP_SETGID)) { if ((rgid != (gid_t) -1) && (rgid != current->gid) && (rgid != current->egid) && (rgid != current->sgid)) @@ -724,6 +748,9 @@ { int retval; + if (!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); @@ -742,6 +769,9 @@ { int old_fsuid; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + old_fsuid = current->fsuid; if (uid == current->uid || uid == current->euid || uid == current->suid || uid == current->fsuid || @@ -784,6 +814,9 @@ { int old_fsgid; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + old_fsgid = current->fsgid; if (gid == current->gid || gid == current->egid || gid == current->sgid || gid == current->fsgid || @@ -831,6 +864,9 @@ struct task_struct * p; int err = -EINVAL; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (!pid) pid = current->pid; if (!pgid) @@ -906,6 +942,9 @@ asmlinkage long sys_getsid(pid_t pid) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (!pid) { return current->session; } else { @@ -928,6 +967,9 @@ struct task_struct * p; int err = -EPERM; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + read_lock(&tasklist_lock); for_each_task(p) { if (p->pgrp == current->pid) @@ -956,6 +998,9 @@ * safe. */ + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (gidsetsize < 0) return -EINVAL; i = current->ngroups; @@ -975,6 +1020,9 @@ asmlinkage long sys_setgroups(int gidsetsize, gid_t *grouplist) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (!capable(CAP_SETGID)) return -EPERM; if ((unsigned) gidsetsize > NGROUPS) @@ -1130,6 +1178,9 @@ { struct rlimit new_rlim, *old_rlim; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (resource >= RLIM_NLIMITS) return -EINVAL; if(copy_from_user(&new_rlim, rlim, sizeof(*rlim))) @@ -1212,6 +1263,9 @@ asmlinkage long sys_umask(int mask) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + mask = xchg(¤t->fs->umask, mask & S_IRWXUGO); return mask; } @@ -1222,6 +1276,9 @@ int error = 0; int sig; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + switch (option) { case PR_SET_PDEATHSIG: sig = arg2; @@ -1290,3 +1347,9 @@ EXPORT_SYMBOL(unregister_reboot_notifier); EXPORT_SYMBOL(in_group_p); EXPORT_SYMBOL(in_egroup_p); + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/kernel/sysctl.c linux-2.4.25-cher1/kernel/sysctl.c --- linux-2.4.25/kernel/sysctl.c 2004-02-20 18:13:40.000000000 +0300 +++ linux-2.4.25-cher1/kernel/sysctl.c 2004-02-20 18:14:16.000000000 +0300 @@ -400,6 +400,9 @@ struct __sysctl_args tmp; int error; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (copy_from_user(&tmp, args, sizeof(tmp))) return -EFAULT; @@ -1525,3 +1528,9 @@ } #endif /* CONFIG_SYSCTL */ + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/kernel/timer.c linux-2.4.25-cher1/kernel/timer.c --- linux-2.4.25/kernel/timer.c 2002-11-29 02:53:15.000000000 +0300 +++ linux-2.4.25-cher1/kernel/timer.c 2004-02-20 18:14:16.000000000 +0300 @@ -784,6 +784,9 @@ struct task_struct * me = current; struct task_struct * parent; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + parent = me->p_opptr; for (;;) { pid = parent->pid; @@ -874,3 +877,8 @@ return 0; } +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/kernel/uid16.c linux-2.4.25-cher1/kernel/uid16.c --- linux-2.4.25/kernel/uid16.c 2000-01-11 05:40:26.000000000 +0300 +++ linux-2.4.25-cher1/kernel/uid16.c 2004-02-20 18:14:16.000000000 +0300 @@ -29,41 +29,65 @@ asmlinkage long sys_chown16(const char * filename, old_uid_t user, old_gid_t group) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + return sys_chown(filename, low2highuid(user), low2highgid(group)); } asmlinkage long sys_lchown16(const char * filename, old_uid_t user, old_gid_t group) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + return sys_lchown(filename, low2highuid(user), low2highgid(group)); } asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + return sys_fchown(fd, low2highuid(user), low2highgid(group)); } asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + return sys_setregid(low2highgid(rgid), low2highgid(egid)); } asmlinkage long sys_setgid16(old_gid_t gid) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + return sys_setgid((gid_t)gid); } asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + return sys_setreuid(low2highuid(ruid), low2highuid(euid)); } asmlinkage long sys_setuid16(old_uid_t uid) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + return sys_setuid((uid_t)uid); } asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + return sys_setresuid(low2highuid(ruid), low2highuid(euid), low2highuid(suid)); } @@ -81,6 +105,9 @@ asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + return sys_setresgid(low2highgid(rgid), low2highgid(egid), low2highgid(sgid)); } @@ -98,11 +125,17 @@ asmlinkage long sys_setfsuid16(old_uid_t uid) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + return sys_setfsuid((uid_t)uid); } asmlinkage long sys_setfsgid16(old_gid_t gid) { + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + return sys_setfsgid((gid_t)gid); } @@ -111,6 +144,9 @@ old_gid_t groups[NGROUPS]; int i,j; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (gidsetsize < 0) return -EINVAL; i = current->ngroups; @@ -130,6 +166,9 @@ old_gid_t groups[NGROUPS]; int i; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (!capable(CAP_SETGID)) return -EPERM; if ((unsigned) gidsetsize > NGROUPS) @@ -161,3 +200,9 @@ { return high2lowgid(current->egid); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/mm/filemap.c linux-2.4.25-cher1/mm/filemap.c --- linux-2.4.25/mm/filemap.c 2004-02-18 16:36:32.000000000 +0300 +++ linux-2.4.25-cher1/mm/filemap.c 2004-02-20 18:14:16.000000000 +0300 @@ -1854,6 +1854,9 @@ struct file * in_file, * out_file; struct inode * in_inode, * out_inode; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + /* * Get input file, and verify that it is ok.. */ @@ -1982,6 +1985,9 @@ ssize_t ret; struct file *file; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + ret = -EBADF; file = fget(fd); if (file) { @@ -2383,6 +2389,9 @@ struct vm_area_struct * vma; int unmapped_error, error = -EINVAL; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + down_read(¤t->mm->mmap_sem); if (start & ~PAGE_MASK) goto out; @@ -2735,6 +2744,9 @@ int unmapped_error = 0; int error = -EINVAL; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + down_write(¤t->mm->mmap_sem); if (start & ~PAGE_MASK) @@ -2888,6 +2900,9 @@ int unmapped_error = 0; long error = -EINVAL; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + down_read(¤t->mm->mmap_sem); if (start & ~PAGE_CACHE_MASK) @@ -3408,3 +3423,9 @@ panic("Failed to allocate page hash table\n"); memset((void *)page_hash_table, 0, PAGE_HASH_SIZE * sizeof(struct page *)); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/mm/mlock.c linux-2.4.25-cher1/mm/mlock.c --- linux-2.4.25/mm/mlock.c 2001-09-18 02:30:23.000000000 +0400 +++ linux-2.4.25-cher1/mm/mlock.c 2004-02-20 18:14:16.000000000 +0300 @@ -198,6 +198,9 @@ unsigned long lock_limit; int error = -ENOMEM; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + down_write(¤t->mm->mmap_sem); len = PAGE_ALIGN(len + (start & ~PAGE_MASK)); start &= PAGE_MASK; @@ -227,6 +230,9 @@ { int ret; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + down_write(¤t->mm->mmap_sem); len = PAGE_ALIGN(len + (start & ~PAGE_MASK)); start &= PAGE_MASK; @@ -268,6 +274,9 @@ unsigned long lock_limit; int ret = -EINVAL; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + down_write(¤t->mm->mmap_sem); if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE))) goto out; @@ -294,8 +303,17 @@ { int ret; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + down_write(¤t->mm->mmap_sem); ret = do_mlockall(0); up_write(¤t->mm->mmap_sem); return ret; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/mm/mmap.c linux-2.4.25-cher1/mm/mmap.c --- linux-2.4.25/mm/mmap.c 2004-02-20 18:13:40.000000000 +0300 +++ linux-2.4.25-cher1/mm/mmap.c 2004-02-20 18:14:16.000000000 +0300 @@ -1030,6 +1030,11 @@ int ret; struct mm_struct *mm = current->mm; + /* + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + */ + down_write(&mm->mmap_sem); ret = do_munmap(mm, addr, len); up_write(&mm->mmap_sem); @@ -1209,3 +1214,9 @@ vma_link(mm, vma, prev, rb_link, rb_parent); validate_mm(mm); } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/mm/mprotect.c linux-2.4.25-cher1/mm/mprotect.c --- linux-2.4.25/mm/mprotect.c 2003-11-28 21:26:21.000000000 +0300 +++ linux-2.4.25-cher1/mm/mprotect.c 2004-02-20 18:14:16.000000000 +0300 @@ -270,6 +270,9 @@ struct vm_area_struct * vma, * next, * prev; int error = -EINVAL; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (start & ~PAGE_MASK) return -EINVAL; len = PAGE_ALIGN(len); @@ -335,3 +338,9 @@ up_write(¤t->mm->mmap_sem); return error; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -ruN linux-2.4.25/mm/mremap.c linux-2.4.25-cher1/mm/mremap.c --- linux-2.4.25/mm/mremap.c 2004-02-20 18:13:40.000000000 +0300 +++ linux-2.4.25-cher1/mm/mremap.c 2004-02-20 18:14:16.000000000 +0300 @@ -372,8 +372,19 @@ { unsigned long ret; + /* + if (!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.4.25/net/socket.c linux-2.4.25-cher1/net/socket.c --- linux-2.4.25/net/socket.c 2004-02-20 18:13:40.000000000 +0300 +++ linux-2.4.25-cher1/net/socket.c 2004-02-20 18:14:16.000000000 +0300 @@ -903,6 +903,9 @@ int retval; struct socket *sock; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + retval = sock_create(family, type, protocol, &sock); if (retval < 0) goto out; @@ -929,6 +932,9 @@ struct socket *sock1, *sock2; int fd1, fd2, err; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + /* * Obtain the first socket and check if the underlying protocol * supports the socketpair call. @@ -1000,6 +1006,9 @@ char address[MAX_SOCK_ADDR]; int err; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if((sock = sockfd_lookup(fd,&err))!=NULL) { if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) @@ -1023,6 +1032,9 @@ struct socket *sock; int err; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if ((sock = sockfd_lookup(fd, &err)) != NULL) { if ((unsigned) backlog > sysctl_somaxconn) backlog = sysctl_somaxconn; @@ -1051,6 +1063,9 @@ int err, len; char address[MAX_SOCK_ADDR]; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1110,6 +1125,9 @@ char address[MAX_SOCK_ADDR]; int err; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1135,6 +1153,9 @@ char address[MAX_SOCK_ADDR]; int len, err; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1160,6 +1181,9 @@ char address[MAX_SOCK_ADDR]; int len, err; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if ((sock = sockfd_lookup(fd, &err))!=NULL) { err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 1); @@ -1185,6 +1209,9 @@ struct msghdr msg; struct iovec iov; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1239,6 +1266,9 @@ char address[MAX_SOCK_ADDR]; int err,err2; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + sock = sockfd_lookup(fd, &err); if (!sock) goto out; @@ -1285,6 +1315,9 @@ int err; struct socket *sock; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if (optlen < 0) return -EINVAL; @@ -1310,6 +1343,9 @@ int len; struct socket *sock; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if ((sock = sockfd_lookup(fd, &err))!=NULL) { /* XXX: insufficient for SMP, but should be redundant anyway */ @@ -1338,6 +1374,9 @@ int err; struct socket *sock; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if ((sock = sockfd_lookup(fd, &err))!=NULL) { err=sock->ops->shutdown(sock, how); @@ -1360,6 +1399,9 @@ struct msghdr msg_sys; int err, ctl_len, iov_size, total_len; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + err = -EFAULT; if (copy_from_user(&msg_sys,msg,sizeof(struct msghdr))) goto out; @@ -1444,6 +1486,9 @@ struct sockaddr *uaddr; int *uaddr_len; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + err=-EFAULT; if (copy_from_user(&msg_sys,msg,sizeof(struct msghdr))) goto out; @@ -1549,6 +1594,9 @@ unsigned long a0,a1; int err; + if (!capable(CAP_SYS_OPERATIONS)) + return -EPERM; + if(call<1||call>SYS_RECVMSG) return -EINVAL; @@ -1764,3 +1812,9 @@ len = 0; return len; } + +/** + * Local variables: + * c-basic-offset: 8 + * End: + */