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/security/audit/audit_arg.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 /*
    2  * Copyright (c) 1999-2005 Apple Computer, Inc.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1.  Redistributions of source code must retain the above copyright
    9  *     notice, this list of conditions and the following disclaimer.
   10  * 2.  Redistributions in binary form must reproduce the above copyright
   11  *     notice, this list of conditions and the following disclaimer in the
   12  *     documentation and/or other materials provided with the distribution.
   13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
   14  *     its contributors may be used to endorse or promote products derived
   15  *     from this software without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
   21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   26  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   27  * POSSIBILITY OF SUCH DAMAGE.
   28  *
   29  * $FreeBSD: releng/6.2/sys/security/audit/audit_arg.c 164286 2006-11-14 20:42:41Z cvs2svn $
   30  */
   31 
   32 #include <sys/param.h>
   33 #include <sys/filedesc.h>
   34 #include <sys/ipc.h>
   35 #include <sys/mount.h>
   36 #include <sys/proc.h>
   37 #include <sys/socket.h>
   38 #include <sys/socketvar.h>
   39 #include <sys/protosw.h>
   40 #include <sys/domain.h>
   41 #include <sys/sbuf.h>
   42 #include <sys/systm.h>
   43 #include <sys/un.h>
   44 #include <sys/vnode.h>
   45 
   46 #include <netinet/in.h>
   47 #include <netinet/in_pcb.h>
   48 
   49 #include <security/audit/audit.h>
   50 #include <security/audit/audit_private.h>
   51 
   52 /*
   53  * Calls to manipulate elements of the audit record structure from system
   54  * call code.  Macro wrappers will prevent this functions from being
   55  * entered if auditing is disabled, avoiding the function call cost.  We
   56  * check the thread audit record pointer anyway, as the audit condition
   57  * could change, and pre-selection may not have allocated an audit
   58  * record for this event.
   59  *
   60  * XXXAUDIT: Should we assert, in each case, that this field of the record
   61  * hasn't already been filled in?
   62  */
   63 void
   64 audit_arg_addr(void * addr)
   65 {
   66         struct kaudit_record *ar;
   67 
   68         ar = currecord();
   69         if (ar == NULL)
   70                 return;
   71 
   72         ar->k_ar.ar_arg_addr = addr;
   73         ARG_SET_VALID(ar, ARG_ADDR);
   74 }
   75 
   76 void
   77 audit_arg_exit(int status, int retval)
   78 {
   79         struct kaudit_record *ar;
   80 
   81         ar = currecord();
   82         if (ar == NULL)
   83                 return;
   84 
   85         ar->k_ar.ar_arg_exitstatus = status;
   86         ar->k_ar.ar_arg_exitretval = retval;
   87         ARG_SET_VALID(ar, ARG_EXIT);
   88 }
   89 
   90 void
   91 audit_arg_len(int len)
   92 {
   93         struct kaudit_record *ar;
   94 
   95         ar = currecord();
   96         if (ar == NULL)
   97                 return;
   98 
   99         ar->k_ar.ar_arg_len = len;
  100         ARG_SET_VALID(ar, ARG_LEN);
  101 }
  102 
  103 void
  104 audit_arg_fd(int fd)
  105 {
  106         struct kaudit_record *ar;
  107 
  108         ar = currecord();
  109         if (ar == NULL)
  110                 return;
  111 
  112         ar->k_ar.ar_arg_fd = fd;
  113         ARG_SET_VALID(ar, ARG_FD);
  114 }
  115 
  116 void
  117 audit_arg_fflags(int fflags)
  118 {
  119         struct kaudit_record *ar;
  120 
  121         ar = currecord();
  122         if (ar == NULL)
  123                 return;
  124 
  125         ar->k_ar.ar_arg_fflags = fflags;
  126         ARG_SET_VALID(ar, ARG_FFLAGS);
  127 }
  128 
  129 void
  130 audit_arg_gid(gid_t gid)
  131 {
  132         struct kaudit_record *ar;
  133 
  134         ar = currecord();
  135         if (ar == NULL)
  136                 return;
  137 
  138         ar->k_ar.ar_arg_gid = gid;
  139         ARG_SET_VALID(ar, ARG_GID);
  140 }
  141 
  142 void
  143 audit_arg_uid(uid_t uid)
  144 {
  145         struct kaudit_record *ar;
  146 
  147         ar = currecord();
  148         if (ar == NULL)
  149                 return;
  150 
  151         ar->k_ar.ar_arg_uid = uid;
  152         ARG_SET_VALID(ar, ARG_UID);
  153 }
  154 
  155 void
  156 audit_arg_egid(gid_t egid)
  157 {
  158         struct kaudit_record *ar;
  159 
  160         ar = currecord();
  161         if (ar == NULL)
  162                 return;
  163 
  164         ar->k_ar.ar_arg_egid = egid;
  165         ARG_SET_VALID(ar, ARG_EGID);
  166 }
  167 
  168 void
  169 audit_arg_euid(uid_t euid)
  170 {
  171         struct kaudit_record *ar;
  172 
  173         ar = currecord();
  174         if (ar == NULL)
  175                 return;
  176 
  177         ar->k_ar.ar_arg_euid = euid;
  178         ARG_SET_VALID(ar, ARG_EUID);
  179 }
  180 
  181 void
  182 audit_arg_rgid(gid_t rgid)
  183 {
  184         struct kaudit_record *ar;
  185 
  186         ar = currecord();
  187         if (ar == NULL)
  188                 return;
  189 
  190         ar->k_ar.ar_arg_rgid = rgid;
  191         ARG_SET_VALID(ar, ARG_RGID);
  192 }
  193 
  194 void
  195 audit_arg_ruid(uid_t ruid)
  196 {
  197         struct kaudit_record *ar;
  198 
  199         ar = currecord();
  200         if (ar == NULL)
  201                 return;
  202 
  203         ar->k_ar.ar_arg_ruid = ruid;
  204         ARG_SET_VALID(ar, ARG_RUID);
  205 }
  206 
  207 void
  208 audit_arg_sgid(gid_t sgid)
  209 {
  210         struct kaudit_record *ar;
  211 
  212         ar = currecord();
  213         if (ar == NULL)
  214                 return;
  215 
  216         ar->k_ar.ar_arg_sgid = sgid;
  217         ARG_SET_VALID(ar, ARG_SGID);
  218 }
  219 
  220 void
  221 audit_arg_suid(uid_t suid)
  222 {
  223         struct kaudit_record *ar;
  224 
  225         ar = currecord();
  226         if (ar == NULL)
  227                 return;
  228 
  229         ar->k_ar.ar_arg_suid = suid;
  230         ARG_SET_VALID(ar, ARG_SUID);
  231 }
  232 
  233 void
  234 audit_arg_groupset(gid_t *gidset, u_int gidset_size)
  235 {
  236         int i;
  237         struct kaudit_record *ar;
  238 
  239         ar = currecord();
  240         if (ar == NULL)
  241                 return;
  242 
  243         for (i = 0; i < gidset_size; i++)
  244                 ar->k_ar.ar_arg_groups.gidset[i] = gidset[i];
  245         ar->k_ar.ar_arg_groups.gidset_size = gidset_size;
  246         ARG_SET_VALID(ar, ARG_GROUPSET);
  247 }
  248 
  249 void
  250 audit_arg_login(char *login)
  251 {
  252         struct kaudit_record *ar;
  253 
  254         ar = currecord();
  255         if (ar == NULL)
  256                 return;
  257 
  258         strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME);
  259         ARG_SET_VALID(ar, ARG_LOGIN);
  260 }
  261 
  262 void
  263 audit_arg_ctlname(int *name, int namelen)
  264 {
  265         struct kaudit_record *ar;
  266 
  267         ar = currecord();
  268         if (ar == NULL)
  269                 return;
  270 
  271         bcopy(name, &ar->k_ar.ar_arg_ctlname, namelen * sizeof(int));
  272         ar->k_ar.ar_arg_len = namelen;
  273         ARG_SET_VALID(ar, ARG_CTLNAME | ARG_LEN);
  274 }
  275 
  276 void
  277 audit_arg_mask(int mask)
  278 {
  279         struct kaudit_record *ar;
  280 
  281         ar = currecord();
  282         if (ar == NULL)
  283                 return;
  284 
  285         ar->k_ar.ar_arg_mask = mask;
  286         ARG_SET_VALID(ar, ARG_MASK);
  287 }
  288 
  289 void
  290 audit_arg_mode(mode_t mode)
  291 {
  292         struct kaudit_record *ar;
  293 
  294         ar = currecord();
  295         if (ar == NULL)
  296                 return;
  297 
  298         ar->k_ar.ar_arg_mode = mode;
  299         ARG_SET_VALID(ar, ARG_MODE);
  300 }
  301 
  302 void
  303 audit_arg_dev(int dev)
  304 {
  305         struct kaudit_record *ar;
  306 
  307         ar = currecord();
  308         if (ar == NULL)
  309                 return;
  310 
  311         ar->k_ar.ar_arg_dev = dev;
  312         ARG_SET_VALID(ar, ARG_DEV);
  313 }
  314 
  315 void
  316 audit_arg_value(long value)
  317 {
  318         struct kaudit_record *ar;
  319 
  320         ar = currecord();
  321         if (ar == NULL)
  322                 return;
  323 
  324         ar->k_ar.ar_arg_value = value;
  325         ARG_SET_VALID(ar, ARG_VALUE);
  326 }
  327 
  328 void
  329 audit_arg_owner(uid_t uid, gid_t gid)
  330 {
  331         struct kaudit_record *ar;
  332 
  333         ar = currecord();
  334         if (ar == NULL)
  335                 return;
  336 
  337         ar->k_ar.ar_arg_uid = uid;
  338         ar->k_ar.ar_arg_gid = gid;
  339         ARG_SET_VALID(ar, ARG_UID | ARG_GID);
  340 }
  341 
  342 void
  343 audit_arg_pid(pid_t pid)
  344 {
  345         struct kaudit_record *ar;
  346 
  347         ar = currecord();
  348         if (ar == NULL)
  349                 return;
  350 
  351         ar->k_ar.ar_arg_pid = pid;
  352         ARG_SET_VALID(ar, ARG_PID);
  353 }
  354 
  355 void
  356 audit_arg_process(struct proc *p)
  357 {
  358         struct kaudit_record *ar;
  359 
  360         KASSERT(p != NULL, ("audit_arg_process: p == NULL"));
  361 
  362         PROC_LOCK_ASSERT(p, MA_OWNED);
  363 
  364         ar = currecord();
  365         if (ar == NULL)
  366                 return;
  367 
  368         ar->k_ar.ar_arg_auid = p->p_au->ai_auid;
  369         ar->k_ar.ar_arg_euid = p->p_ucred->cr_uid;
  370         ar->k_ar.ar_arg_egid = p->p_ucred->cr_groups[0];
  371         ar->k_ar.ar_arg_ruid = p->p_ucred->cr_ruid;
  372         ar->k_ar.ar_arg_rgid = p->p_ucred->cr_rgid;
  373         ar->k_ar.ar_arg_asid = p->p_au->ai_asid;
  374         ar->k_ar.ar_arg_termid = p->p_au->ai_termid;
  375         ar->k_ar.ar_arg_pid = p->p_pid;
  376         ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID |
  377             ARG_RGID | ARG_ASID | ARG_TERMID | ARG_PID | ARG_PROCESS);
  378 }
  379 
  380 void
  381 audit_arg_signum(u_int signum)
  382 {
  383         struct kaudit_record *ar;
  384 
  385         ar = currecord();
  386         if (ar == NULL)
  387                 return;
  388 
  389         ar->k_ar.ar_arg_signum = signum;
  390         ARG_SET_VALID(ar, ARG_SIGNUM);
  391 }
  392 
  393 void
  394 audit_arg_socket(int sodomain, int sotype, int soprotocol)
  395 {
  396         struct kaudit_record *ar;
  397 
  398         ar = currecord();
  399         if (ar == NULL)
  400                 return;
  401 
  402         ar->k_ar.ar_arg_sockinfo.so_domain = sodomain;
  403         ar->k_ar.ar_arg_sockinfo.so_type = sotype;
  404         ar->k_ar.ar_arg_sockinfo.so_protocol = soprotocol;
  405         ARG_SET_VALID(ar, ARG_SOCKINFO);
  406 }
  407 
  408 void
  409 audit_arg_sockaddr(struct thread *td, struct sockaddr *sa)
  410 {
  411         struct kaudit_record *ar;
  412 
  413         KASSERT(td != NULL, ("audit_arg_sockaddr: td == NULL"));
  414         KASSERT(sa != NULL, ("audit_arg_sockaddr: sa == NULL"));
  415 
  416         ar = currecord();
  417         if (ar == NULL)
  418                 return;
  419 
  420         bcopy(sa, &ar->k_ar.ar_arg_sockaddr,
  421             sizeof(ar->k_ar.ar_arg_sockaddr));
  422         switch (sa->sa_family) {
  423         case AF_INET:
  424                 ARG_SET_VALID(ar, ARG_SADDRINET);
  425                 break;
  426 
  427         case AF_INET6:
  428                 ARG_SET_VALID(ar, ARG_SADDRINET6);
  429                 break;
  430 
  431         case AF_UNIX:
  432                 audit_arg_upath(td, ((struct sockaddr_un *)sa)->sun_path,
  433                                 ARG_UPATH1);
  434                 ARG_SET_VALID(ar, ARG_SADDRUNIX);
  435                 break;
  436         /* XXXAUDIT: default:? */
  437         }
  438 }
  439 
  440 void
  441 audit_arg_auid(uid_t auid)
  442 {
  443         struct kaudit_record *ar;
  444 
  445         ar = currecord();
  446         if (ar == NULL)
  447                 return;
  448 
  449         ar->k_ar.ar_arg_auid = auid;
  450         ARG_SET_VALID(ar, ARG_AUID);
  451 }
  452 
  453 void
  454 audit_arg_auditinfo(struct auditinfo *au_info)
  455 {
  456         struct kaudit_record *ar;
  457 
  458         ar = currecord();
  459         if (ar == NULL)
  460                 return;
  461 
  462         ar->k_ar.ar_arg_auid = au_info->ai_auid;
  463         ar->k_ar.ar_arg_asid = au_info->ai_asid;
  464         ar->k_ar.ar_arg_amask.am_success = au_info->ai_mask.am_success;
  465         ar->k_ar.ar_arg_amask.am_failure = au_info->ai_mask.am_failure;
  466         ar->k_ar.ar_arg_termid.port = au_info->ai_termid.port;
  467         ar->k_ar.ar_arg_termid.machine = au_info->ai_termid.machine;
  468         ARG_SET_VALID(ar, ARG_AUID | ARG_ASID | ARG_AMASK | ARG_TERMID);
  469 }
  470 
  471 void
  472 audit_arg_text(char *text)
  473 {
  474         struct kaudit_record *ar;
  475 
  476         KASSERT(text != NULL, ("audit_arg_text: text == NULL"));
  477 
  478         ar = currecord();
  479         if (ar == NULL)
  480                 return;
  481 
  482         /* Invalidate the text string */
  483         ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT);
  484 
  485         if (ar->k_ar.ar_arg_text == NULL)
  486                 ar->k_ar.ar_arg_text = malloc(MAXPATHLEN, M_AUDITTEXT,
  487                     M_WAITOK);
  488 
  489         strncpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN);
  490         ARG_SET_VALID(ar, ARG_TEXT);
  491 }
  492 
  493 void
  494 audit_arg_cmd(int cmd)
  495 {
  496         struct kaudit_record *ar;
  497 
  498         ar = currecord();
  499         if (ar == NULL)
  500                 return;
  501 
  502         ar->k_ar.ar_arg_cmd = cmd;
  503         ARG_SET_VALID(ar, ARG_CMD);
  504 }
  505 
  506 void
  507 audit_arg_svipc_cmd(int cmd)
  508 {
  509         struct kaudit_record *ar;
  510 
  511         ar = currecord();
  512         if (ar == NULL)
  513                 return;
  514 
  515         ar->k_ar.ar_arg_svipc_cmd = cmd;
  516         ARG_SET_VALID(ar, ARG_SVIPC_CMD);
  517 }
  518 
  519 void
  520 audit_arg_svipc_perm(struct ipc_perm *perm)
  521 {
  522         struct kaudit_record *ar;
  523 
  524         ar = currecord();
  525         if (ar == NULL)
  526                 return;
  527 
  528         bcopy(perm, &ar->k_ar.ar_arg_svipc_perm,
  529             sizeof(ar->k_ar.ar_arg_svipc_perm));
  530         ARG_SET_VALID(ar, ARG_SVIPC_PERM);
  531 }
  532 
  533 void
  534 audit_arg_svipc_id(int id)
  535 {
  536         struct kaudit_record *ar;
  537 
  538         ar = currecord();
  539         if (ar == NULL)
  540                 return;
  541 
  542         ar->k_ar.ar_arg_svipc_id = id;
  543         ARG_SET_VALID(ar, ARG_SVIPC_ID);
  544 }
  545 
  546 void
  547 audit_arg_svipc_addr(void * addr)
  548 {
  549         struct kaudit_record *ar;
  550 
  551         ar = currecord();
  552         if (ar == NULL)
  553                 return;
  554 
  555         ar->k_ar.ar_arg_svipc_addr = addr;
  556         ARG_SET_VALID(ar, ARG_SVIPC_ADDR);
  557 }
  558 
  559 void
  560 audit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode)
  561 {
  562         struct kaudit_record *ar;
  563 
  564         ar = currecord();
  565         if (ar == NULL)
  566                 return;
  567 
  568         ar->k_ar.ar_arg_pipc_perm.pipc_uid = uid;
  569         ar->k_ar.ar_arg_pipc_perm.pipc_gid = gid;
  570         ar->k_ar.ar_arg_pipc_perm.pipc_mode = mode;
  571         ARG_SET_VALID(ar, ARG_POSIX_IPC_PERM);
  572 }
  573 
  574 void
  575 audit_arg_auditon(union auditon_udata *udata)
  576 {
  577         struct kaudit_record *ar;
  578 
  579         ar = currecord();
  580         if (ar == NULL)
  581                 return;
  582 
  583         bcopy((void *)udata, &ar->k_ar.ar_arg_auditon,
  584             sizeof(ar->k_ar.ar_arg_auditon));
  585         ARG_SET_VALID(ar, ARG_AUDITON);
  586 }
  587 
  588 /*
  589  * Audit information about a file, either the file's vnode info, or its
  590  * socket address info.
  591  */
  592 void
  593 audit_arg_file(struct proc *p, struct file *fp)
  594 {
  595         struct kaudit_record *ar;
  596         struct socket *so;
  597         struct inpcb *pcb;
  598         struct vnode *vp;
  599         int vfslocked;
  600 
  601         ar = currecord();
  602         if (ar == NULL)
  603                 return;
  604 
  605         switch (fp->f_type) {
  606         case DTYPE_VNODE:
  607         case DTYPE_FIFO:
  608                 /*
  609                  * XXXAUDIT: Only possibly to record as first vnode?
  610                  */
  611                 vp = fp->f_vnode;
  612                 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
  613                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
  614                 audit_arg_vnode(vp, ARG_VNODE1);
  615                 VOP_UNLOCK(vp, 0, curthread);
  616                 VFS_UNLOCK_GIANT(vfslocked);
  617                 break;
  618 
  619         case DTYPE_SOCKET:
  620                 so = (struct socket *)fp->f_data;
  621                 SOCK_LOCK(so);
  622                 if (INP_CHECK_SOCKAF(so, PF_INET)) {
  623                         if (so->so_pcb == NULL)
  624                                 return;
  625                         ar->k_ar.ar_arg_sockinfo.so_type =
  626                             so->so_type;
  627                         ar->k_ar.ar_arg_sockinfo.so_domain =
  628                             INP_SOCKAF(so);
  629                         ar->k_ar.ar_arg_sockinfo.so_protocol =
  630                             so->so_proto->pr_protocol;
  631                         pcb = (struct inpcb *)so->so_pcb;
  632                         ar->k_ar.ar_arg_sockinfo.so_raddr =
  633                             pcb->inp_faddr.s_addr;
  634                         ar->k_ar.ar_arg_sockinfo.so_laddr =
  635                             pcb->inp_laddr.s_addr;
  636                         ar->k_ar.ar_arg_sockinfo.so_rport =
  637                             pcb->inp_fport;
  638                         ar->k_ar.ar_arg_sockinfo.so_lport =
  639                             pcb->inp_lport;
  640                         ARG_SET_VALID(ar, ARG_SOCKINFO);
  641                 }
  642                 SOCK_UNLOCK(so);
  643                 break;
  644 
  645         default:
  646                 /* XXXAUDIT: else? */
  647                 break;
  648         }
  649 
  650 }
  651 
  652 /*
  653  * Store a path as given by the user process for auditing into the audit
  654  * record stored on the user thread. This function will allocate the memory
  655  * to store the path info if not already available. This memory will be freed
  656  * when the audit record is freed.
  657  *
  658  * XXXAUDIT: Possibly assert that the memory isn't already allocated?
  659  */
  660 void
  661 audit_arg_upath(struct thread *td, char *upath, u_int64_t flag)
  662 {
  663         struct kaudit_record *ar;
  664         char **pathp;
  665 
  666         KASSERT(td != NULL, ("audit_arg_upath: td == NULL"));
  667         KASSERT(upath != NULL, ("audit_arg_upath: upath == NULL"));
  668 
  669         ar = currecord();
  670         if (ar == NULL)
  671                 return;
  672 
  673         /*
  674          * XXXAUDIT: Witness warning for possible sleep here?
  675          */
  676         KASSERT((flag == ARG_UPATH1) || (flag == ARG_UPATH2),
  677             ("audit_arg_upath: flag %llu", (unsigned long long)flag));
  678         KASSERT((flag != ARG_UPATH1) || (flag != ARG_UPATH2),
  679             ("audit_arg_upath: flag %llu", (unsigned long long)flag));
  680 
  681         if (flag == ARG_UPATH1)
  682                 pathp = &ar->k_ar.ar_arg_upath1;
  683         else
  684                 pathp = &ar->k_ar.ar_arg_upath2;
  685 
  686         if (*pathp == NULL)
  687                 *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK);
  688 
  689         canon_path(td, upath, *pathp);
  690 
  691         ARG_SET_VALID(ar, flag);
  692 }
  693 
  694 /*
  695  * Function to save the path and vnode attr information into the audit
  696  * record.
  697  *
  698  * It is assumed that the caller will hold any vnode locks necessary to
  699  * perform a VOP_GETATTR() on the passed vnode.
  700  *
  701  * XXX: The attr code is very similar to vfs_vnops.c:vn_stat(), but
  702  * always provides access to the generation number as we need that
  703  * to construct the BSM file ID.
  704  * XXX: We should accept the process argument from the caller, since
  705  * it's very likely they already have a reference.
  706  * XXX: Error handling in this function is poor.
  707  *
  708  * XXXAUDIT: Possibly KASSERT the path pointer is NULL?
  709  */
  710 void
  711 audit_arg_vnode(struct vnode *vp, u_int64_t flags)
  712 {
  713         struct kaudit_record *ar;
  714         struct vattr vattr;
  715         int error;
  716         struct vnode_au_info *vnp;
  717 
  718         KASSERT(vp != NULL, ("audit_arg_vnode: vp == NULL"));
  719         KASSERT((flags == ARG_VNODE1) || (flags == ARG_VNODE2),
  720             ("audit_arg_vnode: flags %jd", (intmax_t)flags));
  721 
  722         /*
  723          * Assume that if the caller is calling audit_arg_vnode() on a
  724          * non-MPSAFE vnode, then it will have acquired Giant.
  725          */
  726         VFS_ASSERT_GIANT(vp->v_mount);
  727         ASSERT_VOP_LOCKED(vp, "audit_arg_vnode");
  728 
  729         ar = currecord();
  730         if (ar == NULL)
  731                 return;
  732 
  733         /*
  734          * XXXAUDIT: The below clears, and then resets the flags for valid
  735          * arguments.  Ideally, either the new vnode is used, or the old one
  736          * would be.
  737          */
  738         if (flags & ARG_VNODE1) {
  739                 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE1);
  740                 vnp = &ar->k_ar.ar_arg_vnode1;
  741         } else {
  742                 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE2);
  743                 vnp = &ar->k_ar.ar_arg_vnode2;
  744         }
  745 
  746         error = VOP_GETATTR(vp, &vattr, curthread->td_ucred, curthread);
  747         if (error) {
  748                 /* XXX: How to handle this case? */
  749                 return;
  750         }
  751 
  752         vnp->vn_mode = vattr.va_mode;
  753         vnp->vn_uid = vattr.va_uid;
  754         vnp->vn_gid = vattr.va_gid;
  755         vnp->vn_dev = vattr.va_rdev;
  756         vnp->vn_fsid = vattr.va_fsid;
  757         vnp->vn_fileid = vattr.va_fileid;
  758         vnp->vn_gen = vattr.va_gen;
  759         if (flags & ARG_VNODE1)
  760                 ARG_SET_VALID(ar, ARG_VNODE1);
  761         else
  762                 ARG_SET_VALID(ar, ARG_VNODE2);
  763 }
  764 
  765 /*
  766  * Audit the argument strings passed to exec.
  767  */
  768 void
  769 audit_arg_argv(char *argv, int argc, int length)
  770 {
  771         struct kaudit_record *ar;
  772 
  773         if (audit_argv == 0)
  774                 return;
  775 
  776         ar = currecord();
  777         if (ar == NULL)
  778                 return;
  779 
  780         ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK);
  781         bcopy(argv, ar->k_ar.ar_arg_argv, length);
  782         ar->k_ar.ar_arg_argc = argc;
  783         ARG_SET_VALID(ar, ARG_ARGV);
  784 }
  785 
  786 /*
  787  * Audit the environment strings passed to exec.
  788  */
  789 void
  790 audit_arg_envv(char *envv, int envc, int length)
  791 {
  792         struct kaudit_record *ar;
  793 
  794         if (audit_arge == 0)
  795                 return;
  796 
  797         ar = currecord();
  798         if (ar == NULL)
  799                 return;
  800 
  801         ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK);
  802         bcopy(envv, ar->k_ar.ar_arg_envv, length);
  803         ar->k_ar.ar_arg_envc = envc;
  804         ARG_SET_VALID(ar, ARG_ENVV);
  805 }
  806 
  807 /*
  808  * The close() system call uses it's own audit call to capture the path/vnode
  809  * information because those pieces are not easily obtained within the system
  810  * call itself.
  811  */
  812 void
  813 audit_sysclose(struct thread *td, int fd)
  814 {
  815         struct kaudit_record *ar;
  816         struct vnode *vp;
  817         struct file *fp;
  818         int vfslocked;
  819 
  820         KASSERT(td != NULL, ("audit_sysclose: td == NULL"));
  821 
  822         ar = currecord();
  823         if (ar == NULL)
  824                 return;
  825 
  826         audit_arg_fd(fd);
  827 
  828         if (getvnode(td->td_proc->p_fd, fd, &fp) != 0)
  829                 return;
  830 
  831         vp = fp->f_vnode;
  832         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
  833         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
  834         audit_arg_vnode(vp, ARG_VNODE1);
  835         VOP_UNLOCK(vp, 0, td);
  836         VFS_UNLOCK_GIANT(vfslocked);
  837         fdrop(fp, td);
  838 }

Cache object: a7e22bd81417073043655367d4461731


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