2 * Copyright (C) 2010 The Android Open Source Project
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include "linker_environ.h"
33 /* Returns 1 if 'str' points to a valid environment variable definition.
34 * For now, we check that:
35 * - It is smaller than MAX_ENV_LEN (to detect non-zero terminated strings)
36 * - It contains at least one equal sign that is not the first character
39 _is_valid_definition(const char* str
)
42 int first_equal_pos
= -1;
44 /* According to its sources, the kernel uses 32*PAGE_SIZE by default
45 * as the maximum size for an env. variable definition.
47 const int MAX_ENV_LEN
= 32*4096;
52 /* Parse the string, looking for the first '=' there, and its size */
56 if (str
[pos
] == '=' && first_equal_pos
< 0)
57 first_equal_pos
= pos
;
59 } while (pos
< MAX_ENV_LEN
);
61 if (pos
>= MAX_ENV_LEN
) /* Too large */
64 if (first_equal_pos
< 1) /* No equal sign, or it is the first character */
71 linker_env_init(unsigned* vecs
)
73 /* Store environment pointer - can't be NULL */
74 _envp
= (char**) vecs
;
76 /* Skip over all definitions */
79 /* The end of the environment block is marked by two NULL pointers */
82 /* As a sanity check, we're going to remove all invalid variable
83 * definitions from the environment array.
87 char** writep
= _envp
;
88 for ( ; readp
[0] != NULL
; readp
++ ) {
89 if (!_is_valid_definition(readp
[0]))
97 /* Return the address of the aux vectors table */
101 /* Check if the environment variable definition at 'envstr'
102 * starts with '<name>=', and if so return the address of the
103 * first character after the equal sign. Otherwise return NULL.
106 env_match(char* envstr
, const char* name
)
110 while (envstr
[cnt
] == name
[cnt
] && name
[cnt
] != '\0')
113 if (name
[cnt
] == '\0' && envstr
[cnt
] == '=')
114 return envstr
+ cnt
+ 1;
119 #define MAX_ENV_LEN (16*4096)
122 linker_env_get(const char* name
)
124 char** readp
= _envp
;
126 if (name
== NULL
|| name
[0] == '\0')
129 for ( ; readp
[0] != NULL
; readp
++ ) {
130 char* val
= env_match(readp
[0], name
);
132 /* Return NULL for empty strings, or if it is too large */
143 linker_env_unset(const char* name
)
145 char** readp
= _envp
;
146 char** writep
= readp
;
148 if (name
== NULL
|| name
[0] == '\0')
151 for ( ; readp
[0] != NULL
; readp
++ ) {
152 if (env_match(readp
[0], name
))
154 writep
[0] = readp
[0];
157 /* end list with a NULL */
163 /* Remove unsafe environment variables. This should be used when
164 * running setuid programs. */
166 linker_env_secure(void)
168 /* The same list than GLibc at this point */
169 static const char* const unsec_vars
[] = {
193 "LD_AOUT_LIBRARY_PATH",
197 const char* const* cp
= unsec_vars
;
198 const char* const* endp
= cp
+ sizeof(unsec_vars
)/sizeof(unsec_vars
[0]);
201 linker_env_unset(*cp
);