1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* LINTLIBRARY */ 27 28 #include <link.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <unistd.h> 32 #include <strings.h> 33 #include <limits.h> 34 #include "rtld.h" 35 #include "_crle.h" 36 #include "msg.h" 37 38 /* 39 * This file provides the LD_AUDIT interfaces for libcrle.so.1, which are 40 * called for one of two reasons: 41 * 42 * CRLE_AUD_DEPENDS 43 * under this mode, the dependencies of the application are 44 * gathered (similar to ldd(1)) and written back to the calling 45 * process. 46 * 47 * CRLE_AUD_DLDUMP 48 * under this mode, the LD_CONFIG file is read to determine which 49 * objects are to be dldump()'ed. The memory range occupied by 50 * the dumped images is written back to the calling process. 51 * 52 * Both of these interfaces are invoked via the crle(1) calling process. The 53 * following environment variables are used to communicate between the two: 54 * 55 * CRLE_FD the file descriptor on which to communicate to the calling 56 * process (used for CRLE_AUD_DEPENDS and CRLE_AUD_DUMP). 57 * 58 * CRLE_FLAGS this signals CRLE_AUD_DLDUMP mode, and indicates the required 59 * flags for the dldump(3C) calls. 60 */ 61 62 static int auflag; 63 64 int pfd; 65 int dlflag = RTLD_CONFSET; 66 67 /* 68 * Initial audit handshake, establish audit mode. 69 */ 70 uint_t 71 /* ARGSUSED */ 72 la_version(uint_t version) 73 { 74 char *str; 75 76 /* 77 * Establish the file desciptor to communicate with the calling process, 78 * If there are any errors terminate the process. 79 */ 80 if ((str = getenv(MSG_ORIG(MSG_ENV_AUD_FD))) == NULL) 81 exit(1); 82 pfd = atoi(str); 83 84 /* 85 * Determine which audit mode is required based on the existance of 86 * CRLE_FLAGS. 87 */ 88 if ((str = getenv(MSG_ORIG(MSG_ENV_AUD_FLAGS))) == NULL) { 89 auflag = CRLE_AUD_DEPENDS; 90 } else { 91 auflag = CRLE_AUD_DLDUMP; 92 dlflag |= atoi(str); 93 94 /* 95 * Fill any memory holes before anything gets mapped. 96 */ 97 if (filladdr() != 0) 98 exit(1); 99 } 100 101 /* 102 * We need the audit interface containing la_objfilter(). 103 */ 104 return (LAV_VERSION3); 105 } 106 107 /* 108 * Audit interface called for each dependency. If in CRLE_AUD_DEPENDS mode, 109 * return each dependency of the primary link-map to the caller. 110 */ 111 uint_t 112 /* ARGSUSED2 */ 113 la_objopen(Link_map * lmp, Lmid_t lmid, uintptr_t *cookie) 114 { 115 if (auflag == CRLE_AUD_DLDUMP) 116 return (0); 117 118 if ((lmid == LM_ID_BASE) && 119 !(FLAGS(LINKMAP_TO_RTMAP(lmp)) & FLG_RT_ISMAIN)) { 120 char buffer[PATH_MAX]; 121 122 (void) snprintf(buffer, PATH_MAX, MSG_ORIG(MSG_AUD_DEPEND), 123 lmp->l_name); 124 (void) write(pfd, buffer, strlen(buffer)); 125 *cookie = (uintptr_t)lmp->l_name; 126 } else 127 *cookie = (uintptr_t)0; 128 129 return (0); 130 } 131 132 /* 133 * Audit interface called for any filter/filtee pairs. If in CRLE_AUD_DEPENDS 134 * mode, return the filter/filtee association to the caller. 135 */ 136 int 137 /* ARGSUSED2 */ 138 la_objfilter(uintptr_t *fltrcook, const char *fltestr, uintptr_t *fltecook, 139 uint_t flags) 140 { 141 if (auflag == CRLE_AUD_DLDUMP) 142 return (0); 143 144 if (*fltrcook && *fltestr && *fltecook) { 145 char buffer[PATH_MAX]; 146 147 (void) snprintf(buffer, PATH_MAX, MSG_ORIG(MSG_AUD_FILTER), 148 (char *)(*fltrcook), fltestr, (char *)(*fltecook)); 149 (void) write(pfd, buffer, strlen(buffer)); 150 } 151 return (1); 152 } 153 154 /* 155 * Audit interface called before transfer of control to application. If in 156 * CRLE_AUD_DLDUMP mode read the configuration file and dldump() all necessary 157 * objects. 158 */ 159 void 160 /* ARGSUSED */ 161 la_preinit(uintptr_t *cookie) 162 { 163 if (auflag == CRLE_AUD_DLDUMP) { 164 if (dumpconfig() != 0) 165 exit(1); 166 } 167 exit(0); 168 } 169