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