Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/util/support/secure_getenv.c
34889 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/* util/support/secure_getenv.c - secure_getenv() portability support */
3
/*
4
* Copyright (C) 2019 by the Massachusetts Institute of Technology.
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
*
11
* * Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
*
14
* * Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in
16
* the documentation and/or other materials provided with the
17
* distribution.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30
* OF THE POSSIBILITY OF SUCH DAMAGE.
31
*/
32
33
/*
34
* This file contains the fallback implementation for secure_getenv(), which is
35
* currently only provided by glibc 2.17 and later. The goal is to ignore the
36
* environment if this process is (or previously was) running at elevated
37
* privilege compared to the calling process.
38
*
39
* In this fallback version we compare the real and effective uid/gid, and also
40
* compare the saved uid/gid if possible. These comparisons detect a setuid or
41
* setgid process which is still running with elevated privilege; if we can
42
* fetch the saved uid/gid, we also detect a process which has temporarily
43
* dropped privilege with seteuid() or setegid(). These comparisons do not
44
* detect the case where a setuid or setgid process has permanently dropped
45
* privilege before the library initializer ran; this is not ideal because such
46
* a process may possess a privileged resource or have privileged information
47
* in its address space.
48
*
49
* Heimdal also looks at the ELF aux vector in /proc/self/auxv to determine the
50
* starting uid/euid/gid/euid on Solaris/Illumos and NetBSD. On FreeBSD this
51
* approach can determine the executable path to do a stat() check. We do not
52
* go to this length due to the amount of code required.
53
*
54
* The BSDs and Solaris provide issetugid(), but the FreeBSD and NetBSD
55
* versions are not useful; they return true if a non-setuid/setgid executable
56
* is run by root and drops privilege, such as Apache httpd. We do not want to
57
* ignore the process environment in this case.
58
*
59
* On some platforms a process may have elevated privilege via mechanisms other
60
* than setuid/setgid. glibc's secure_getenv() should detect these cases on
61
* Linux; we do not detect them in this fallback version.
62
*/
63
64
#include "k5-platform.h"
65
66
static int elevated_privilege = 0;
67
68
MAKE_INIT_FUNCTION(k5_secure_getenv_init);
69
70
int
71
k5_secure_getenv_init(void)
72
{
73
int saved_errno = errno;
74
75
#ifdef HAVE_GETRESUID
76
{
77
uid_t r, e, s;
78
if (getresuid(&r, &e, &s) == 0) {
79
if (r != e || r != s)
80
elevated_privilege = 1;
81
}
82
}
83
#else
84
if (getuid() != geteuid())
85
elevated_privilege = 1;
86
#endif
87
88
#ifdef HAVE_GETRESGID
89
{
90
gid_t r, e, s;
91
if (!elevated_privilege && getresgid(&r, &e, &s) == 0) {
92
if (r != e || r != s)
93
elevated_privilege = 1;
94
}
95
}
96
#else
97
if (!elevated_privilege && getgid() != getegid())
98
elevated_privilege = 1;
99
#endif
100
101
errno = saved_errno;
102
return 0;
103
}
104
105
char *
106
k5_secure_getenv(const char *name)
107
{
108
if (CALL_INIT_FUNCTION(k5_secure_getenv_init) != 0)
109
return NULL;
110
return elevated_privilege ? NULL : getenv(name);
111
}
112
113