~sergiusens/libhybris/autotests

« back to all changes in this revision

Viewing changes to hybris/common/gingerbread/linker_environ.c

  • Committer: Package Import Robot
  • Author(s): Ricardo Salveti de Araujo
  • Date: 2013-06-04 07:33:11 UTC
  • Revision ID: package-import@ubuntu.com-20130604073311-20ldi2hm1axkvjl1
Tags: upstream-0.1.0+git20130601+dfb2e26
ImportĀ upstreamĀ versionĀ 0.1.0+git20130601+dfb2e26

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2010 The Android Open Source Project
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
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
 
13
 *    distribution.
 
14
 *
 
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
 
26
 * SUCH DAMAGE.
 
27
 */
 
28
#include "linker_environ.h"
 
29
#include <stddef.h>
 
30
 
 
31
static char** _envp;
 
32
 
 
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
 
37
 */
 
38
static int
 
39
_is_valid_definition(const char*  str)
 
40
{
 
41
    int   pos = 0;
 
42
    int   first_equal_pos = -1;
 
43
 
 
44
    /* According to its sources, the kernel uses 32*PAGE_SIZE by default
 
45
     * as the maximum size for an env. variable definition.
 
46
     */
 
47
    const int MAX_ENV_LEN = 32*4096;
 
48
 
 
49
    if (str == NULL)
 
50
        return 0;
 
51
 
 
52
    /* Parse the string, looking for the first '=' there, and its size */
 
53
    do {
 
54
        if (str[pos] == '\0')
 
55
            break;
 
56
        if (str[pos] == '=' && first_equal_pos < 0)
 
57
            first_equal_pos = pos;
 
58
        pos++;
 
59
    } while (pos < MAX_ENV_LEN);
 
60
 
 
61
    if (pos >= MAX_ENV_LEN)  /* Too large */
 
62
        return 0;
 
63
 
 
64
    if (first_equal_pos < 1)  /* No equal sign, or it is the first character */
 
65
        return 0;
 
66
 
 
67
    return 1;
 
68
}
 
69
 
 
70
unsigned*
 
71
linker_env_init(unsigned* vecs)
 
72
{
 
73
    /* Store environment pointer - can't be NULL */
 
74
    _envp = (char**) vecs;
 
75
 
 
76
    /* Skip over all definitions */
 
77
    while (vecs[0] != 0)
 
78
        vecs++;
 
79
    /* The end of the environment block is marked by two NULL pointers */
 
80
    vecs++;
 
81
 
 
82
    /* As a sanity check, we're going to remove all invalid variable
 
83
     * definitions from the environment array.
 
84
     */
 
85
    {
 
86
        char** readp  = _envp;
 
87
        char** writep = _envp;
 
88
        for ( ; readp[0] != NULL; readp++ ) {
 
89
            if (!_is_valid_definition(readp[0]))
 
90
                continue;
 
91
            writep[0] = readp[0];
 
92
            writep++;
 
93
        }
 
94
        writep[0] = NULL;
 
95
    }
 
96
 
 
97
    /* Return the address of the aux vectors table */
 
98
    return vecs;
 
99
}
 
100
 
 
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.
 
104
 */
 
105
static char*
 
106
env_match(char* envstr, const char* name)
 
107
{
 
108
    size_t  cnt = 0;
 
109
 
 
110
    while (envstr[cnt] == name[cnt] && name[cnt] != '\0')
 
111
        cnt++;
 
112
 
 
113
    if (name[cnt] == '\0' && envstr[cnt] == '=')
 
114
        return envstr + cnt + 1;
 
115
 
 
116
    return NULL;
 
117
}
 
118
 
 
119
#define MAX_ENV_LEN  (16*4096)
 
120
 
 
121
const char*
 
122
linker_env_get(const char* name)
 
123
{
 
124
    char** readp = _envp;
 
125
 
 
126
    if (name == NULL || name[0] == '\0')
 
127
        return NULL;
 
128
 
 
129
    for ( ; readp[0] != NULL; readp++ ) {
 
130
        char* val = env_match(readp[0], name);
 
131
        if (val != NULL) {
 
132
            /* Return NULL for empty strings, or if it is too large */
 
133
            if (val[0] == '\0')
 
134
                val = NULL;
 
135
            return val;
 
136
        }
 
137
    }
 
138
    return NULL;
 
139
}
 
140
 
 
141
 
 
142
void
 
143
linker_env_unset(const char* name)
 
144
{
 
145
    char**  readp = _envp;
 
146
    char**  writep = readp;
 
147
 
 
148
    if (name == NULL || name[0] == '\0')
 
149
        return;
 
150
 
 
151
    for ( ; readp[0] != NULL; readp++ ) {
 
152
        if (env_match(readp[0], name))
 
153
            continue;
 
154
        writep[0] = readp[0];
 
155
        writep++;
 
156
    }
 
157
    /* end list with a NULL */
 
158
    writep[0] = NULL;
 
159
}
 
160
 
 
161
 
 
162
 
 
163
/* Remove unsafe environment variables. This should be used when
 
164
 * running setuid programs. */
 
165
void
 
166
linker_env_secure(void)
 
167
{
 
168
    /* The same list than GLibc at this point */
 
169
    static const char* const unsec_vars[] = {
 
170
        "GCONV_PATH",
 
171
        "GETCONF_DIR",
 
172
        "HOSTALIASES",
 
173
        "LD_AUDIT",
 
174
        "LD_DEBUG",
 
175
        "LD_DEBUG_OUTPUT",
 
176
        "LD_DYNAMIC_WEAK",
 
177
        "LD_LIBRARY_PATH",
 
178
        "LD_ORIGIN_PATH",
 
179
        "LD_PRELOAD",
 
180
        "LD_PROFILE",
 
181
        "LD_SHOW_AUXV",
 
182
        "LD_USE_LOAD_BIAS",
 
183
        "LOCALDOMAIN",
 
184
        "LOCPATH",
 
185
        "MALLOC_TRACE",
 
186
        "MALLOC_CHECK_",
 
187
        "NIS_PATH",
 
188
        "NLSPATH",
 
189
        "RESOLV_HOST_CONF",
 
190
        "RES_OPTIONS",
 
191
        "TMPDIR",
 
192
        "TZDIR",
 
193
        "LD_AOUT_LIBRARY_PATH",
 
194
        "LD_AOUT_PRELOAD",
 
195
    };
 
196
 
 
197
    const char* const* cp   = unsec_vars;
 
198
    const char* const* endp = cp + sizeof(unsec_vars)/sizeof(unsec_vars[0]);
 
199
 
 
200
    while (cp < endp) {
 
201
        linker_env_unset(*cp);
 
202
        cp++;
 
203
    }
 
204
}