audit.c revision 56d7adc646bc459090594b76f6e6a050ca65216f
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License, Version 1.0 only 2N/A * (the "License"). You may not use this file except in compliance 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A * Audit interfaces. Auditing can be enabled in two ways: 2N/A * o Using the LD_AUDIT environment variable 2N/A * o From individual objects containing a DT_DEPAUDIT entry 2N/A * (see ld(1) -P/-p options). 2N/A * The former establishes a global set of audit libraries which can inspect all 2N/A * objects from a given process. The latter establishes a local set of audit 2N/A * libraries which can inspect the immediate dependencies of the caller. 2N/A * Audit library capabilities are indicated by flags within the link-map list 2N/A * header (for global auditing), see LML_TFLG_AUD_* flags, or by the same flags 2N/A * within the individual link-map (for local auditing). Although both sets of 2N/A * flags can occur in different data items they are defined as one to simplify 2N/A * audit interface requirements. The basic test for all audit interfaces is: 2N/A * if (((lml->lm_tflags | FLAGS1(lmp)) & LML_TFLG_AUD_MASK) && 2N/A * (lml == LIST(lmp))) 2N/A * The latter link-map list equivalence test insures that auditors themselves 2N/A * (invoked through DT_DEPAUDIT) are not audited. 2N/A#
pragma ident "%Z%%M% %I% %E% SMI" 2N/A * la_filter() caller. Traverses through all audit libraries and call any 2N/A * la_filter() entry points found. A zero return from an auditor indicates 2N/A * that the filtee should be ignored. 2N/A * la_objsearch() caller. Traverses through all audit libraries and call any 2N/A * la_objsearch() entry points found. 2N/A * Effectively any audit library can change the name we're working with, so we 2N/A * continue to propagate the new name to each audit library. Any 0 return 2N/A * terminates the search. 2N/A * la_activity() caller. Traverses through all audit library and calls any 2N/A * la_activity() entry points found. 2N/A * We want to trigger the first addition or deletion only. Ignore any 2N/A * consistent calls unless a previous addition or deletion occurred. 2N/A * la_objopen() caller. Create an audit information structure for the indicated 2N/A * link-map, regardless of an la_objopen() entry point. This structure is used 2N/A * to supply information to various audit interfaces (see LML_MSK_AUDINFO). 2N/A * Traverses through all audit library and calls any la_objopen() entry points 2N/A * Associate a cookie with the audit library, and assign the 2N/A * initial cookie as the present link-map. 2N/A * We only need dynamic plt's if a pltenter and/or a 2N/A * pltexit() entry point exist in one of our auditing 2N/A * Create one dynplt for every 'PLT' that exists in the 2N/A * Determine the total number of audit libraries in use. This provides 2N/A * the number of client structures required for this object. 2N/A * The initial allocation of the audit information structure includes 2N/A * an array of audit clients, 1 per audit library presently available. 2N/A * Audit_info | ai_clients |------- 2N/A * |---------------| | 2N/A * Audit_client | 1 |<------ 2N/A * la_objclose() caller. Traverses through all audit library and calls any 2N/A * la_objclose() entry points found. 2N/A * la_pltenter() caller. Traverses through all audit library and calls any 2N/A * la_pltenter() entry points found. NOTE: this routine is called via the 2N/A * glue code established in elf_plt_trace_write(), the symbol descriptor is 2N/A * created as part of the glue and for 32bit environments the st_name is a 2N/A * pointer to the real symbol name (ie. it's already been adjusted with the 2N/A * objects base offset). For 64bit environments the st_name remains the 2N/A * original symbol offset and in this case it is used to compute the real name 2N/A * pointer and pass as a separate argument to the auditor. 2N/A * We're effectively entering ld.so.1 from user (glue) code. 2N/A * la_pltexit() caller. Traverses through all audit library and calls any 2N/A * la_pltexit() entry points found. See notes above (_audit_pltenter) for 2N/A * discussion on st_name. 2N/A * We're effectively entering ld.so.1 from user (glue) code. 2N/A * la_symbind() caller. Traverses through all audit library and calls any 2N/A * la_symbind() entry points found. 2N/A * The la_symbind interface is only called when the calling 2N/A * object has been identified as BINDFROM, and the destination 2N/A * object has been identified as BINDTO. Use a local version of 2N/A * the flags, so that any user update can be collected. 2N/A * If the auditor indicated that they did not want to process 2N/A * pltenter, or pltexit audits for this symbol, retain this 2N/A * information. Also retain whether an alternative symbol value 2N/A * has been supplied. 2N/A * Construct a new symbol from that supplied but with the real address. 2N/A * In the 64-bit world the st_name field is only 32-bits which isn't 2N/A * big enough to hold a character pointer. We pass this pointer as a 2N/A * separate parameter for 64-bit audit libraries. 2N/A * If no la_symbind() was called for this interface, fabricate that no 2N/A * la_pltenter, or la_pltexit is required. This helps reduce the glue 2N/A * code created for further auditing. 2N/A * la_preinit() caller. Traverses through all audit libraries and calls any 2N/A * la_preinit() entry points found. 2N/A * Clean up (free) an audit descriptor. First, gather a list of all handles, 2N/A * and then close each one down. This is done rather than using the handles 2N/A * directly from the auditors, as the audit list can be torn down as a result 2N/A * of the dlclose. In other words, what you're pointing at can be removed 2N/A * while your still pointing at it. 2N/A * Clean up (free) an audit information structure. 2N/A * Create a data structure of symbol lookup names and associated flags to help 2N/A * simplify audit_symget() use. 2N/A * Centralize cleanup routines. 2N/A * Given a list of one or more audit libraries, open each one and establish a 2N/A * a descriptor representing the entry points it provides. 2N/A * Mark that we have at least one auditing link map 2N/A * The audit definitions may be a list (which will already have been 2N/A * dupped) so split it into individual tokens. 2N/A * Open the audit library on its own link-map. 2N/A * If this auditor has already been loaded, reuse it. 2N/A * If we are not running in the environment where 2N/A * upon leave() function. 2N/A * There is a possibility that libc is not mapped in yet. 2N/A * We may later find out that we will be running in 2N/A * Allocate an audit list descriptor for this object and 2N/A * search for all known entry points. 2N/A * All audit libraries must handshake through la_version(). 2N/A * Determine that the symbol exists, finish initializing the 2N/A * object, and then call the function. 2N/A * Collect any remaining entry points. 2N/A * Collect the individual object flags, and assign this audit 2N/A * list descriptor to its associated link-map list. 2N/A * Free the original audit string, as this descriptor may be used again 2N/A * to add additional auditing.