xref: /illumos-gate/usr/src/cmd/sgs/libcrle/common/audit.c (revision 24da5b34f49324ed742a340010ed5bd3d4e06625)
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