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/kern/kern_prot.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 /*      $NetBSD: kern_prot.c,v 1.108 2008/10/11 13:40:57 pooka Exp $    */
    2 
    3 /*
    4  * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  * (c) UNIX System Laboratories, Inc.
    7  * All or some portions of this file are derived from material licensed
    8  * to the University of California by American Telephone and Telegraph
    9  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   10  * the permission of UNIX System Laboratories, Inc.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. Neither the name of the University nor the names of its contributors
   21  *    may be used to endorse or promote products derived from this software
   22  *    without specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  *
   36  *      @(#)kern_prot.c 8.9 (Berkeley) 2/14/95
   37  */
   38 
   39 /*
   40  * System calls related to processes and protection
   41  */
   42 
   43 #include <sys/cdefs.h>
   44 __KERNEL_RCSID(0, "$NetBSD: kern_prot.c,v 1.108 2008/10/11 13:40:57 pooka Exp $");
   45 
   46 #include "opt_compat_43.h"
   47 
   48 #include <sys/param.h>
   49 #include <sys/acct.h>
   50 #include <sys/systm.h>
   51 #include <sys/ucred.h>
   52 #include <sys/proc.h>
   53 #include <sys/timeb.h>
   54 #include <sys/times.h>
   55 #include <sys/pool.h>
   56 #include <sys/prot.h>
   57 #include <sys/syslog.h>
   58 #include <sys/uidinfo.h>
   59 #include <sys/kauth.h>
   60 
   61 #include <sys/mount.h>
   62 #include <sys/syscallargs.h>
   63 
   64 int     sys_getpid(struct lwp *, const void *, register_t *);
   65 int     sys_getpid_with_ppid(struct lwp *, const void *, register_t *);
   66 int     sys_getuid(struct lwp *, const void *, register_t *);
   67 int     sys_getuid_with_euid(struct lwp *, const void *, register_t *);
   68 int     sys_getgid(struct lwp *, const void *, register_t *);
   69 int     sys_getgid_with_egid(struct lwp *, const void *, register_t *);
   70 
   71 /* ARGSUSED */
   72 int
   73 sys_getpid(struct lwp *l, const void *v, register_t *retval)
   74 {
   75         struct proc *p = l->l_proc;
   76 
   77         *retval = p->p_pid;
   78         return (0);
   79 }
   80 
   81 /* ARGSUSED */
   82 int
   83 sys_getpid_with_ppid(struct lwp *l, const void *v, register_t *retval)
   84 {
   85         struct proc *p = l->l_proc;
   86 
   87         retval[0] = p->p_pid;
   88         retval[1] = p->p_ppid;
   89         return (0);
   90 }
   91 
   92 /* ARGSUSED */
   93 int
   94 sys_getppid(struct lwp *l, const void *v, register_t *retval)
   95 {
   96         struct proc *p = l->l_proc;
   97 
   98         *retval = p->p_ppid;
   99         return (0);
  100 }
  101 
  102 /* Get process group ID; note that POSIX getpgrp takes no parameter */
  103 int
  104 sys_getpgrp(struct lwp *l, const void *v, register_t *retval)
  105 {
  106         struct proc *p = l->l_proc;
  107 
  108         mutex_enter(proc_lock);
  109         *retval = p->p_pgrp->pg_id;
  110         mutex_exit(proc_lock);
  111         return (0);
  112 }
  113 
  114 /*
  115  * Return the process group ID of the session leader (session ID)
  116  * for the specified process.
  117  */
  118 int
  119 sys_getsid(struct lwp *l, const struct sys_getsid_args *uap, register_t *retval)
  120 {
  121         /* {
  122                 syscalldarg(pid_t) pid;
  123         } */
  124         pid_t pid = SCARG(uap, pid);
  125         struct proc *p;
  126         int error = 0;
  127 
  128         mutex_enter(proc_lock);
  129         if (pid == 0)
  130                 *retval = l->l_proc->p_session->s_sid;
  131         else if ((p = p_find(pid, PFIND_LOCKED)) != NULL)
  132                 *retval = p->p_session->s_sid;
  133         else
  134                 error = ESRCH;
  135         mutex_exit(proc_lock);
  136 
  137         return error;
  138 }
  139 
  140 int
  141 sys_getpgid(struct lwp *l, const struct sys_getpgid_args *uap, register_t *retval)
  142 {
  143         /* {
  144                 syscallarg(pid_t) pid;
  145         } */
  146         pid_t pid = SCARG(uap, pid);
  147         struct proc *p;
  148         int error = 0;
  149 
  150         mutex_enter(proc_lock);
  151         if (pid == 0)
  152                 *retval = l->l_proc->p_pgid;
  153         else if ((p = p_find(pid, PFIND_LOCKED)) != NULL)
  154                 *retval = p->p_pgid;
  155         else
  156                 error = ESRCH;
  157         mutex_exit(proc_lock);
  158 
  159         return error;
  160 }
  161 
  162 /* ARGSUSED */
  163 int
  164 sys_getuid(struct lwp *l, const void *v, register_t *retval)
  165 {
  166 
  167         *retval = kauth_cred_getuid(l->l_cred);
  168         return (0);
  169 }
  170 
  171 /* ARGSUSED */
  172 int
  173 sys_getuid_with_euid(struct lwp *l, const void *v, register_t *retval)
  174 {
  175 
  176         retval[0] = kauth_cred_getuid(l->l_cred);
  177         retval[1] = kauth_cred_geteuid(l->l_cred);
  178         return (0);
  179 }
  180 
  181 /* ARGSUSED */
  182 int
  183 sys_geteuid(struct lwp *l, const void *v, register_t *retval)
  184 {
  185 
  186         *retval = kauth_cred_geteuid(l->l_cred);
  187         return (0);
  188 }
  189 
  190 /* ARGSUSED */
  191 int
  192 sys_getgid(struct lwp *l, const void *v, register_t *retval)
  193 {
  194 
  195         *retval = kauth_cred_getgid(l->l_cred);
  196         return (0);
  197 }
  198 
  199 /* ARGSUSED */
  200 int
  201 sys_getgid_with_egid(struct lwp *l, const void *v, register_t *retval)
  202 {
  203 
  204         retval[0] = kauth_cred_getgid(l->l_cred);
  205         retval[1] = kauth_cred_getegid(l->l_cred);
  206         return (0);
  207 }
  208 
  209 /*
  210  * Get effective group ID.  The "egid" is groups[0], and could be obtained
  211  * via getgroups.  This syscall exists because it is somewhat painful to do
  212  * correctly in a library function.
  213  */
  214 /* ARGSUSED */
  215 int
  216 sys_getegid(struct lwp *l, const void *v, register_t *retval)
  217 {
  218 
  219         *retval = kauth_cred_getegid(l->l_cred);
  220         return (0);
  221 }
  222 
  223 int
  224 sys_getgroups(struct lwp *l, const struct sys_getgroups_args *uap, register_t *retval)
  225 {
  226         /* {
  227                 syscallarg(int) gidsetsize;
  228                 syscallarg(gid_t *) gidset;
  229         } */
  230 
  231         *retval = kauth_cred_ngroups(l->l_cred);
  232         if (SCARG(uap, gidsetsize) == 0)
  233                 return 0;
  234         if (SCARG(uap, gidsetsize) < *retval)
  235                 return EINVAL;
  236 
  237         return kauth_cred_getgroups(l->l_cred, SCARG(uap, gidset), *retval,
  238             UIO_USERSPACE);
  239 }
  240 
  241 /* ARGSUSED */
  242 int
  243 sys_setsid(struct lwp *l, const void *v, register_t *retval)
  244 {
  245         struct proc *p = l->l_proc;
  246         int error;
  247 
  248         error = enterpgrp(p, p->p_pid, p->p_pid, 1);
  249         *retval = p->p_pid;
  250         return (error);
  251 }
  252 
  253 
  254 /*
  255  * set process group (setpgid/old setpgrp)
  256  *
  257  * caller does setpgid(targpid, targpgid)
  258  *
  259  * pgid must be in valid range (EINVAL)
  260  * pid must be caller or child of caller (ESRCH)
  261  * if a child
  262  *      pid must be in same session (EPERM)
  263  *      pid can't have done an exec (EACCES)
  264  * if pgid != pid
  265  *      there must exist some pid in same session having pgid (EPERM)
  266  * pid must not be session leader (EPERM)
  267  *
  268  * Permission checks now in enterpgrp()
  269  */
  270 /* ARGSUSED */
  271 int
  272 sys_setpgid(struct lwp *l, const struct sys_setpgid_args *uap, register_t *retval)
  273 {
  274         /* {
  275                 syscallarg(int) pid;
  276                 syscallarg(int) pgid;
  277         } */
  278         struct proc *p = l->l_proc;
  279         pid_t targp, pgid;
  280 
  281         if (SCARG(uap, pgid) < 0)
  282                 return EINVAL;
  283         if ((targp = SCARG(uap, pid)) == 0)
  284                 targp = p->p_pid;
  285         if ((pgid = SCARG(uap, pgid)) == 0)
  286                 pgid = targp;
  287 
  288         return enterpgrp(p, targp, pgid, 0);
  289 }
  290 
  291 /*
  292  * Set real, effective and saved uids to the requested values.
  293  * non-root callers can only ever change uids to values that match
  294  * one of the processes current uid values.
  295  * This is further restricted by the flags argument.
  296  */
  297 
  298 int
  299 do_setresuid(struct lwp *l, uid_t r, uid_t e, uid_t sv, u_int flags)
  300 {
  301         struct proc *p = l->l_proc;
  302         kauth_cred_t cred, ncred;
  303 
  304         ncred = kauth_cred_alloc();
  305 
  306         /* Get a write lock on the process credential. */
  307         proc_crmod_enter();
  308         cred = p->p_cred;
  309 
  310         /*
  311          * Check that the new value is one of the allowed existing values,
  312          * or that we have root privilege.
  313          */
  314         if ((r != -1
  315             && !((flags & ID_R_EQ_R) && r == kauth_cred_getuid(cred))
  316             && !((flags & ID_R_EQ_E) && r == kauth_cred_geteuid(cred))
  317             && !((flags & ID_R_EQ_S) && r == kauth_cred_getsvuid(cred))) ||
  318             (e != -1
  319             && !((flags & ID_E_EQ_R) && e == kauth_cred_getuid(cred))
  320             && !((flags & ID_E_EQ_E) && e == kauth_cred_geteuid(cred))
  321             && !((flags & ID_E_EQ_S) && e == kauth_cred_getsvuid(cred))) ||
  322             (sv != -1
  323             && !((flags & ID_S_EQ_R) && sv == kauth_cred_getuid(cred))
  324             && !((flags & ID_S_EQ_E) && sv == kauth_cred_geteuid(cred))
  325             && !((flags & ID_S_EQ_S) && sv == kauth_cred_getsvuid(cred)))) {
  326                 int error;
  327 
  328                 error = kauth_authorize_process(cred, KAUTH_PROCESS_SETID,
  329                     p, NULL, NULL, NULL);
  330                 if (error != 0) {
  331                         proc_crmod_leave(cred, ncred, false);
  332                         return error;
  333                 }
  334         }
  335 
  336         /* If nothing has changed, short circuit the request */
  337         if ((r == -1 || r == kauth_cred_getuid(cred))
  338             && (e == -1 || e == kauth_cred_geteuid(cred))
  339             && (sv == -1 || sv == kauth_cred_getsvuid(cred))) {
  340                 proc_crmod_leave(cred, ncred, false);
  341                 return 0;
  342         }
  343 
  344         kauth_cred_clone(cred, ncred);
  345 
  346         if (r != -1 && r != kauth_cred_getuid(ncred)) {
  347                 /* Update count of processes for this user */
  348                 (void)chgproccnt(kauth_cred_getuid(ncred), -1);
  349                 (void)chgproccnt(r, 1);
  350                 kauth_cred_setuid(ncred, r);
  351         }
  352         if (sv != -1)
  353                 kauth_cred_setsvuid(ncred, sv);
  354         if (e != -1)
  355                 kauth_cred_seteuid(ncred, e);
  356 
  357         /* Broadcast our credentials to the process and other LWPs. */
  358         proc_crmod_leave(ncred, cred, true);
  359 
  360         return 0;
  361 }
  362 
  363 /*
  364  * Set real, effective and saved gids to the requested values.
  365  * non-root callers can only ever change gids to values that match
  366  * one of the processes current gid values.
  367  * This is further restricted by the flags argument.
  368  */
  369 
  370 int
  371 do_setresgid(struct lwp *l, gid_t r, gid_t e, gid_t sv, u_int flags)
  372 {
  373         struct proc *p = l->l_proc;
  374         kauth_cred_t cred, ncred;
  375 
  376         ncred = kauth_cred_alloc();
  377 
  378         /* Get a write lock on the process credential. */
  379         proc_crmod_enter();
  380         cred = p->p_cred;
  381 
  382         /*
  383          * check new value is one of the allowed existing values.
  384          * otherwise, check if we have root privilege.
  385          */
  386         if ((r != -1
  387             && !((flags & ID_R_EQ_R) && r == kauth_cred_getgid(cred))
  388             && !((flags & ID_R_EQ_E) && r == kauth_cred_getegid(cred))
  389             && !((flags & ID_R_EQ_S) && r == kauth_cred_getsvgid(cred))) ||
  390             (e != -1
  391             && !((flags & ID_E_EQ_R) && e == kauth_cred_getgid(cred))
  392             && !((flags & ID_E_EQ_E) && e == kauth_cred_getegid(cred))
  393             && !((flags & ID_E_EQ_S) && e == kauth_cred_getsvgid(cred))) ||
  394             (sv != -1
  395             && !((flags & ID_S_EQ_R) && sv == kauth_cred_getgid(cred))
  396             && !((flags & ID_S_EQ_E) && sv == kauth_cred_getegid(cred))
  397             && !((flags & ID_S_EQ_S) && sv == kauth_cred_getsvgid(cred)))) {
  398                 int error;
  399 
  400                 error = kauth_authorize_process(cred, KAUTH_PROCESS_SETID,
  401                     p, NULL, NULL, NULL);
  402                 if (error != 0) {
  403                         proc_crmod_leave(cred, ncred, false);
  404                         return error;
  405                 }
  406         }
  407 
  408         /* If nothing has changed, short circuit the request */
  409         if ((r == -1 || r == kauth_cred_getgid(cred))
  410             && (e == -1 || e == kauth_cred_getegid(cred))
  411             && (sv == -1 || sv == kauth_cred_getsvgid(cred))) {
  412                 proc_crmod_leave(cred, ncred, false);
  413                 return 0;
  414         }
  415 
  416         kauth_cred_clone(cred, ncred);
  417 
  418         if (r != -1)
  419                 kauth_cred_setgid(ncred, r);
  420         if (sv != -1)
  421                 kauth_cred_setsvgid(ncred, sv);
  422         if (e != -1)
  423                 kauth_cred_setegid(ncred, e);
  424 
  425         /* Broadcast our credentials to the process and other LWPs. */
  426         proc_crmod_leave(ncred, cred, true);
  427 
  428         return 0;
  429 }
  430 
  431 /* ARGSUSED */
  432 int
  433 sys_setuid(struct lwp *l, const struct sys_setuid_args *uap, register_t *retval)
  434 {
  435         /* {
  436                 syscallarg(uid_t) uid;
  437         } */
  438         uid_t uid = SCARG(uap, uid);
  439 
  440         return do_setresuid(l, uid, uid, uid,
  441                             ID_R_EQ_R | ID_E_EQ_R | ID_S_EQ_R);
  442 }
  443 
  444 /* ARGSUSED */
  445 int
  446 sys_seteuid(struct lwp *l, const struct sys_seteuid_args *uap, register_t *retval)
  447 {
  448         /* {
  449                 syscallarg(uid_t) euid;
  450         } */
  451 
  452         return do_setresuid(l, -1, SCARG(uap, euid), -1, ID_E_EQ_R | ID_E_EQ_S);
  453 }
  454 
  455 int
  456 sys_setreuid(struct lwp *l, const struct sys_setreuid_args *uap, register_t *retval)
  457 {
  458         /* {
  459                 syscallarg(uid_t) ruid;
  460                 syscallarg(uid_t) euid;
  461         } */
  462         kauth_cred_t cred = l->l_cred;
  463         uid_t ruid, euid, svuid;
  464 
  465         ruid = SCARG(uap, ruid);
  466         euid = SCARG(uap, euid);
  467 
  468         if (ruid == -1)
  469                 ruid = kauth_cred_getuid(cred);
  470         if (euid == -1)
  471                 euid = kauth_cred_geteuid(cred);
  472 
  473         /* Saved uid is set to the new euid if the ruid changed */
  474         svuid = (ruid == kauth_cred_getuid(cred)) ? -1 : euid;
  475 
  476         return do_setresuid(l, ruid, euid, svuid,
  477                             ID_R_EQ_R | ID_R_EQ_E |
  478                             ID_E_EQ_R | ID_E_EQ_E | ID_E_EQ_S |
  479                             ID_S_EQ_R | ID_S_EQ_E | ID_S_EQ_S);
  480 }
  481 
  482 /* ARGSUSED */
  483 int
  484 sys_setgid(struct lwp *l, const struct sys_setgid_args *uap, register_t *retval)
  485 {
  486         /* {
  487                 syscallarg(gid_t) gid;
  488         } */
  489         gid_t gid = SCARG(uap, gid);
  490 
  491         return do_setresgid(l, gid, gid, gid,
  492                             ID_R_EQ_R | ID_E_EQ_R | ID_S_EQ_R);
  493 }
  494 
  495 /* ARGSUSED */
  496 int
  497 sys_setegid(struct lwp *l, const struct sys_setegid_args *uap, register_t *retval)
  498 {
  499         /* {
  500                 syscallarg(gid_t) egid;
  501         } */
  502 
  503         return do_setresgid(l, -1, SCARG(uap, egid), -1, ID_E_EQ_R | ID_E_EQ_S);
  504 }
  505 
  506 int
  507 sys_setregid(struct lwp *l, const struct sys_setregid_args *uap, register_t *retval)
  508 {
  509         /* {
  510                 syscallarg(gid_t) rgid;
  511                 syscallarg(gid_t) egid;
  512         } */
  513         kauth_cred_t cred = l->l_cred;
  514         gid_t rgid, egid, svgid;
  515 
  516         rgid = SCARG(uap, rgid);
  517         egid = SCARG(uap, egid);
  518 
  519         if (rgid == -1)
  520                 rgid = kauth_cred_getgid(cred);
  521         if (egid == -1)
  522                 egid = kauth_cred_getegid(cred);
  523 
  524         /* Saved gid is set to the new egid if the rgid changed */
  525         svgid = rgid == kauth_cred_getgid(cred) ? -1 : egid;
  526 
  527         return do_setresgid(l, rgid, egid, svgid,
  528                         ID_R_EQ_R | ID_R_EQ_E |
  529                         ID_E_EQ_R | ID_E_EQ_E | ID_E_EQ_S |
  530                         ID_S_EQ_R | ID_S_EQ_E | ID_S_EQ_S);
  531 }
  532 
  533 int
  534 sys_issetugid(struct lwp *l, const void *v, register_t *retval)
  535 {
  536         struct proc *p = l->l_proc;
  537 
  538         /*
  539          * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
  540          * we use PK_SUGID because we consider changing the owners as
  541          * "tainting" as well.
  542          * This is significant for procs that start as root and "become"
  543          * a user without an exec - programs cannot know *everything*
  544          * that libc *might* have put in their data segment.
  545          */
  546         *retval = (p->p_flag & PK_SUGID) != 0;
  547         return (0);
  548 }
  549 
  550 /* ARGSUSED */
  551 int
  552 sys_setgroups(struct lwp *l, const struct sys_setgroups_args *uap, register_t *retval)
  553 {
  554         /* {
  555                 syscallarg(int) gidsetsize;
  556                 syscallarg(const gid_t *) gidset;
  557         } */
  558         kauth_cred_t ncred;
  559         int error;
  560 
  561         ncred = kauth_cred_alloc();
  562         error = kauth_cred_setgroups(ncred, SCARG(uap, gidset),
  563             SCARG(uap, gidsetsize), -1, UIO_USERSPACE);
  564         if (error != 0) {
  565                 kauth_cred_free(ncred);
  566                 return error;
  567         }
  568 
  569         return kauth_proc_setgroups(l, ncred);
  570 }
  571 
  572 /*
  573  * Get login name, if available.
  574  */
  575 /* ARGSUSED */
  576 int
  577 sys___getlogin(struct lwp *l, const struct sys___getlogin_args *uap, register_t *retval)
  578 {
  579         /* {
  580                 syscallarg(char *) namebuf;
  581                 syscallarg(size_t) namelen;
  582         } */
  583         struct proc *p = l->l_proc;
  584         char login[sizeof(p->p_session->s_login)];
  585         int namelen = SCARG(uap, namelen);
  586 
  587         if (namelen > sizeof(login))
  588                 namelen = sizeof(login);
  589         mutex_enter(proc_lock);
  590         memcpy(login, p->p_session->s_login, namelen);
  591         mutex_exit(proc_lock);
  592         return (copyout(login, (void *)SCARG(uap, namebuf), namelen));
  593 }
  594 
  595 /*
  596  * Set login name.
  597  */
  598 /* ARGSUSED */
  599 int
  600 sys___setlogin(struct lwp *l, const struct sys___setlogin_args *uap, register_t *retval)
  601 {
  602         /* {
  603                 syscallarg(const char *) namebuf;
  604         } */
  605         struct proc *p = l->l_proc;
  606         struct session *sp;
  607         char newname[sizeof sp->s_login + 1];
  608         int error;
  609 
  610         if ((error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_SETID,
  611             p, NULL, NULL, NULL)) != 0)
  612                 return (error);
  613         error = copyinstr(SCARG(uap, namebuf), &newname, sizeof newname, NULL);
  614         if (error != 0)
  615                 return (error == ENAMETOOLONG ? EINVAL : error);
  616 
  617         mutex_enter(proc_lock);
  618         sp = p->p_session;
  619         if (sp->s_flags & S_LOGIN_SET && p->p_pid != sp->s_sid &&
  620             strncmp(newname, sp->s_login, sizeof sp->s_login) != 0)
  621                 log(LOG_WARNING, "%s (pid %d) changing logname from "
  622                     "%.*s to %s\n", p->p_comm, p->p_pid,
  623                     (int)sizeof sp->s_login, sp->s_login, newname);
  624         sp->s_flags |= S_LOGIN_SET;
  625         strncpy(sp->s_login, newname, sizeof sp->s_login);
  626         mutex_exit(proc_lock);
  627         return (0);
  628 }
  629 

Cache object: 5fa550558dbb13fca8072d8ae64aee23


[ 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.