1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2014 <contributor>.  All rights reserved.
  14  */
  15 
  16 #include <sys/ddi.h>
  17 #include <sys/errno.h>
  18 #include <sys/policy.h>
  19 #include <sys/proc.h>
  20 #include <sys/procset.h>
  21 #include <sys/systm.h>
  22 #include <sys/types.h>
  23 
  24 struct psecargs {
  25         psecflags_cmd_t cmd;
  26         uint_t val;
  27 };
  28 
  29 static int
  30 psecdo(proc_t *p, struct psecargs *args)
  31 {
  32         mutex_enter(&p->p_lock);
  33 
  34         if (secpolicy_psecflags(CRED(), p, curproc) != 0) {
  35                 mutex_exit(&p->p_lock);
  36                 return (EPERM);
  37         }
  38 
  39         switch (args->cmd) {
  40         case PSECFLAGS_SET:
  41                 secflag_set(p, args->val);
  42                 break;
  43         case PSECFLAGS_DISABLE:
  44                 secflag_disable(p, args->val);
  45                 break;
  46         case PSECFLAGS_ENABLE:
  47                 secflag_enable(p, args->val);
  48                 break;
  49         }
  50         mutex_exit(&p->p_lock);
  51 
  52         return (0);
  53 }
  54 
  55 int
  56 psecflags(procset_t *psp, psecflags_cmd_t cmd, uint_t arg)
  57 {
  58         procset_t procset;
  59         struct psecargs args = { 0 };
  60         int rv = 0;
  61 
  62         /*
  63          * We don't check the validity in 'arg' for the sake of newer
  64          * software on older systems not just falling down dead.
  65          *
  66          * XXX: I'm not particularly confident that's not dumb.
  67          */
  68 
  69         if (copyin(psp, &procset, sizeof (procset)) != 0)
  70                 return (set_errno(EFAULT));
  71 
  72         /* secflags are per-process, procset must be in terms of processes */
  73         if ((procset.p_lidtype == P_LWPID) ||
  74             (procset.p_ridtype == P_LWPID))
  75                 return (set_errno(EINVAL));
  76 
  77         switch (cmd) {
  78         case PSECFLAGS_SET:
  79         case PSECFLAGS_DISABLE:
  80         case PSECFLAGS_ENABLE:
  81                 args.cmd = cmd;
  82                 args.val = arg;
  83                 rv = dotoprocs(&procset, psecdo,
  84                     (caddr_t)&args);
  85                 break;
  86         default:
  87                 return (set_errno(EINVAL));
  88         }
  89 
  90         return (rv ? set_errno(rv) : 0);
  91 }