The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kernel/system/do_privctl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* The kernel call implemented in this file:
    2  *   m_type:    SYS_PRIVCTL
    3  *
    4  * The parameters for this kernel call are:
    5  *    m1_i1:    PR_PROC_NR      (process number of caller)      
    6  */
    7 
    8 #include "../system.h"
    9 #include "../ipc.h"
   10 #include <signal.h>
   11 
   12 #if USE_PRIVCTL
   13 
   14 #define FILLED_MASK     (~0)
   15 
   16 /*===========================================================================*
   17  *                              do_privctl                                   *
   18  *===========================================================================*/
   19 PUBLIC int do_privctl(m_ptr)
   20 message *m_ptr;                 /* pointer to request message */
   21 {
   22 /* Handle sys_privctl(). Update a process' privileges. If the process is not
   23  * yet a system process, make sure it gets its own privilege structure.
   24  */
   25   register struct proc *caller_ptr;
   26   register struct proc *rp;
   27   register struct priv *sp;
   28   int proc_nr;
   29   int priv_id;
   30   int old_flags;
   31   int i;
   32 
   33   /* Check whether caller is allowed to make this call. Privileged proceses 
   34    * can only update the privileges of processes that are inhibited from 
   35    * running by the NO_PRIV flag. This flag is set when a privileged process
   36    * forks. 
   37    */
   38   caller_ptr = proc_addr(m_ptr->m_source);
   39   if (! (priv(caller_ptr)->s_flags & SYS_PROC)) return(EPERM); 
   40   proc_nr = m_ptr->PR_PROC_NR;
   41   if (! isokprocn(proc_nr)) return(EINVAL);
   42   rp = proc_addr(proc_nr);
   43   if (! (rp->p_rts_flags & NO_PRIV)) return(EPERM);
   44 
   45   /* Make sure this process has its own privileges structure. This may fail, 
   46    * since there are only a limited number of system processes. Then copy the
   47    * privileges from the caller and restore some defaults.
   48    */
   49   if ((i=get_priv(rp, SYS_PROC)) != OK) return(i);
   50   priv_id = priv(rp)->s_id;                     /* backup privilege id */
   51   *priv(rp) = *priv(caller_ptr);                /* copy from caller */
   52   priv(rp)->s_id = priv_id;                     /* restore privilege id */
   53   priv(rp)->s_proc_nr = proc_nr;                /* reassociate process nr */
   54 
   55   for (i=0; i< BITMAP_CHUNKS(NR_SYS_PROCS); i++)        /* remove pending: */
   56       priv(rp)->s_notify_pending.chunk[i] = 0;          /* - notifications */
   57   priv(rp)->s_int_pending = 0;                          /* - interrupts */
   58   sigemptyset(&priv(rp)->s_sig_pending);                /* - signals */
   59 
   60   /* Now update the process' privileges as requested. */
   61   rp->p_priv->s_trap_mask = FILLED_MASK;
   62   for (i=0; i<BITMAP_CHUNKS(NR_SYS_PROCS); i++) {
   63         rp->p_priv->s_ipc_to.chunk[i] = FILLED_MASK;
   64   }
   65   unset_sys_bit(rp->p_priv->s_ipc_to, USER_PRIV_ID);
   66 
   67   /* All process that this process can send to must be able to reply. 
   68    * Therefore, their send masks should be updated as well. 
   69    */
   70   for (i=0; i<NR_SYS_PROCS; i++) {
   71       if (get_sys_bit(rp->p_priv->s_ipc_to, i)) {
   72           set_sys_bit(priv_addr(i)->s_ipc_to, priv_id(rp));
   73       }
   74   }
   75 
   76   /* Done. Privileges have been set. Allow process to run again. */
   77   old_flags = rp->p_rts_flags;          /* save value of the flags */
   78   rp->p_rts_flags &= ~NO_PRIV;          
   79   if (old_flags != 0 && rp->p_rts_flags == 0) lock_enqueue(rp);
   80   return(OK);
   81 }
   82 
   83 #endif /* USE_PRIVCTL */
   84 

Cache object: 452f0712d727db61993f2311fbad8e57


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.