xref: /illumos-gate/usr/src/cmd/sgs/libconv/common/lddstub.c (revision dde769a2c00c82faaf80563ddd5610de2f4da339)
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 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include	<unistd.h>
28 #include	<strings.h>
29 #include	<limits.h>
30 #include	<dlfcn.h>
31 #include	"_conv.h"
32 #include	"lddstub_msg.h"
33 
34 static int
35 originlddstub(char *buffer, const char *orgfile)
36 {
37 	int	len;
38 
39 	if (dlinfo(RTLD_SELF, RTLD_DI_ORIGIN, (void *)buffer) == -1)
40 		return (-1);
41 	if (strlcat(buffer, orgfile, PATH_MAX) >= PATH_MAX)
42 		return (-1);
43 	if ((len = resolvepath(buffer, buffer, (PATH_MAX - 1))) == -1)
44 		return (-1);
45 	buffer[len] = '\0';
46 	if (access(buffer, X_OK) == -1)
47 		return (-1);
48 
49 	return (1);
50 }
51 
52 static char	orgstub[PATH_MAX], orgstub64[PATH_MAX];
53 static int	orgflag, orgflag64;
54 
55 /*
56  * Determine what lddstub to run.
57  */
58 const char *
59 conv_lddstub(int class)
60 {
61 	const char *stub;
62 
63 	/*
64 	 * Establish defaults.
65 	 */
66 	if (class == ELFCLASS32)
67 		stub = MSG_ORIG(MSG_PTH_LDDSTUB);
68 	else
69 		stub = MSG_ORIG(MSG_PTH_LDDSTUB_64);
70 
71 	/*
72 	 * Provided we're not secure, determine lddstub's location from our
73 	 * own origin.
74 	 */
75 	if (geteuid()) {
76 		if ((class == ELFCLASS32) && (orgflag != -1)) {
77 			if (orgflag == 0) {
78 				/* BEGIN CSTYLED */
79 				if ((orgflag = originlddstub(orgstub,
80 #ifdef	_LP64
81 				    MSG_ORIG(MSG_ORG_64LDD_32STUB))) == -1)
82 #else
83 				    MSG_ORIG(MSG_ORG_32LDD_32STUB))) == -1)
84 #endif
85 					return (stub);
86 				/* END CSTYLED */
87 			}
88 			stub = (const char *)orgstub;
89 		}
90 		if ((class == ELFCLASS64) && (orgflag64 != -1)) {
91 			if (orgflag64 == 0) {
92 				/* BEGIN CSTYLED */
93 				if ((orgflag64 = originlddstub(orgstub64,
94 #ifdef	_LP64
95 				    MSG_ORIG(MSG_ORG_64LDD_64STUB))) == -1)
96 #else
97 				    MSG_ORIG(MSG_ORG_32LDD_64STUB))) == -1)
98 #endif
99 					return (stub);
100 				/* END CSTYLED */
101 			}
102 			stub = (const char *)orgstub64;
103 		}
104 	}
105 	return (stub);
106 }
107