"Fossies" - the Fresh Open Source Software Archive

Member "sysmask-1.08/linux/sysmask.c" (29 Jan 2006, 43698 Bytes) of package /linux/misc/old/sysmask-1.08.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sysmask.c" see the Fossies "Dox" file reference documentation.

    1 /* Main sysmask file.
    2  * 
    3  * Copyright: (C) 2005 Gang Xiao <xiao@unice.fr>
    4  */
    5 
    6 /* #define SMK_DISABLE 1 */
    7 
    8 #define _SYSMASK_C
    9 
   10 #include <linux/sys.h>
   11 #include <asm/unistd.h>
   12 #include <linux/sched.h>
   13 #include <linux/file.h>
   14 #include <asm/uaccess.h>
   15 #include <linux/fs.h>
   16 #include <linux/mount.h>
   17 #include <linux/mm.h>
   18 #include <linux/sysmask.h>
   19 #include <linux/version.h>
   20 
   21 #if LINUX_VERSION_CODE < 0x20500
   22 # define LINUX_2_4 1
   23 #else
   24 # define LINUX_2_6 1
   25 # include <linux/namei.h>
   26 #endif
   27 
   28 extern int sys_kill(int pid, int sig);
   29 
   30 int sysmask_tab[]={
   31 SM1_NEW,        /* 0, __NR_restart_syscall, sys_restart_syscall */
   32 0,          /* __NR_exit, sys_exit */
   33 SM1_FORK,       /* __NR_fork, sys_fork */
   34 0,          /* __NR_read, sys_read */
   35 0,          /* __NR_write, sys_write */
   36 SM1_OPEN,       /* __NR_open, sys_open */
   37 0,          /* __NR_close, sys_close */
   38 SM1_FORK,       /* __NR_waitpid, sys_waitpid */
   39 SM1_OPEN,       /* __NR_creat, sys_creat */
   40 SM1_LINK,       /* __NR_link, sys_link */
   41 
   42 SM1_ERASE,      /* 10, __NR_unlink, sys_unlink */
   43 SM1_EXECVE,     /* __NR_execve, sys_execve */
   44 SM1_CHDIR,      /* __NR_chdir, sys_chdir */
   45 SM1_HARMLESS,       /* __NR_time, sys_time,  */
   46 SM1_MOUNT,      /* __NR_mknod, sys_mknod */
   47 SM1_CHMOD,      /* __NR_chmod, sys_chmod */
   48 SM1_ROOTMISC,       /* __NR_lchown, sys_lchown16 */
   49 SM1_NONSTD,     /* __NR_break, sys_ni_syscall */
   50 SM1_OBSOLETE|SM1_DREAD, /* __NR_oldstat, sys_stat */
   51 SM1_FNOHARM,        /* __NR_lseek, sys_lseek */
   52 
   53 SM1_HARMLESS,       /* 20, __NR_getpid, sys_getpid */
   54 SM1_MOUNT,      /* __NR_mount, sys_mount,  */
   55 SM1_MOUNT,      /* __NR_umount, sys_oldumount */
   56 0,          /* __NR_setuid, sys_setuid16 */
   57 SM1_HARMLESS,       /* __NR_getuid, sys_getuid16 */
   58 SM1_SYSADM,     /* __NR_stime, sys_stime,  */
   59 SM1_MISC,       /* __NR_ptrace, sys_ptrace */
   60 SM1_SIGNAL,     /* __NR_alarm, sys_alarm */
   61 SM1_DREAD|SM1_OBSOLETE, /* __NR_oldfstat, sys_fstat */
   62 SM1_HARMLESS,       /* __NR_pause, sys_pause */
   63 
   64 SM1_CHMOD,      /* 30, __NR_utime, sys_utime */
   65 SM1_NONSTD,     /* __NR_stty, sys_ni_syscall */
   66 SM1_NONSTD,     /* __NR_gtty, sys_ni_syscall */
   67 SM1_DREAD,      /* __NR_access, sys_access */
   68 SM1_RLIM,       /* __NR_nice, sys_nice */
   69 SM1_NONSTD,     /* __NR_ftime, sys_ni_syscall */
   70 SM1_FNOHARM,        /* __NR_sync, sys_sync */
   71 SM1_KILL,       /* __NR_kill, sys_kill */
   72 SM1_LINK,       /* __NR_rename, sys_rename */
   73 SM1_DIR,        /* __NR_mkdir, sys_mkdir */
   74 
   75 SM1_DIR|SM1_ERASE,  /* 40, __NR_rmdir, sys_rmdir */
   76 SM1_FMISC,      /* __NR_dup, sys_dup */
   77 SM1_FMISC,      /* __NR_pipe, sys_pipe */
   78 SM1_HARMLESS,       /* __NR_times, sys_times */
   79 SM1_NONSTD,     /* __NR_prof, sys_ni_syscall */
   80 SM1_BRK,        /* __NR_brk, sys_brk */
   81 0,          /* __NR_setgid, sys_setgid16 */
   82 SM1_HARMLESS,       /* __NR_getgid, sys_getgid16 */
   83 SM1_SIGNAL,     /* __NR_signal, sys_signal */
   84 SM1_HARMLESS,       /* __NR_geteuid, sys_geteuid16 */
   85 
   86 SM1_HARMLESS,       /* 50, __NR_getegid, sys_getegid16 */
   87 SM1_SYSADM,     /* __NR_acct, sys_acct */
   88 SM1_MOUNT,      /* __NR_umount2, sys_umount */
   89 SM1_NONSTD,     /* __NR_lock, sys_ni_syscall */
   90 SM1_IOCTL,      /* __NR_ioctl, sys_ioctl */
   91 SM1_OPEN|SM1_FMISC, /* __NR_fcntl, sys_fcntl */
   92 SM1_SYSMASK,        /* __NR_mpx, sys_ni_syscall */  /* Hijacked by sys_sysmask. */
   93 SM1_SPID,       /* __NR_setpgid, sys_setpgid */
   94 SM1_NONSTD,     /* __NR_ulimit, sys_ni_syscall */
   95 SM1_OBSOLETE,       /* __NR_oldolduname, sys_olduname */
   96 
   97 SM1_CHMOD,      /* 60, __NR_umask, sys_umask */
   98 SM1_CHROOT,     /* __NR_chroot, sys_chroot */
   99 SM1_FS,         /* __NR_ustat, sys_ustat */
  100 SM1_FMISC,      /* __NR_dup2, sys_dup2 */
  101 SM1_HARMLESS,       /* __NR_getppid, sys_getppid */
  102 SM1_HARMLESS,       /* __NR_getpgrp, sys_getpgrp */
  103 SM1_SPID,       /* __NR_setsid, sys_setsid */
  104 SM1_SIGNAL,     /* __NR_sigaction, sys_sigaction */
  105 SM1_SIGNAL,     /* __NR_sgetmask, sys_sgetmask */
  106 SM1_SIGNAL,     /* __NR_ssetmask, sys_ssetmask */
  107 
  108 0,          /* 70, __NR_setreuid, sys_setreuid16 */
  109 0,          /* __NR_setregid, sys_setregid16 */
  110 SM1_SIGNAL,     /* __NR_sigsuspend, sys_sigsuspend */
  111 SM1_SIGNAL,     /* __NR_sigpending, sys_sigpending */
  112 SM1_SYSADM,     /* __NR_sethostname, sys_sethostname */
  113 SM1_RLIM,       /* __NR_setrlimit, sys_setrlimit */
  114 SM1_RLIM,       /* __NR_getrlimit, sys_old_getrlimit */
  115 SM1_RLIM,       /* __NR_getrusage, sys_getrusage */
  116 SM1_HARMLESS,       /* __NR_gettimeofday, sys_gettimeofday */
  117 SM1_SYSADM,     /* __NR_settimeofday, sys_settimeofday */
  118 
  119 SM1_HARMLESS,       /* 80, __NR_getgroups, sys_getgroups16 */
  120 0,          /* __NR_setgroups, sys_setgroups16 */
  121 SM1_POLL,       /* __NR_select, old_select */
  122 SM1_LINK,       /* __NR_symlink, sys_symlink */
  123 SM1_OBSOLETE|SM1_DREAD, /* __NR_oldlstat, sys_lstat */
  124 SM1_DREAD,      /* __NR_readlink, sys_readlink */
  125 SM1_OBSOLETE,       /* __NR_uselib, sys_uselib */
  126 SM1_MOUNT,      /* __NR_swapon, sys_swapon */
  127 SM1_ROOTMISC,       /* __NR_reboot, sys_reboot */
  128 SM1_OBSOLETE,       /* __NR_readdir, old_readdir,  */
  129 
  130 SM1_MMAP,       /* 90, __NR_mmap, old_mmap */
  131 SM1_MMAP,       /* __NR_munmap, sys_munmap */
  132 SM1_ERASE,      /* __NR_truncate, sys_truncate */
  133 SM1_FMISC,      /* __NR_ftruncate, sys_ftruncate */
  134 SM1_CHMOD,      /* __NR_fchmod, sys_fchmod */
  135 SM1_ROOTMISC,       /* __NR_fchown, sys_fchown16 */
  136 SM1_RLIM,       /* __NR_getpriority, sys_getpriority */
  137 SM1_RLIM,       /* __NR_setpriority, sys_setpriority */
  138 SM1_NONSTD,     /* __NR_profil, sys_ni_syscall */
  139 SM1_FS,         /* __NR_statfs, sys_statfs */
  140 
  141 SM1_FS,         /* 100, __NR_fstatfs, sys_fstatfs */
  142 SM1_ROOTMISC|SM1_NONSTD,/* __NR_ioperm, sys_ioperm */
  143 SM1_SOCKETCALL,     /* __NR_socketcall, sys_socketcall */
  144 SM1_ROOTMISC,       /* __NR_syslog, sys_syslog */
  145 SM1_RLIM,       /* __NR_setitimer, sys_setitimer */
  146 SM1_RLIM,       /* __NR_getitimer, sys_getitimer */
  147 SM1_DREAD,      /* __NR_stat, sys_newstat */
  148 SM1_DREAD,      /* __NR_lstat, sys_newlstat */
  149 SM1_DREAD,      /* __NR_fstat, sys_newfstat */
  150 SM1_OBSOLETE,       /* __NR_olduname, sys_uname */
  151 
  152 SM1_ROOTMISC|SM1_NONSTD,/* 110, __NR_iopl, sys_iopl */
  153 SM1_ROOTMISC|SM1_NONSTD,/* __NR_vhangup, sys_vhangup */
  154 SM1_NONSTD,     /* __NR_idle, sys_ni_syscall */
  155 SM1_OBSOLETE,       /* __NR_vm86old, sys_vm86old */
  156 SM1_FORK,       /* __NR_wait4, sys_wait4 */
  157 SM1_MOUNT,      /* __NR_swapoff, sys_swapoff */
  158 SM1_NONSTD,     /* __NR_sysinfo, sys_sysinfo */
  159 SM1_IPC,        /* __NR_ipc, sys_ipc */
  160 SM1_FNOHARM,        /* __NR_fsync, sys_fsync */
  161 SM1_SIGNAL,     /* __NR_sigreturn, sys_sigreturn */
  162 
  163 SM1_FORK,       /* 120, __NR_clone, sys_clone */
  164 SM1_SYSADM|SM1_NONSTD,  /* __NR_setdomainname, sys_setdomainname */
  165 SM1_HARMLESS,       /* __NR_uname, sys_newuname */
  166 SM1_LDT,        /* __NR_modify_ldt, sys_modify_ldt */
  167 SM1_SYSADM|SM1_NONSTD,  /* __NR_adjtimex, sys_adjtimex */
  168 SM1_MMAP,       /* __NR_mprotect, sys_mprotect */
  169 SM1_SIGNAL,     /* __NR_sigprocmask, sys_sigprocmask */
  170 SM1_SYSADM|SM1_NONSTD,  /* __NR_create_module, sys_create_module */
  171 SM1_SYSADM|SM1_NONSTD,  /* __NR_init_module, sys_init_module */
  172 SM1_SYSADM|SM1_NONSTD,  /* __NR_delete_module, sys_delete_module */
  173 
  174 SM1_SYSADM|SM1_NONSTD,  /* 130, __NR_get_kernel_syms, sys_get_kernel_syms */
  175 SM1_SYSADM,     /* __NR_quotactl, sys_quotactl */
  176 SM1_SPID,       /* __NR_getpgid, sys_getpgid */
  177 SM1_CHDIR,      /* __NR_fchdir, sys_fchdir */
  178 SM1_NONSTD|SM1_ROOTMISC,/* __NR_bdflush, sys_bdflush */
  179 SM1_FS,         /* __NR_sysfs, sys_sysfs */
  180 SM1_NONSTD,     /* __NR_personality, sys_personality */
  181 SM1_NONSTD,     /* __NR_afs_syscall, sys_ni_syscall */
  182 SM1_NONSTD,     /* __NR_setfsuid, sys_setfsuid16 */
  183 SM1_NONSTD,     /* __NR_setfsgid, sys_setfsgid16 */
  184 
  185 SM1_FNOHARM,        /* 140, __NR__llseek, sys_llseek */
  186 SM1_DREAD,      /* __NR_getdents, sys_getdents */
  187 SM1_POLL,       /* __NR__newselect, sys_select */
  188 SM1_FMISC,      /* __NR_flock, sys_flock */
  189 SM1_MMAP|SM1_FNOHARM,   /* __NR_msync, sys_msync */
  190 SM1_HARMLESS,       /* __NR_readv, sys_readv */
  191 SM1_HARMLESS,       /* __NR_writev, sys_writev */
  192 SM1_SPID,       /* __NR_getsid, sys_getsid */
  193 SM1_FNOHARM,        /* __NR_fdatasync, sys_fdatasync */
  194 SM1_SYSADM|SM1_NONSTD,  /* __NR_sysctl, sys_sysctl */
  195 
  196 SM1_ROOTMISC,       /* 150, __NR_mlock, sys_mlock */
  197 SM1_ROOTMISC,       /* __NR_munlock, sys_munlock */
  198 SM1_ROOTMISC,       /* __NR_mlockall, sys_mlockall */
  199 SM1_ROOTMISC,       /* __NR_munlockall, sys_munlockall */
  200 SM1_ROOTMISC,       /* __NR_sched_setparam, sys_sched_setparam */
  201 SM1_ROOTMISC,       /* __NR_sched_getparam, sys_sched_getparam */
  202 SM1_ROOTMISC,       /* __NR_sched_setscheduler, sys_sched_setscheduler */
  203 SM1_ROOTMISC,       /* __NR_sched_getscheduler, sys_sched_getscheduler */
  204 SM1_RLIM,       /* __NR_sched_yield, sys_yield */
  205 SM1_RLIM,       /* __NR_sched_get_priority_max, sys_sched_get_priority_max */
  206 
  207 SM1_RLIM,       /* 160, __NR_sched_get_priority_min, sys_sched_get_priority_min */
  208 SM1_ROOTMISC,       /* __NR_sched_rr_get_interval, sys_sched_rr_get_interval */
  209 SM1_HARMLESS,       /* __NR_nanosleep, sys_nanosleep */
  210 SM1_MMAP|SM1_NONSTD,    /* __NR_mremap, sys_mremap */
  211 SM1_NONSTD,     /* __NR_setresuid, sys_setresuid16 */
  212 SM1_NONSTD,     /* __NR_getresuid, sys_getresuid16 */
  213 SM1_NONSTD,     /* __NR_vm86, sys_vm86 */
  214 SM1_SYSADM|SM1_NONSTD,  /* __NR_query_module, sys_query_module */
  215 SM1_POLL,       /* __NR_poll, sys_poll */
  216 SM1_SYSADM|SM1_NONSTD,  /* __NR_nfsservctl, sys_nfsservctl */
  217 
  218 SM1_NONSTD,     /* 170, __NR_setresgid, sys_setresgid16 */
  219 SM1_NONSTD,     /* __NR_getresgid, sys_getresgid16 */
  220 SM1_NONSTD|SM1_KILL,    /* __NR_prctl, sys_prctl */
  221 SM1_SIGNAL,     /* __NR_rt_sigreturn, sys_rt_sigreturn */
  222 SM1_SIGNAL,     /* __NR_rt_sigaction, sys_rt_sigaction */
  223 SM1_SIGNAL,     /* __NR_rt_sigprocmask, sys_rt_sigprocmask */
  224 SM1_SIGNAL,     /* __NR_rt_sigpending, sys_rt_sigpending */
  225 SM1_SIGNAL,     /* __NR_rt_sigtimedwait, sys_rt_sigtimedwait */
  226 SM1_SIGNAL,     /* __NR_rt_sigqueueinfo, sys_rt_sigqueueinfo */
  227 SM1_SIGNAL,     /* __NR_rt_sigsuspend, sys_rt_sigsuspend */
  228 
  229 SM1_HARMLESS,       /* 180, __NR_pread64, sys_pread64 */
  230 SM1_HARMLESS,       /* __NR_pwrite64, sys_pwrite64 */
  231 SM1_ROOTMISC,       /* __NR_chown, sys_chown16 */
  232 SM1_DREAD,      /* __NR_getcwd, sys_getcwd */
  233 SM1_SYSMASK,        /* __NR_capget, sys_capget */
  234 SM1_SYSMASK,        /* __NR_capset, sys_capset */
  235 SM1_SIGNAL|SM1_NONSTD,  /* __NR_sigaltstack, sys_sigaltstack */
  236 SM1_NONSTD,     /* __NR_sendfile, sys_sendfile */
  237 SM1_NONSTD,     /* __NR_getpmsg, sys_ni_syscall */
  238 SM1_NONSTD,     /* __NR_putpmsg, sys_ni_syscall */
  239 
  240 SM1_FORK,       /* 190, __NR_vfork, sys_vfork */
  241 SM1_RLIM,       /* __NR_ugetrlimit, sys_getrlimit */
  242 SM1_MMAP,       /* __NR_mmap2, sys_mmap2 */
  243 SM1_ERASE,      /* __NR_truncate64, sys_truncate64 */
  244 SM1_FMISC,      /* __NR_ftruncate64, sys_ftruncate64 */
  245 SM1_DREAD,      /* __NR_stat64, sys_stat64 */
  246 SM1_DREAD,      /* __NR_lstat64, sys_lstat64 */
  247 SM1_DREAD,      /* __NR_fstat64, sys_fstat64 */
  248 SM1_ROOTMISC,       /* __NR_lchown, sys_lchown */
  249 SM1_HARMLESS,       /* __NR_getuid, sys_getuid */
  250 
  251 SM1_HARMLESS,       /* 200, __NR_getgid, sys_getgid */
  252 SM1_HARMLESS,       /* __NR_geteuid, sys_geteuid */
  253 SM1_HARMLESS,       /* __NR_getegid, sys_getegid */
  254 0,          /* __NR_setreuid, sys_setreuid */
  255 0,          /* __NR_setregid, sys_setregid */
  256 SM1_HARMLESS,       /* __NR_getgroups, sys_getgroups */
  257 0,          /* __NR_setgroups, sys_setgroups */
  258 SM1_ROOTMISC,       /* __NR_fchown, sys_fchown */
  259 SM1_NONSTD,     /* __NR_setresuid, sys_setresuid */
  260 SM1_NONSTD,     /* __NR_getresuid, sys_getresuid */
  261 
  262 SM1_NONSTD,     /* 210 __NR_setresgid, sys_setresgid */
  263 SM1_NONSTD,     /* __NR_getresgid, sys_getresgid */
  264 SM1_ROOTMISC,       /* __NR_chown, sys_chown */
  265 0,          /* __NR_setuid, sys_setuid */
  266 0,          /* __NR_setgid, sys_setgid */
  267 SM1_NONSTD,     /* __NR_setfsuid, sys_setfsuid */
  268 SM1_NONSTD,     /* __NR_setfsgid, sys_setfsgid */
  269 SM1_ROOTMISC|SM1_NONSTD,/* __NR_pivot_root, sys_pivot_root */
  270 SM1_ROOTMISC|SM1_NONSTD,/* __NR_mincore, sys_mincore */
  271 SM1_ROOTMISC|SM1_NONSTD,/* __NR_madvise, sys_madvise */
  272 
  273 SM1_DREAD,      /* 220, __NR_getdents64, sys_getdents64 */
  274 SM1_OPEN|SM1_FMISC, /* __NR_fcntl64, sys_fcntl64 */
  275 SM1_NEW,        /* 222, sys_ni_syscall */
  276 SM1_NEW,        /* 223, sys_ni_syscall */
  277 SM1_HARMLESS,       /* __NR_gettid, sys_gettid */
  278 SM1_NONSTD,     /* __NR_readahead, sys_readahead */
  279 SM1_CHMOD,      /* __NR_setxattr, sys_setxattr */
  280 SM1_CHMOD,      /* __NR_lsetxattr, sys_lsetxattr */
  281 SM1_CHMOD,      /* __NR_fsetxattr, sys_fsetxattr */
  282 SM1_DREAD,      /* __NR_getxattr, sys_getxattr */
  283 
  284 SM1_DREAD,      /* 230, __NR_lgetxattr, sys_lgetxattr */
  285 SM1_DREAD,      /* __NR_fgetxattr, sys_fgetxattr */
  286 SM1_DREAD,      /* __NR_listxattr, sys_listxattr */
  287 SM1_DREAD,      /* __NR_llistxattr, sys_llistxattr */
  288 SM1_DREAD,      /* __NR_flistxattr, sys_flistxattr */
  289 SM1_CHMOD,      /* __NR_removexattr, sys_removexattr */
  290 SM1_CHMOD,      /* __NR_lremovexattr, sys_lremovexattr */
  291 SM1_CHMOD,      /* __NR_fremovexattr, sys_fremovexattr */
  292 SM1_KILL|SM1_NONSTD,    /* __NR_tkill, sys_tkill */
  293 SM1_NONSTD,     /* __NR_sendfile64, sys_sendfile64 */
  294 
  295 SM1_NONSTD,     /* 240, __NR_futex, sys_futex */
  296 SM1_NONSTD|SM1_ROOTMISC,/* __NR_sched_setaffinity, sys_sched_setaffinity */
  297 SM1_NONSTD|SM1_ROOTMISC,/* __NR_sched_getaffinity, sys_sched_getaffinity */
  298 SM1_NONSTD|SM1_MISC,    /* __NR_set_thread_area, sys_set_thread_area */
  299 SM1_NONSTD|SM1_MISC,    /* __NR_get_thread_area, sys_get_thread_area */
  300 SM1_NONSTD|SM1_RT,  /* __NR_io_setup, sys_io_setup */
  301 SM1_NONSTD|SM1_RT,  /* __NR_io_destroy, sys_io_destroy */
  302 SM1_NONSTD|SM1_RT,  /* __NR_io_getevents, sys_io_getevents */
  303 SM1_NONSTD|SM1_RT,  /* __NR_io_submit, sys_io_submit */
  304 SM1_NONSTD|SM1_RT,  /* __NR_io_cancel, sys_io_cancel */
  305 
  306 SM1_NONSTD,     /* 250, __NR_fadvise64, sys_fadvise64 */
  307 SM1_NEW,        /* 251, sys_ni_syscall */
  308 0,          /* __NR_exit_group, sys_exit_group */
  309 SM1_NONSTD|SM1_DREAD,   /* __NR_lookup_dcookie, sys_lookup_dcookie */
  310 SM1_NONSTD|SM1_POLL,    /* __NR_epoll_create, sys_epoll_create */
  311 SM1_NONSTD|SM1_POLL,    /* __NR_epoll_ctl, sys_epoll_ctl */
  312 SM1_NONSTD|SM1_POLL,    /* __NR_epoll_wait, sys_epoll_wait */
  313 SM1_NONSTD|SM1_MMAP,    /* __NR_remap_file_pages, sys_remap_file_pages */
  314 SM1_NONSTD,     /* __NR_set_tid_address, sys_set_tid_address */
  315 SM1_NONSTD|SM1_RT,  /* __NR_timer_create, sys_timer_create */
  316 
  317 SM1_NONSTD|SM1_RT,  /* 260, __NR_timer_settime, sys_timer_settime */
  318 SM1_NONSTD|SM1_RT,  /* __NR_timer_gettime, sys_timer_gettime */
  319 SM1_NONSTD|SM1_RT,  /* __NR_timer_getoverrun, sys_timer_getoverrun */
  320 SM1_NONSTD|SM1_RT,  /* __NR_timer_delete, sys_timer_delete */
  321 SM1_NONSTD|SM1_RT,  /* __NR_clock_settime, sys_clock_settime */
  322 SM1_HARMLESS,       /* __NR_clock_gettime, sys_clock_gettime */
  323 SM1_NONSTD|SM1_RT,  /* __NR_clock_getres, sys_clock_getres */
  324 SM1_NONSTD|SM1_RT,  /* __NR_clock_nanosleep, sys_clock_nanosleep */
  325 SM1_NONSTD|SM1_FS,  /* __NR_statfs64, sys_statfs64 */
  326 SM1_NONSTD|SM1_FS,  /* __NR_fstatfs64, sys_fstatfs64 */
  327 };
  328 
  329 #define NR_sysmasks (sizeof(sysmask_tab)/sizeof(sysmask_tab[0]))
  330 
  331 pid_t smk_daemon_pid;
  332 uid_t sysmask_denyid;
  333 struct task_struct *smk_daemon_task;
  334 spinlock_t smkreq_lock;
  335 struct smkd_request smk_req;
  336 int smk_req_flags;
  337 static atomic_t smkd_tick_time;
  338 static atomic_t smk_sescnt;
  339 static long int smk_session_inited = 0;
  340 long int smk_ses_next_id = 0;
  341 pid_t smk_reqpid, smk_waiting;
  342 int smk_req_result;
  343 struct vfsmount *smkd_rootmnt;
  344 struct dentry *smkd_root;
  345 
  346     /* allocate a new session */
  347 #define _smk_getsession() (struct smk_session *) __get_free_pages(GFP_KERNEL,1);
  348     /* free a session page */
  349 #define _smk_putsession(x) free_pages((unsigned long) x,1);
  350 
  351 long smk_kill(struct task_struct *p)
  352 {
  353     struct siginfo info;
  354 
  355     info.si_signo = SIGKILL;
  356     info.si_errno = 0;
  357     info.si_code = SI_USER;
  358     info.si_pid = current->pid;
  359     info.si_uid = current->uid;
  360     
  361     return send_sig_info(SIGKILL, &info, p);
  362 }
  363 
  364     /* Returns non-zero if should be killed */
  365 static int _ultimatum(void)
  366 {
  367     int i;
  368     struct smk_session *ses;
  369     unsigned long t, nowsec;
  370     struct timeval now;
  371 
  372     do_gettimeofday(&now); nowsec=now.tv_sec;
  373     for(i=0; i<SMK_SESSIONS; i++) {
  374     ses = current->smk_ses[i];
  375     if(!ses) continue;
  376     t = ses->rlim[SMK_RLIM_TIMEOUT];
  377     if(t && nowsec >= t) {
  378         smk_kill(current);
  379         return -EPERM;
  380     }
  381     }
  382     return 0;
  383 }
  384 
  385 static void _smk_init_ses(void)
  386 {
  387     current->smk.token = 0;
  388     current->smk_ses[0] = NULL;
  389     current->smk_ses[1] = NULL;
  390     smk_session_inited = 1;
  391     atomic_set(&smk_sescnt, 0);
  392 }
  393 
  394 static void _smk_session_decrease(struct smk_session *ses)
  395 {
  396     if(!ses) return;
  397     if(atomic_dec_and_test(&ses->rstatus[SMK_RLIM_NPROC])) {
  398     _smk_putsession(ses);
  399     atomic_dec(&smk_sescnt);
  400     }
  401 }
  402 
  403 static void _smk_new_session(long old_token, long token, long *rlim, long killid)
  404 {
  405     int i;
  406     long t1, t2;
  407     struct timeval now;
  408     struct smk_session *ses, *oldses;
  409 
  410     for(i = 0; i < SMK_SESSIONS; i++) {
  411     t1 = (token>>(i*16))&0xFFFF;
  412     t2 = (old_token>>(i*16))&0xFFFF;
  413     if(t1 == t2) continue;
  414     oldses=current->smk_ses[i];
  415     if(oldses) {
  416         if(t1) {
  417         atomic_inc(&oldses->rstatus[SMK_RLIM_SWITCH]);
  418         }
  419         _smk_session_decrease(oldses);
  420         current->smk_ses[i]=NULL;
  421     }
  422     if(t1 == 0) continue;
  423     ses=_smk_getsession(); if(!ses) continue;
  424     current->smk_ses[i]=ses;
  425     ses->token = t1;
  426     ses->token_type = i;
  427     ses->id = ++smk_ses_next_id;
  428     ses->killid = killid;
  429     atomic_inc(&smk_sescnt);
  430     do_gettimeofday(&now);
  431     ses->start_time = now.tv_sec;
  432     memmove(ses->rlim,rlim,sizeof(ses->rlim));
  433     ses->rlim[0] <<= 20-PAGE_SHIFT;
  434     ses->rlim[1] <<= 20-PAGE_SHIFT;
  435     memset(ses->rstatus,0,sizeof(ses->rstatus));
  436     atomic_set(&ses->rstatus[SMK_RLIM_NPROC],1);
  437     current->fork_depth[i] = 0;
  438     }
  439 }
  440 
  441     /* check rlim [type] against v: returns 1 if OK. */
  442 long smk_rlim_exceed(unsigned long v, int type)
  443 {
  444     int i, t;
  445     struct smk_session *ses;
  446 
  447     for(i = 0; i<SMK_SESSIONS; i++) {
  448     ses = current->smk_ses[i];
  449     if(!ses) continue;
  450     t = ses->rlim[type];
  451     if(t && v > t) return 1;
  452     }
  453     return 0;
  454 }
  455 
  456     /* check rlim [type] against v: returns 0 if OK. */
  457 long smk_rlim_reached(int type)
  458 {
  459     unsigned int i, t;
  460     struct smk_session *ses;
  461 
  462     if(!smk_session_inited) return 0;
  463     for(i=0; i<SMK_SESSIONS; i++) {
  464     ses = current->smk_ses[i];
  465     if(!ses) continue;
  466     t = ses->rlim[type];
  467     if(t && atomic_read(&ses->rstatus[type]) >= t) return 1;
  468     }
  469     return 0;
  470 }
  471 
  472     /* move triggered mask to active mask, then clean the former. */
  473 static void _smk_trigger(struct sysmask_struct *smk)
  474 {
  475     smk->active.m1|=smk->triggered.m1;
  476     smk->active.m2|=smk->triggered.m2;
  477     smk->active.cap|=smk->triggered.cap;
  478     smk->triggered.m1=smk->triggered.m2=smk->triggered.cap=0;
  479     smk->trigger=smk->tcnt=0;
  480 }
  481 
  482     /* check trigger value and advance count. */
  483 void smk_trigger(int t)
  484 {
  485     if(!t || t!=current->smk.trigger) return;
  486     current->smk.tcnt--;
  487     if(current->smk.tcnt<=0) _smk_trigger(&current->smk);
  488 }
  489 
  490 static int _smk_daemon_connect(void)
  491 {
  492     int i, retval;
  493     time_t asktime, checktime;
  494     struct timeval now;
  495 
  496     if(!smk_daemon_task) return -EACCES;    /* no daemon: deny every request */
  497     if(current==smk_daemon_task) return -EINVAL;    /* calling myself */
  498     if(current->pid == 0) return -EINVAL;   /* init process */
  499     if(_ultimatum()) return -EPERM;     /* time up */
  500     retval=-EAGAIN; asktime=0;
  501 
  502     /* This is not correct: we need to queue the requests. */
  503 reloop:
  504     for(i=0; i<1000; i++) {
  505     spin_lock(&smkreq_lock);
  506     if(!smk_reqpid) break;
  507     spin_unlock(&smkreq_lock);
  508     if(!asktime) {
  509         do_gettimeofday(&now); asktime = now.tv_sec;
  510     }
  511     yield();
  512     }
  513     if(i>=1000) {
  514     do_gettimeofday(&now); checktime = now.tv_sec;
  515     if(checktime < asktime + 2) goto reloop;
  516     else {
  517         printk(KERN_DEBUG "Process %u: smkd connect timeout (%u).\n",current->pid,smk_reqpid);
  518         goto out;
  519     }
  520     }
  521     smk_req.pid=0; retval=0; smk_reqpid=current->pid;
  522     smk_req.reqlen=0;
  523     spin_unlock(&smkreq_lock);
  524 out:
  525     return retval;
  526 }
  527 
  528 static void _smk_daemon_abandon(void)
  529 {
  530     spin_lock(&smkreq_lock);
  531     if(smk_reqpid == current->pid) smk_reqpid=smk_req.pid=0;
  532     spin_unlock(&smkreq_lock);
  533 }
  534 
  535 
  536 static int _smk_put_req_fname(const char *fname)
  537 {
  538     unsigned long l,k;
  539     int err;
  540     static char cwd[SMK_PATH_MAX+1];
  541     char *e;
  542     struct vfsmount *pwdmnt;
  543     struct dentry *pwd;
  544 
  545     smk_req.fname[0]=0; smk_req_flags=0;
  546     l=strlen(fname);
  547     if(current->fs->rootmnt != smkd_rootmnt ||
  548        current->fs->root != smkd_root)
  549       smk_req_flags |= SMKD_REQ_ISCHROOT;
  550     pwdmnt=NULL; pwd=NULL;
  551     if(fname[0]!='/') {
  552     cwd[0] = 0;
  553     read_lock(&current->fs->lock);
  554     pwdmnt=mntget(current->fs->pwdmnt);
  555     pwd=dget(current->fs->pwd);
  556     read_unlock(&current->fs->lock);
  557     e=d_path(pwd, pwdmnt, cwd, SMK_PATH_MAX);
  558     dput(pwd); mntput(pwdmnt);
  559     if(IS_ERR(e)) {
  560         err = PTR_ERR(e);
  561         goto free_out;
  562     }
  563     k=strlen(e);
  564     if(k+l>=SMK_PATH_MAX-1) {
  565         err = -ENAMETOOLONG;
  566         goto free_out;
  567     }
  568     memmove(smk_req.fname,e,k);
  569     if(k>0 && smk_req.fname[k-1]!='/') smk_req.fname[k++]='/';
  570     }
  571     else k=0;
  572     if(k+l>=SMK_PATH_MAX) return -ENAMETOOLONG;
  573     memmove(smk_req.fname+k,fname,l+1);
  574     smk_req.reqlen=k+l;
  575     err = 0;
  576 free_out:
  577     return err;
  578 }
  579 
  580 static long _smk_daemon_req(int type)
  581 {
  582     int i,l;
  583     time_t asktime, checktime;
  584     struct timeval now;
  585     smk_req.uid=current->euid;
  586 #ifdef LINUX_2_4
  587     smk_req.start_time=current->start_time;
  588 #else
  589     smk_req.start_time=current->start_time.tv_sec;
  590 #endif
  591     smk_req.sm1=current->smk.active.m1;
  592     smk_req.sm2=current->smk.active.m2;
  593     smk_req.syscall=current->smk_syscall&0xFFFF;
  594     smk_req.token=current->smk.token;
  595     smk_req.reqtype=type;
  596     if(current->smk_log_cnt>=SMK_LOG_LIM) smk_req.sm2&=~SM2_LOG;
  597     spin_lock(&smkreq_lock);
  598     smk_req.pid=current->pid;   /* this is the indicator for write end */
  599     spin_unlock(&smkreq_lock);
  600     wake_up_process(smk_daemon_task);
  601     /* smk_waiting for daemon */
  602     yield();
  603     if(smk_reqpid != current->pid && smk_waiting != current->pid) goto got;
  604     do_gettimeofday(&now); asktime = now.tv_sec;
  605     rewait:
  606     for(i=0;
  607     i<1000 && (smk_reqpid == current->pid || smk_waiting == current->pid);
  608     i++) yield();
  609     if(i>=1000) {   /* timeout: abandon */
  610     do_gettimeofday(&now); checktime = now.tv_sec;
  611     if(checktime < asktime + 10) goto rewait;
  612     _smk_daemon_abandon();
  613     return -EAGAIN;
  614     }
  615 
  616     got: l=current->smk_got.ind&0xFFFF;
  617     if(current->smk_got.ind&SMKD_ANS_LOGGED &&
  618        current->smk_log_cnt<SMK_LOG_LIM) current->smk_log_cnt++;
  619     current->smk_got.ind|=0xFFFF;
  620     return -l;
  621 }
  622 
  623 #define _smk_addmask(x) __smk_addmask(&current->smk,x)
  624 
  625     /* the principle is never remove an already-installed restriction */
  626 static void __smk_addmask(struct sysmask_struct *dest, struct sysmask_struct *src)
  627 {
  628     int i,j,k;
  629     if(src->trigger) {
  630     if(dest->trigger) {
  631         if(dest->trigger!=src->trigger) _smk_trigger(dest);
  632         else {
  633         if(dest->tcnt<src->tcnt)
  634           src->tcnt=dest->tcnt;
  635         }
  636     }
  637     dest->trigger=src->trigger;
  638     dest->tcnt=src->tcnt;
  639     dest->triggered.m1|=src->triggered.m1;
  640     dest->triggered.m2|=src->triggered.m2;
  641     dest->triggered.cap|=src->triggered.cap;
  642     }
  643     if(!dest->active.m1) k=1;
  644     else {
  645     for(i=k=0;i<SMK_EXCEPTS;i++) {
  646         if(dest->except[i]==SMKD_EXCEPT) {
  647         k=1; break;
  648         }
  649     }
  650     }
  651     for(i=0;i<SMK_EXCEPTS;i++) {
  652     if(src->except[i]>NR_sysmasks && 
  653        (src->except[i]!=SMKD_EXCEPT || k==0)) {
  654         src->except[i]=0;
  655     }
  656     if(src->except[i]!=0) {
  657         for(j=0;j<SMK_EXCEPTS && src->except[i]!=dest->except[j];j++);
  658         if(j>=SMK_EXCEPTS) {
  659         if(src->except[i]<=NR_sysmasks) {
  660             if((sysmask_tab[src->except[i]-1]&dest->active.m1)!=0)
  661               src->except[i]=0;
  662         }
  663         else if(dest->active.m1) src->except[i]=0;
  664         }
  665     }
  666     }
  667     memmove(&dest->except,&src->except,SMK_EXCEPTS*sizeof(short));
  668     dest->active.m1|=src->active.m1;
  669     dest->active.m2|=src->active.m2;
  670     dest->active.cap|=src->active.cap;
  671 }
  672 
  673     /* This one avoids mixing two tokens of the same level */
  674 static void _smk_addtoken(signed long t)
  675 {
  676     int err;
  677     int old_token = current->smk.token;
  678     
  679     if((t&0xFFFF) && (current->smk.token&0xFFFF)) t&=0xFFFF0000;
  680     if((t&0xFFFF0000) && (current->smk.token&0xFFFF0000)) t&=0xFFFF;
  681     err=_smk_daemon_connect();
  682     if(err) return;
  683     current->smk.token|=t;
  684     if(_smk_daemon_req(SMKD_REQ_TOKEN)) return;
  685     _smk_addmask(&current->smk_got.smk);
  686     _smk_new_session(old_token,current->smk.token,
  687              current->smk_got.rlim,current->smk_got.killid);
  688 }
  689 
  690     /* log syscall refusal by smkd */
  691 static int _smk_log(int call,int check)
  692 {
  693     int err;
  694     err=_smk_daemon_connect();
  695     if(err) return err;
  696     current->smk_syscall=call;
  697     if(check) return _smk_daemon_req(SMKD_REQ_CALL);
  698     else return _smk_daemon_req(SMKD_REQ_LOG);
  699 }
  700 
  701 static int _smk_masked(int syscall)
  702 {
  703     int i,err;
  704     int dex = 0;
  705     syscall++;
  706     for(i=0;i<SMK_EXCEPTS && syscall!=current->smk.except[i];i++) {
  707     if(current->smk.except[i] == SMKD_EXCEPT) dex=1;
  708     }
  709     syscall--;
  710     if(syscall==current->smk.trigger) smk_trigger(syscall);
  711     if(i < SMK_EXCEPTS) return 0;
  712     /* log refusals */
  713     if(dex || (sm2_masked(SM2_LOG) && current->smk_log_cnt<SMK_LOG_LIM)) {
  714     err=_smk_log(syscall,dex);
  715     if(dex && !err) return 0;
  716     current->smk_log_cnt++;
  717     }
  718     return -EPERM;
  719 }
  720 
  721     /* kill a single process */
  722 static int _smk_killproc(long pid, long start_time)
  723 {
  724     struct task_struct *p;
  725     read_lock(&tasklist_lock);
  726     p = find_task_by_pid(pid);
  727 #ifdef LINUX_2_4
  728     if(!p || p->start_time != start_time) {
  729 #else
  730     if(!p || p->start_time.tv_sec != start_time) {
  731 #endif
  732     read_unlock(&tasklist_lock); return -EINVAL;
  733     }
  734     smk_kill(p);
  735     read_unlock(&tasklist_lock);
  736     return 0;
  737 }
  738 
  739     /* kill a whole session */
  740 static int _smk_killses(long sid)
  741 {
  742     struct task_struct *p;
  743 
  744     read_lock(&tasklist_lock);
  745 #ifdef LINUX_2_4
  746     for_each_task(p) {
  747 #else
  748     for_each_process(p) {
  749 #endif
  750     if((p->smk_ses[0] && p->smk_ses[0]->killid == sid) ||
  751        (p->smk_ses[1] && p->smk_ses[1]->killid == sid))
  752       smk_kill(p);
  753     }
  754     read_unlock(&tasklist_lock);
  755     return 0;
  756 }
  757 
  758 static int _smk_getreq(void __user * smk, size_t len)
  759 {
  760     int err, t;
  761     size_t l;
  762     static int cnt = 0;
  763     struct task_struct *p;
  764     
  765     if(len > sizeof(smk_req)) len = sizeof(smk_req);
  766     if(cnt < 0) cnt = 0;
  767     spin_lock(&smkreq_lock);
  768     t = smk_req.pid - smk_reqpid;
  769     spin_unlock(&smkreq_lock);
  770     if(t != 0) {    /* half-done request */
  771     cnt++;
  772     if(cnt > 30) {  /* Stray request? Kill it. */
  773         printk(KERN_ERR "smkd: stray requester %u killed.\n", smk_reqpid);
  774         if(smk_reqpid > 1 && smk_reqpid != current->pid) sys_kill(smk_reqpid,SIGKILL);
  775         spin_lock(&smkreq_lock);
  776         smk_reqpid = 0; cnt = 0;
  777         spin_unlock(&smkreq_lock);
  778     }
  779     return -EINVAL;
  780     }
  781     cnt=0;
  782     smk_req.reqtype|=smk_req_flags;
  783     if(smk_req.reqlen<0) smk_req.reqlen=0;
  784     l=sizeof(smk_req)-SMK_PATH_MAX+smk_req.reqlen;
  785     if(l>len) { /* too long; should only occur under unequal versions */
  786     read_lock(&tasklist_lock);
  787     p = find_task_by_pid(smk_reqpid);
  788     if(p) p->smk_got.ind=ENAMETOOLONG;
  789     read_unlock(&tasklist_lock);
  790     err = -ENAMETOOLONG;
  791     spin_lock(&smkreq_lock);
  792     smk_waiting = 0;
  793     goto release_out;
  794     }
  795     err = copy_to_user(smk,&smk_req,l);
  796     spin_lock(&smkreq_lock);
  797     smk_waiting=smk_req.pid;
  798 release_out:
  799     smk_reqpid = 0; /* can receive new requests */
  800     spin_unlock(&smkreq_lock);
  801     return err;
  802 }
  803 
  804 static int _smk_smkdrep(void __user * smk, size_t len)
  805 {
  806     struct task_struct *p;
  807     struct smkd_answer ans;
  808     
  809     if(len > sizeof(ans)) len = sizeof(ans);
  810     if(len < sizeof(ans)) memset(&ans,0,sizeof(ans));
  811     if(copy_from_user(&ans,smk,len))
  812       return -EFAULT;
  813     if(ans.ind & SMKD_ANS_KILL) {   /* kill the named process */
  814     if(!ans.smk.active.m1) return 0;    /* nothing to kill */
  815     if(ans.opt==0) {
  816         if(ans.smk.active.m1==smk_waiting) smk_waiting=0;
  817         return _smk_killproc(ans.smk.active.m1,ans.smk.active.m2);
  818     }
  819     else {
  820         return _smk_killses(ans.smk.active.m1);
  821     }
  822     }
  823     if(!smk_waiting) return -EINVAL;
  824     read_lock(&tasklist_lock);
  825     p = find_task_by_pid(smk_waiting);
  826     if(!p) {    /* task disappeared */
  827     read_unlock(&tasklist_lock);
  828     smk_waiting = 0;
  829     return -EINVAL;
  830     }
  831     p->smk_got = ans;
  832     read_unlock(&tasklist_lock);
  833     smk_waiting=0;
  834     yield();
  835     return 0;
  836 }
  837 
  838 static int _smk_smkdreg(long l)
  839 {
  840     struct timeval now;
  841     int oldtime, testime;
  842     
  843     if(current->euid!=0 || current->uid!=0 || sm2_masked(SM2_KILLSMKD))
  844     return -EPERM;
  845     if(smk_daemon_pid == current->pid) return 0;
  846     do_gettimeofday(&now);
  847     testime = now.tv_sec;
  848     /* This following situation only occurs if there is a bug in smkd.
  849      * The codes are there to limit the consequences of the bug. */
  850     if(smk_daemon_pid != 0) {
  851     oldtime = atomic_read(&smkd_tick_time);
  852         /* another daemon is alive */
  853     if(oldtime <= testime && oldtime > testime - 15)
  854         return -EPERM;
  855     smk_kill(smk_daemon_task);
  856     }
  857     smkd_rootmnt = current->fs->rootmnt;
  858     smkd_root = current->fs->root;
  859     atomic_set(&smkd_tick_time,testime);
  860     sysmask_denyid=l;
  861     smkreq_lock=SPIN_LOCK_UNLOCKED;
  862     smk_daemon_pid=current->pid;
  863     smk_daemon_task=current;
  864     if(!smk_session_inited) _smk_init_ses();
  865     printk(KERN_WARNING "smkd: process %u registered.\n", smk_daemon_pid);
  866     return 0;
  867 }
  868 
  869 static int _smk_gettick(void)
  870 {
  871     struct timeval now;
  872     
  873     do_gettimeofday(&now);
  874     atomic_set(&smkd_tick_time,now.tv_sec);
  875     return 0;
  876 }
  877 
  878 static int _smk_getmask2(void __user * smk, size_t l)
  879 {
  880     int i, err, t1, t2, shift;
  881     int pid;
  882     struct task_struct *p;
  883     struct sysmask_struct s;
  884 
  885     err = copy_from_user(&s, smk, sizeof(struct sysmask_struct));
  886     if(err) return err;
  887     pid=s.token;
  888     if (pid<=0) return -EINVAL;
  889     if (pid == 1 || pid == smk_daemon_pid) return -EACCES;
  890     read_lock(&tasklist_lock);
  891     p = find_task_by_pid(pid);
  892     read_unlock(&tasklist_lock);
  893     if(!p) {    /* task disappeared */
  894     err = -ESRCH; goto ret;
  895     }
  896         /* Here race condition in target process
  897          * will result in corrupt data collected or even segfault.
  898          * Worth locking kernel for that? Maybe not. */
  899     err=-EACCES;
  900     if (current->euid != 0 && p->euid != current->euid) goto ret;
  901     t1=current->smk.token; t2=p->smk.token;
  902     if((t1&0xFFFF) && (t1&0xFFFF) != (t2&0xFFFF)) goto ret;
  903     if((t1&0xFFFF) && (t1&0xFFFF0000) &&
  904        (t1&0xFFFF0000) != (t2&0xFFFF0000)) goto ret;
  905     err = copy_to_user(smk,&p->smk,sizeof(struct sysmask_struct));
  906     if(err) goto ret;
  907     shift = sizeof(struct sysmask_struct);
  908     /* session information */
  909     for(i=0; l >= shift + sizeof(struct smk_session) && i<SMK_SESSIONS; i++) {
  910     if(p->smk_ses[i]) {
  911         err = copy_to_user(smk+shift,p->smk_ses[i],sizeof(struct smk_session));
  912         if(err) goto ret;
  913     }
  914     shift += sizeof(struct smk_session);
  915     }
  916 ret:
  917     return err;
  918 }
  919 
  920     /* this one is performance-critical. */
  921 asmlinkage int sys_checkmask(int syscall)
  922 {
  923 #ifdef SMK_DISABLE
  924     return 0;
  925 #endif
  926     if(syscall<0) return -ENOSYS;
  927     if(syscall>=NR_sysmasks) {
  928     if(sm1_masked(SM1_NEW|SM1_NONSTD)) return -EPERM;
  929     else return 0;
  930     }
  931     if(sm1_masked(sysmask_tab[syscall]) && _smk_masked(syscall)) {
  932     return -EPERM;
  933     }
  934     else if(syscall==current->smk.trigger) smk_trigger(syscall);
  935     current->smk_got.ind=0; current->smk_syscall=syscall;
  936     return 0;
  937 }
  938 
  939     /* userspace program interface */
  940 asmlinkage long sys_sysmask(long req, void __user * smk, long l)
  941 {
  942     switch(req) {
  943     case SMK_VERSION: return SYSMASK_VERSION;
  944     case SMK_GETMASK: {
  945         if(l != sizeof(struct sysmask_struct)) return -EINVAL;
  946         copy_to_user(smk,&current->smk,sizeof(struct sysmask_struct));
  947         return 0;
  948     }
  949     case SMK_SETMASK: {
  950         struct sysmask_struct newmask;
  951         int err;
  952         if(l!=sizeof(struct sysmask_struct)) return -EINVAL;
  953         err=copy_from_user(&newmask,smk,l);
  954         if(err) return err;
  955         _smk_addmask(&newmask);
  956         if(newmask.token) _smk_addtoken(newmask.token);
  957         return 0;
  958     }
  959     case SMK_TRIGGER: {
  960         _smk_trigger(&current->smk);
  961         return 0;
  962     }
  963     case SMK_RESERVE1: {
  964         return -EINVAL;
  965     }
  966     case SMK_SMKDREQ: { /* get request */
  967         if(current!=smk_daemon_task) return -EPERM;
  968         spin_lock(&smkreq_lock);
  969         if(!smk_reqpid) {   /* no request */
  970         spin_unlock(&smkreq_lock);
  971         return -EAGAIN;
  972         }
  973         spin_unlock(&smkreq_lock);
  974         return _smk_getreq(smk,l);
  975     }
  976     case SMK_SMKDREP: { /* give reply */
  977         if(current!=smk_daemon_task) return -EPERM;
  978         return _smk_smkdrep(smk, l);
  979     }
  980     case SMK_SMKDREG: { /* daemon registration */
  981         return _smk_smkdreg(l);
  982     }
  983     case SMK_GETMASK2: {        /* get mask of another process. */
  984         if(l < sizeof(struct sysmask_struct)) return -EINVAL;
  985         return _smk_getmask2(smk,l);
  986     }
  987     case SMK_SETMASK2: {        /* not implemented */
  988         return -EINVAL;
  989     }
  990     case SMK_SESSIONCNT: {
  991         if(current->euid!=0 || current->uid!=0 ||
  992            sm2_masked(SM2_KILLSMKD))
  993           return -EPERM;
  994         if(!smk_session_inited) _smk_init_ses();
  995         return atomic_read(&smk_sescnt);
  996     }
  997     case SMK_TICK: {
  998         if(current!=smk_daemon_task) return -EPERM;
  999         return _smk_gettick();
 1000     }
 1001     default: return -EINVAL;    /* invalid request. */
 1002     }
 1003     return 0;
 1004 }
 1005 
 1006 long smk_checkexec(const char *fname)
 1007 {
 1008     int err;
 1009     
 1010 #ifdef SMK_DISABLE
 1011     return 0;
 1012 #endif
 1013     if(!current->smk.token) return -EACCES;
 1014     current->smk_got.ind=0;
 1015     err=_smk_daemon_connect();
 1016     if(err) return err;
 1017     err=_smk_put_req_fname(fname);
 1018     if(err) {_smk_daemon_abandon(); return err;}
 1019     current->total_link_count = 0;
 1020     return _smk_daemon_req(SMKD_REQ_EXEC);
 1021 }
 1022 
 1023 long smk_checkexec2(struct file *file)
 1024 {
 1025     int err, ind;
 1026     struct smkd_answer save_ans;
 1027     char *buf, *e;
 1028 
 1029 #ifdef SMK_DISABLE
 1030     return 0;
 1031 #endif
 1032     ind=current->smk_got.ind;
 1033     current->smk_got.ind &= 0xFFFF0000; /* allow for interpreter check */
 1034     if(current->total_link_count > 0 && (ind & SMKD_ANS_NOSLINK)) {
 1035     return -EACCES;
 1036     }
 1037     if((ind & SMKD_ANS_NOHLINK) && file->f_dentry->d_inode->i_nlink>1) {
 1038     return -EACCES;
 1039     }
 1040     if((!current->total_link_count && !(ind&SMKD_ANS_HASDOTDOT)) ||
 1041        !(ind & SMKD_ANS_FOLLOW)) return 0;
 1042     buf = (char *) __get_free_pages(GFP_KERNEL,1);
 1043     if(!buf) return -EFAULT;
 1044     e=d_path(file->f_dentry, file->f_vfsmnt, buf, SMK_PATH_MAX);
 1045     if(IS_ERR(e)) {
 1046     err = PTR_ERR(e);
 1047     goto free_out;
 1048     }
 1049     save_ans = current->smk_got;
 1050     err = smk_checkexec(e);
 1051     if(!err && (current->smk_got.ind & SMKD_ANS_ADDMASK)) {
 1052     __smk_addmask(&save_ans.smk,&current->smk_got.smk);
 1053     }
 1054     save_ans.ind &= ~(SMKD_ANS_FOLLOW|SMKD_ANS_HASDOTDOT);
 1055     current->smk_got = save_ans;
 1056 free_out:
 1057     free_pages((unsigned long) buf,1);
 1058     return err;
 1059 }
 1060 
 1061 long smk_check_end(void)
 1062 {
 1063 #ifdef SMK_DISABLE
 1064     return 0;
 1065 #endif
 1066     /* tick triggering */
 1067     if((current->smk_got.ind & SMKD_ANS_TICK) && current->smk.trigger
 1068        && current->smk.tcnt > 0) {
 1069     current->smk.tcnt--;
 1070     if(current->smk.tcnt<=0) _smk_trigger(&current->smk);
 1071     }
 1072     if(current->smk_got.ind & SMKD_ANS_NEWMASK) {
 1073     _smk_new_session(current->smk.token,
 1074              current->smk_got.smk.token,
 1075              current->smk_got.rlim,
 1076              current->smk_got.killid);
 1077     current->smk=current->smk_got.smk;
 1078     }
 1079     else if(current->smk_got.ind & SMKD_ANS_ADDMASK) {  /* add new mask to old one */
 1080     _smk_addmask(&current->smk_got.smk);
 1081     }
 1082     current->smk_got.ind &= ~(SMKD_ANS_NEWMASK|SMKD_ANS_ADDMASK|SMKD_ANS_TICK);
 1083     return 0;
 1084 }
 1085 
 1086 static long _smk_checkpath(const char *fname)
 1087 {
 1088     int err, call;
 1089     struct smkd_answer save_ans;
 1090     
 1091     if(!current->smk.token) return -EACCES; /* always deny if no token */
 1092     call=current->smk_syscall&0xFFFF;
 1093     if(call == __NR_execve) save_ans = current->smk_got;
 1094     err=_smk_daemon_connect();
 1095     if(err) return err;
 1096     err=_smk_put_req_fname(fname);
 1097     if(err) {_smk_daemon_abandon(); return err;}
 1098     smk_req.flags = 0;
 1099     if((current->smk.active.m2&(SM2_PATH|SM2_ROPEN))==(SM2_PATH|SM2_ROPEN)
 1100        || call == __NR_execve)
 1101       smk_req.flags = 1;
 1102     if(call < NR_sysmasks && (sysmask_tab[call] & (SM1_DWRITE|SM1_ROOTMISC|SM1_SOCKETCALL))
 1103        && sm2_masked(SM2_WOPEN)) {
 1104     smk_req.flags |= 2;
 1105     }
 1106     else if(!smk_req.flags) {
 1107     _smk_daemon_abandon(); return 0;
 1108     }
 1109     err = _smk_daemon_req(SMKD_REQ_OPEN);
 1110     if(call == __NR_execve) current->smk_got = save_ans;
 1111     current->smk_got.ind &= 0xFFFF0000;     /* there may be more checks */
 1112     return err;
 1113 }
 1114 
 1115 long smk_checkpath(const char *fname)
 1116 {
 1117     int err;
 1118 #ifdef SMK_DISABLE
 1119     return 0;
 1120 #endif
 1121     if(current->smk_got.ind & 0xFFFF) return 0; /* already checked */
 1122     err = _smk_checkpath(fname);
 1123     if((current->smk_syscall&0xFFFF) != __NR_execve) smk_check_end();
 1124     return err;
 1125 }
 1126 
 1127 long smk_recheckpath(struct nameidata *nd)
 1128 {
 1129     int call, l;
 1130     int err;
 1131     char *buf;
 1132     char *e;
 1133 
 1134 #ifdef SMK_DISABLE
 1135     return 0;
 1136 #endif
 1137     if(current->smk_got.ind&0xFFFF) return 0; /* should be checked elsewhere */
 1138     if(current->total_link_count > 0 && (current->smk_got.ind & SMKD_ANS_NOSLINK)) {
 1139     return -EACCES;
 1140     }
 1141     if(!sm2_masked(SM2_WOPEN)) return 0;
 1142     call=current->smk_syscall&0xFFFF;
 1143     /* only recheck writing */
 1144     if(call>=NR_sysmasks || !(sysmask_tab[call] & (SM1_DWRITE|SM1_ROOTMISC))) {
 1145     return 0;
 1146     }
 1147     /* no recheck if no symbolic links nor dotdot */
 1148     if(!(current->smk_got.ind & SMKD_ANS_FOLLOW) ||
 1149        (!current->total_link_count && !(current->smk_got.ind & SMKD_ANS_HASDOTDOT))) {
 1150     return 0;
 1151     }
 1152     buf = (char *) __get_free_pages(GFP_KERNEL,1);
 1153     if(!buf) return -EFAULT;
 1154     e=d_path(nd->dentry, nd->mnt, buf, SMK_PATH_MAX);
 1155     if(IS_ERR(e)) {
 1156     err = PTR_ERR(e);
 1157     goto free_out;
 1158     }
 1159     if(nd->last_type == LAST_NORM && nd->last.len) {
 1160     l=strlen(e); memmove(buf,e,l+1); e=buf;
 1161     if(l>=SMK_PATH_MAX - nd->last.len - 1) {
 1162         err = -ENAMETOOLONG;
 1163         goto free_out;
 1164     }
 1165     buf[l++]='/'; memmove(buf+l,nd->last.name,nd->last.len);
 1166     buf[l+nd->last.len]=0;
 1167     }
 1168     err = _smk_checkpath(e);
 1169 free_out:
 1170     free_pages((unsigned long) buf,1);
 1171     return err;
 1172 }
 1173 
 1174 long smk_checksymlink(const char *from, const char *to)
 1175 {
 1176     char *buf;
 1177     int l1, l2, err;
 1178     
 1179 #ifdef SMK_DISABLE
 1180     return 0;
 1181 #endif
 1182     if(*from=='/') return smk_checkpath(from);
 1183     l1=strlen(from);
 1184     for(l2=strlen(to); l2>0 && to[l2-1]!='/'; l2--);
 1185     if(l1+l2 >= SMK_PATH_MAX) return -ENAMETOOLONG;
 1186     buf = (char *) __get_free_pages(GFP_KERNEL,1);
 1187     if(!buf) return -EFAULT;
 1188     memmove(buf,to,l2); memmove(buf+l2,from,l1); buf[l1+l2]=0;
 1189     err = smk_checkpath(buf);
 1190     free_pages((unsigned long) buf,1);
 1191     return err;
 1192 }
 1193 
 1194 static long _smk_checkopen(const char *fname, int *flag, int type)
 1195 {
 1196     int acc,req,rem;
 1197     int err;
 1198 
 1199     if(sm2_masked(SM2_CREAT)) *flag&=~(O_CREAT|O_TRUNC);
 1200     if((*flag&3)==0) return -EINVAL;
 1201     req=0;
 1202     if(sm2_masked(SM2_ROPEN)) req|=1;
 1203     if(sm2_masked(SM2_WOPEN)) req|=2;
 1204     acc=*flag&req;
 1205     if(!acc) return 0;
 1206     rem=*flag&~req; err=-EACCES;
 1207         /* no token: always refuse. */
 1208     if(!current->smk.token) {
 1209     ret_rem:
 1210     if(rem&3) {
 1211         *flag=rem; return 0;    /* return allowed flags */
 1212     }
 1213     else return err;
 1214     }
 1215     err=_smk_daemon_connect();
 1216     if(err) return err;
 1217     err=_smk_put_req_fname(fname);
 1218     if(err) {_smk_daemon_abandon(); return err;}
 1219     smk_req.flags=*flag;
 1220     err=_smk_daemon_req(type);
 1221     if(err) {
 1222     rem=current->smk_got.opt;
 1223     goto ret_rem;
 1224     }
 1225     current->total_link_count=0;
 1226     return 0;
 1227 }
 1228 
 1229 long smk_checkopen(const char *fname, int *flag)
 1230 {
 1231     int err;
 1232     
 1233 #ifdef SMK_DISABLE
 1234     return 0;
 1235 #endif
 1236     if(!sm2_masked(SM2_OPEN2|SM2_CREAT)) return 0;
 1237     current->smk_got.ind &= 0xFFFF;
 1238     err = _smk_checkopen(fname,flag,SMKD_REQ_OPEN);
 1239     smk_check_end();
 1240     return err;
 1241 }
 1242 
 1243 static long _smk_recheckopen(struct nameidata *nd, int flag)
 1244 {
 1245     int save_flag, err;
 1246     char *buf;
 1247     char *e;
 1248 
 1249     if(current->total_link_count > 0 && (current->smk_got.ind & SMKD_ANS_NOSLINK)) {
 1250     return -EACCES;
 1251     }
 1252     buf = (char *) __get_free_pages(GFP_KERNEL,1);
 1253     if(!buf) return -EFAULT;
 1254     e=d_path(nd->dentry, nd->mnt, buf, SMK_PATH_MAX);
 1255     if(IS_ERR(e)) {
 1256     err = PTR_ERR(e);
 1257     goto free_out;
 1258     }
 1259     save_flag=flag;
 1260     err=_smk_checkopen(e,&flag,SMKD_REQ_OPEN);
 1261     if(err) goto free_out;
 1262     err = -EACCES;
 1263     if(save_flag != flag) goto free_out;
 1264     /* No token nor tick is taken into account at this stage */
 1265     if(current->smk_got.ind & SMKD_ANS_ADDMASK) {/* second set of masks */
 1266     _smk_addmask(&current->smk_got.smk);
 1267     current->smk_got.ind &= ~SMKD_ANS_ADDMASK;
 1268     }
 1269     err = 0;
 1270 free_out:
 1271     free_pages((unsigned long) buf,1);
 1272     return err;
 1273 }
 1274 
 1275 long smk_openmode(struct nameidata *nd, int flag)
 1276 {
 1277     struct inode *inode = nd->dentry->d_inode;
 1278     int mode = inode->i_mode;
 1279     int err;
 1280 
 1281 #ifdef SMK_DISABLE
 1282     return 0;
 1283 #endif
 1284     /* hardlink check */
 1285     if(!(inode->i_mode & S_IFDIR) && 
 1286        (current->smk_got.ind & SMKD_ANS_NOHLINK) && inode->i_nlink>1)
 1287       return -EACCES;
 1288     /* symlink check */
 1289     if(current->total_link_count > 0 && (current->smk_got.ind & SMKD_ANS_NOSLINK)) {
 1290     return -EACCES;
 1291     }
 1292     /* recheck path if symbolic links are followed */
 1293     if((current->smk_got.ind & SMKD_ANS_FOLLOW) && 
 1294        (current->total_link_count > 0 || (current->smk_got.ind & SMKD_ANS_HASDOTDOT))) {
 1295     err=_smk_recheckopen(nd, flag);
 1296     if(err) return err;
 1297     }
 1298     /*
 1299      * Do not allow writing to executable files
 1300      * when chmod is masked.
 1301      */
 1302     if (sm1_masked(SM1_CHMOD) && (flag & FMODE_WRITE)
 1303     && (mode & S_IXUGO)) {
 1304     return -EACCES;
 1305     }
 1306     if (sm2_masked(SM2_DEV) && (S_ISCHR(mode) || S_ISBLK(mode)) &&
 1307     (S_ISBLK(mode) || MAJOR(inode->i_rdev)!=1 || MINOR(inode->i_rdev)!=3)) { /* /dev/null is allowed */
 1308     char buf[32];
 1309     char c;
 1310     int fl = flag;
 1311     if(S_ISBLK(mode)) c='b'; else c='c';
 1312     snprintf(buf,sizeof(buf),"/%c/%u/%u",c,MAJOR(inode->i_rdev),MINOR(inode->i_rdev));
 1313     err=_smk_checkopen(buf,&fl,SMKD_REQ_DEV);
 1314     if(err) return err;
 1315     if(fl != flag) return -EACCES;
 1316     }
 1317     if (sm2_masked(SM2_PROCFS)) {   /* lock? */
 1318     if(memcmp(nd->mnt->mnt_sb->s_type->name,"proc",5)==0)
 1319       return -EACCES;
 1320     }
 1321     return 0;
 1322 }
 1323 
 1324     /* this is only a template for the time being */
 1325 long smk_checksocket(struct socket *sock, int type,
 1326               struct sockaddr __user *addr, int addrlen)
 1327 {
 1328     char *cp;
 1329     int *ip;
 1330     int err;
 1331     struct smkd_answer save_ans;
 1332 
 1333     if(current->smk_syscall == __NR_execve) save_ans = current->smk_got;
 1334     current->smk_got.ind = 0;
 1335     err = -ENAMETOOLONG;
 1336     if(addrlen < 0) goto out;
 1337     if(!addr) addrlen=0;
 1338     err = 0;
 1339     if(addrlen==0 && type==SYS_SEND) goto out;
 1340     err = -ENAMETOOLONG;
 1341     if(addrlen+3*sizeof(int) >= SMK_PATH_MAX) goto out;
 1342     err = -EACCES;
 1343     if(!current->smk.token) goto out;
 1344     err=_smk_daemon_connect();
 1345     if(err) goto out;
 1346     ip=(int *) smk_req.fname; 
 1347     ip[0]=type; ip[1]=sock->ops->family; ip[2]=sock->type;
 1348     cp=smk_req.fname+3*sizeof(int);
 1349     if(addrlen>0) {
 1350     if(type != SYS_SEND && type != SYS_RECV) {
 1351         err = copy_from_user(cp, addr, addrlen);
 1352         if(err) {_smk_daemon_abandon();goto out;}
 1353     }
 1354     else memmove(cp,addr,addrlen);
 1355     }
 1356     smk_req.reqlen=addrlen+3*sizeof(int);
 1357     
 1358     err = _smk_daemon_req(SMKD_REQ_SOCKET);
 1359     smk_check_end();
 1360 out:
 1361     if(current->smk_syscall == __NR_execve) current->smk_got = save_ans;
 1362     return err;
 1363 }
 1364 
 1365     /* Fork limit check */
 1366 long smk_checkfork(void)
 1367 {
 1368     int i;
 1369     struct smk_session *ses;
 1370     unsigned long t, nowsec;
 1371     struct timeval now;
 1372 
 1373 #ifdef SMK_DISABLE
 1374     return 0;
 1375 #endif
 1376     if(!smk_session_inited) {
 1377     _smk_init_ses();
 1378     return 0;
 1379     }
 1380     if(_ultimatum()) return -EPERM;
 1381     if(smk_rlim_reached(SMK_RLIM_FORK)) return -EPERM;
 1382     if(smk_rlim_reached(SMK_RLIM_NPROC)) return -EAGAIN;
 1383     do_gettimeofday(&now); nowsec=now.tv_sec;
 1384     for(i=0; i<SMK_SESSIONS; i++) {
 1385     ses = current->smk_ses[i];
 1386     if(!ses) continue;
 1387     if(atomic_read(&ses->fork_time) != (nowsec & 0xFFFF)) {
 1388         atomic_set(&ses->fork_time, nowsec & 0xFFFF);
 1389         atomic_set(&ses->rstatus[SMK_RLIM_FORKFREQ], 0);
 1390     }
 1391     t = ses->rlim[SMK_RLIM_FORKDEPTH];
 1392     if(t && current->fork_depth[i] >= t) return -EPERM;
 1393     }
 1394     if(smk_rlim_reached(SMK_RLIM_FORKFREQ)) return -EAGAIN;
 1395     return 0;
 1396 }
 1397 
 1398     /* set sysmask for fork child */
 1399 void smk_forked(struct task_struct *p)
 1400 {
 1401     int i;
 1402     
 1403     memmove(&p->smk,&current->smk,sizeof(struct sysmask_struct));
 1404     memmove(p->smk_ses, current->smk_ses, sizeof(current->smk_ses));
 1405     p->smk_log_cnt = 0;
 1406     if(!smk_session_inited) return;
 1407     for(i=0; i<SMK_SESSIONS; i++) {
 1408     if(p->smk_ses[i]) {
 1409         atomic_inc(&p->smk_ses[i]->rstatus[SMK_RLIM_FORK]);
 1410         atomic_inc(&p->smk_ses[i]->rstatus[SMK_RLIM_FORKFREQ]);
 1411         atomic_inc(&p->smk_ses[i]->rstatus[SMK_RLIM_NPROC]);
 1412         p->fork_depth[i] = current->fork_depth[i]+1;
 1413     }
 1414     }
 1415 }
 1416 
 1417     /* release session count for an exited task. */
 1418 void smk_exited(struct task_struct *p)
 1419 {
 1420     int i;
 1421 
 1422     if(!smk_session_inited) {
 1423     _smk_init_ses();
 1424     return;
 1425     }
 1426     for(i=0; i<SMK_SESSIONS; i++) {
 1427     _smk_session_decrease(p->smk_ses[i]);
 1428     p->smk_ses[i]=NULL;
 1429     }
 1430 }
 1431