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