audit.c revision 9e9e6ab82d4247028c312ff50a65b8a05a194b33
#
include <
sys/
disp.h>
/* for servicing_interrupt() */ * PURPOSE: initialize the child p_audit_data structure * NOTE: All threads for the parent process are locked at this point. * We are essentially running singled threaded for this reason. * GETPROC is called when system creates a new process. * By the time AUDIT_NEWPROC is called, the child proc * structure has already been initialized. What we need * to do is to allocate the child p_audit_data and * initialize it with the content of current parent process. * copy the audit data. Note that all threads of current * process have been "held". Thus there is no race condition * here with mutiple threads trying to alter the cwrd * structure (such as releasing it). * The audit context in the cred is "duplicated" for the new * proc by elsewhere crhold'ing the parent's cred which it shares. * We still want to hold things since auditon() [A_SETUMASK, * A_SETSMASK] could be walking through the processes to * finish auditing of parent here so that it will be done * before child has a chance to run. We include the child * pid since the return value in the return token is a dummy * one and contains no useful information (it is included to * make the audit record structure consistant). * tad_flag is set if auditing is on * finish up audit record generation here because child process * is set to run before parent process. We distinguish here * between FORK, FORK1, or VFORK by the saved system call ID. * PURPOSE: deallocate the per-process udit data structure * NOTE: all lwp except current one have stopped in SEXITLWPS * why we are single threaded? * . all lwp except current one have stopped in SEXITLWPS. /* better be a per process audit data structure */ /* deallocate all auditing resources for this process */ * Since the pad structure is completely overwritten after alloc, * we don't bother to clear it. * ROUTINE: AUDIT_THREAD_CREATE * PURPOSE: allocate per-process thread audit data structure * NOTE: This is called just after *t was bzero'd. * We are single threaded in this routine. T2A(t) =
tad;
/* set up thread audit data ptr */ * ROUTINE: AUDIT_THREAD_FREE * PURPOSE: free the per-thread audit data structure * NOTE: most thread data is clear after return /* thread audit data must still be set */ /* must not have any audit record residual */ /* saved path must be empty */ * ROUTINE: AUDIT_SAVEPATH * NOTE: We have reached the end of a path in fs/lookup.c. * We get two pieces of information here: * the vnode of the last component (vp) and * the status of the last access (flag). struct vnode *
vp,
/* vnode of the last component */ int flag,
/* status of the last access */ * this event being audited or do we need path information * later? This might be for a chdir/chroot or open (add path * to file pointer. If the path has already been found for an * open/creat then we don't need to process the path. * S2E_SP (PAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with * chroot, chdir, open, creat system call processing. It determines * if audit_savepath() will discard the path or we need it later. * PAD_PATHFND means path already included in this audit record. It * is used in cases where multiple path lookups are done per * system call. The policy flag, AUDIT_PATH, controls if multiple * S2E_NPT (PAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with * exit processing to inhibit any paths that may be added due to * are we auditing only if error, or if it is not open or create * otherwise audit_setf will do it /* add token to audit record for this name */ /* add the attributes of the object */ * only capture attributes when there is no error * lookup will not return the vnode of the failing * if there was a lookup error, then don't add * attribute. if lookup in vn_create(), * then don't add attribute, * it will be added at end of vn_create(). /* free up space if we're not going to save path (open, crate) */ char *
pp;
/* pointer to path */ int len;
/* length of incoming segment */ int newsect;
/* path requires a new section */ /* adjust for path prefix: tad_aupath, ATPATH, CRD, or CWD */ /* get an expanded buffer to hold the anchored path */ /* overlay previous NUL terminator */ /* now add string of processed path */ /* perform path simplification as necessary */ /* for case where multiple lookups in one syscall (rename) */ * ROUTINE: AUDIT_ADDCOMPONENT * PURPOSE: extend the path by the component accepted * NOTE: This function is called only when there is an error in * parsing a path component * TODO: Add the error component to audit record * QUESTION: what is this for * S2E_SP (PAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with * chroot, chdir, open, creat system call processing. It determines * if audit_savepath() will discard the path or we need it later. * PAD_PATHFND means path already included in this audit record. It * is used in cases where multiple path lookups are done per * system call. The policy flag, AUDIT_PATH, controls if multiple * S2E_NPT (PAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with * exit processing to inhibit any paths that may be added due to }
/* AUDIT_ADDCOMPONENT */ * ROUTINE: AUDIT_ANCHORPATH * anchor path at "/". We have seen a symbolic link or entering for the * first time we will throw away any saved path if path is anchored. * flag = 0, path is relative. * flag = 1, path is absolute. Free any saved path and set flag to PAD_ABSPATH. * If the (new) path is absolute, then we have to throw away whatever we have * already accumulated since it is being superceeded by new path which is * Note that if the path is relative, this function does nothing * this event being audited or do we need path information * later? This might be for a chdir/chroot or open (add path * to file pointer. If the path has already been found for an * open/creat then we don't need to process the path. * S2E_SP (PAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with * chroot, chdir, open, creat system call processing. It determines * if audit_savepath() will discard the path or we need it later. * PAD_PATHFND means path already included in this audit record. It * is used in cases where multiple path lookups are done per * system call. The policy flag, AUDIT_PATH, controls if multiple * S2E_NPT (PAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with * exit processing to inhibit any paths that may be added due to * symbolic link. Save previous components. * the path seen so far looks like this * +-----------------------+----------------+ * | path processed so far | remaining path | * +-----------------------+----------------+ * \-----------------------/ * (but don't include symlink component) char *
sp;
/* saved initial pp */ char *
cp;
/* start of symlink path */ * this event being audited or do we need path information * later? This might be for a chdir/chroot or open (add path * to file pointer. If the path has already been found for an * open/creat then we don't need to process the path. * S2E_SP (PAD_SAVPATH) flag comes from audit_s2e[].au_ctrl. Used with * chroot, chdir, open, creat system call processing. It determines * if audit_savepath() will discard the path or we need it later. * PAD_PATHFND means path already included in this audit record. It * is used in cases where multiple path lookups are done per * system call. The policy flag, AUDIT_PATH, controls if multiple * S2E_NPT (PAD_NOPATH) flag comes from audit_s2e[].au_ctrl. Used with * exit processing to inhibit any paths that may be added due to * if symbolic link is anchored at / then do nothing. * When we cycle back to begin: in lookuppn() we will * call audit_anchorpath() with a flag indicating if the * path is anchored at / or is relative. We will release * any saved path at that point. * Note In the event that an error occurs in pn_combine then * we want to remain pointing at the component that caused the * path to overflow the pnp structure. /* backup over last component */ /* is there anything to save? */ * file_is_public : determine whether events for the file (corresponding to * the specified file attr) should be audited or ignored. * returns: 1 - if audit policy and file attributes indicate that * file is effectively public. read events for * the file should not be audited. * The required attributes to be considered a public object are: * - world-readable (permissions for other include read), AND * - NOT world-writeable (permissions for other don't * (mode doesn't need to be checked for symlinks) * ROUTINE: AUDIT_ATTRIBUTES * PURPOSE: Audit the attributes so we can tell why the error occured * This is a public object and a "public" event * (i.e., read only) -- either by definition * (e.g., stat, access...) or by virtue of write access * not being requested (e.g. mmap). * Flag it in the tad to prevent this audit at the end. * PURPOSE: allocating a new file structure * NOTE: file structure already initialized /* allocate per file audit structure if there a'int any */ * ROUTINE: AUDIT_UNFALLOC * PURPOSE: deallocate file audit data structure * QUESTION: why cmw code as offset by 2 but not here * tad_scid will be set by audit_start even if we are not auditing * if we are auditing the exit system call, then complete * audit record generation (no return from system call). * Anyone auditing the system call that was aborted? * Generate an audit record for process exit if preselected. * ROUTINE: AUDIT_CORE_START /* get basic event for system call */ /* reset the flags for non-user attributable events */ /* if auditing not enabled, then don't generate an audit record */ * ROUTINE: AUDIT_CORE_FINISH /* kludge for error 0, should use `code==CLD_DUMPED' instead */ * Add subject information (no locks since our private copy of /* Add a return token (should use f argument) */ /* Close up everything */ /* free up any space remaining with the path's */ /* lock stdata from audit_sock */ /* proceed ONLY if user is being audited */ * this is so we will not add audit data onto * a thread that is not being audited. /* lock stdata from audit_sock */ /* proceed ONLY if user is being audited */ * this is so we will not add audit data onto * a thread that is not being audited. * release per file audit resources when file structure is being released. * IMPORTANT NOTE: Since we generate an audit record here, we may sleep * on the audit queue if it becomes full. This means * audit_closef can not be called when f_count == 0. Since * f_count == 0 indicates the file structure is free, another * process could attempt to use the file while we were still * asleep waiting on the audit queue. This would cause the * per file audit data to be corrupted when we finally do /* audit record already generated by system call envelope */ /* so close audit event will have bits set */ /* if auditing not enabled, then don't generate an audit record */ /* not selected for this event */ * can't use audit_attributes here since we use a private audit area * to build the audit record instead of the one off the thread. * When write was not used and the file can be considered public, /* Add subject information */ * Note: path space recovery handled by normal system * call envelope if not at last close. * Note there is no failure at this point since * this represents closes due to exit of process, * thus we always indicate successful closes. * PURPOSE: Audit the file path and file attributes. * NOTE: SETF associate a file pointer with user area's open files. * call audit_finish directly ??? * assign path information associated with file audit data /* if not auditing this event, then do nothing */ /* if not auditing this event, then do nothing */ * At this point we know that the system call reboot will not return. We thus * have to complete the audit record generation and put it onto the queue. * This might be fairly useless if the auditing daemon is already dead.... * QUESTION: who calls audit_reboot /* if not auditing this event, then do nothing */ /* add a process token */ /* Add subject information */ * Flow control useless here since we're going * to drop everything in the queue anyway. Why * block and wait. There aint anyone left alive to * read the records remaining anyway. /* Close up everything */ /* if not auditing this event, then do nothing */ * ROUTINE: AUDIT_VNCREATE_START * PURPOSE: set flag so path name lookup in create will not add attribute * ROUTINE: AUDIT_VNCREATE_FINISH /* if not auditing this event, then do nothing */ /* for case where multiple lookups in one syscall (rename) */ * PURPOSE: Records the function arguments and environment variables const char *
argstr,
/* argument strings */ const char *
envstr,
/* environment strings */ /* if not auditing this event, then do nothing */ /* return if not interested in argv or environment variables */ * ROUTINE: AUDIT_ENTERPROM * ROUTINE: AUDIT_EXITPROM * ROUTINE: AUDIT_C2_REVOKE * QUESTION: are we keeping this func * NOTE: The main function of CHDIREC * TODO: Move the audit_chdirec hook above the VN_RELE in vncalls.c * NOTE: The main function of GETF_INTERNAL is to associate a given * file descriptor with a file structure and increment the * file pointer reference count. * TODO: remove pass in of fpp. * increment a reference count so that even if a thread with same process delete * the same object, it will not panic our system * where to decrement the f_count????????????????? * seems like I need to set a flag if f_count incrmented through audit_getf * Audit hook for stream based socket and tli request. * Note that we do not have user context while executing * this code so we had to record them earlier during the * putmsg/getmsg to figure out which user we are dealing with. queue_t *q,
/* contains the process and thread audit data */ int from)
/* timod or sockmod request */ /* are we being audited */ /* no pointer to thread, nothing to do */ /* only allow one addition of a record token */ * thread is not the one being audited, then nothing to do * This could be the stream thread handling the module * service routine. In this case, the context for the audit * record can no longer be assumed. Simplest to just drop * we know that the thread that did the put/getmsg is the * one running. Now we can get the TAD and see if we should /* proceed ONLY if user is being audited */ * Figure out the type of stream networking request here. * Note that getmsg and putmsg are always preselected * because during the beginning of the system call we have * not yet figure out which of the socket or tli request * we are looking at until we are here. So we need to check * against that specific request and reset the type of event. case T_CONN_IND:
/* connectionless receive request */ * we are only interested in tcp stream connections, /* skip over TPI header and point to the ip address */ default:
/* reset to AUE_PUTMSG if not a inet request */ int error;
/* ignore for now */ struct vnode *
vp;
/* for file attributes */ /* is this system call being audited */ /* add path and file attributes */ * Record privileges sucessfully used and we attempted to use but /* Make sure this isn't being called in an interrupt context */ /* Tell audit_success() and audit_finish() that we saw this case */ /* Clear set first time around */ /* Save the privileges in the tad */ * Audit the setpriv() system call; the operation, the set name and * the current value as well as the set argument are put in the /* Generate the actual record, include the before and after */ /* Report privileges actually switched off */ /* Report privileges actually switched on */ /* Report before and after */ * Dump the full device policy setting in the audit trail. for (i = 0; i <
nitems; i++) {
struct vnode *
vp;
/* for file attributes */ /* is this system call being audited */ /* add path and file attributes */ * ROUTINE: AUDIT_CRYPTOADM * PURPOSE: Records arguments to administrative ioctls on /dev/cryptoadm * CALLBY: CRYPTO_LOAD_DEV_DISABLED, CRYPTO_LOAD_SOFT_DISABLED, * CRYPTO_UNLOAD_SOFT_MODULE, CRYPTO_LOAD_SOFT_CONFIG, * CRYPTO_POOL_CREATE, CRYPTO_POOL_WAIT, CRYPTO_POOL_RUN, /* Add subject information */ "op=CRYPTO_LOAD_DEV_DISABLED, module=%s," "op=CRYPTO_LOAD_DEV_DISABLED, return_val=%d",
rv);
"op=CRYPTO_LOAD_SOFT_DISABLED, module=%s",
"op=CRYPTO_LOAD_SOFT_DISABLED, return_val=%d",
rv);
"op=CRYPTO_UNLOAD_SOFT_MODULE, module=%s",
"op=CRYPTO_UNLOAD_SOFT_MODULE, return_val=%d",
rv);
"op=CRYPTO_LOAD_SOFT_CONFIG, module=%s",
"op=CRYPTO_LOAD_SOFT_CONFIG, return_val=%d",
rv);
"op=CRYPTO_POOL_CREATE");
"op=CRYPTO_LOAD_DOOR, return_val=%d",
rv);
* Audit the kernel SSL administration command. The address and the * port number for the SSL instance, and the proxy port are put in the /* Add subject information */ * ROUTINE: AUDIT_SEC_ATTRIBUTES * PURPOSE: Add security attributes * CALLBY: AUDIT_ATTRIBUTES return;
/* nothing else to do */ return;
/* nothing else to do */ }
/* AUDIT_SEC_ATTRIBUTES */