Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/src/apparmor.c
1532 views
1
/*
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2022 Will Shand <[email protected]>
5
*
6
* Permission to use, copy, modify, and distribute this software for any
7
* purpose with or without fee is hereby granted, provided that the above
8
* copyright notice and this permission notice appear in all copies.
9
*
10
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
*/
18
19
#include <config.h>
20
21
#ifdef HAVE_APPARMOR
22
23
# include <stdio.h>
24
# include <stdlib.h>
25
# include <sys/apparmor.h>
26
27
# include <sudo.h>
28
# include <sudo_debug.h>
29
30
/**
31
* @brief Check whether AppArmor is enabled.
32
*
33
* @return 1 if AppArmor is enabled, 0 otherwise.
34
*/
35
int
36
apparmor_is_enabled(void)
37
{
38
int ret;
39
FILE *fd;
40
debug_decl(apparmor_is_enabled, SUDO_DEBUG_APPARMOR);
41
42
/*
43
* Check whether AppArmor is enabled by reading
44
* /sys/module/apparmor/parameters/enabled
45
*
46
* When this file exists and its contents are equal to "Y", AppArmor
47
* is enabled. This is a little more reliable than using
48
* aa_is_enabled(2), which performs an additional check on securityfs
49
* that will fail in settings where securityfs isn't available
50
* (e.g. inside a container).
51
*/
52
53
fd = fopen("/sys/module/apparmor/parameters/enabled", "r");
54
if (fd == NULL)
55
debug_return_int(0);
56
57
ret = (fgetc(fd) == 'Y');
58
59
fclose(fd);
60
debug_return_int(ret);
61
}
62
63
/**
64
* @brief Prepare to transition into a new AppArmor profile.
65
*
66
* @param new_profile The AppArmor profile to transition into on the
67
* next exec.
68
*
69
* @return 0 on success, and a nonzero value on failure.
70
*/
71
int
72
apparmor_prepare(const char *new_profile)
73
{
74
int ret;
75
char *mode, *old_profile;
76
debug_decl(apparmor_prepare, SUDO_DEBUG_APPARMOR);
77
78
/* Determine the current AppArmor confinement status */
79
if ((ret = aa_getcon(&old_profile, &mode)) == -1) {
80
sudo_warn("%s", U_("failed to determine AppArmor confinement"));
81
old_profile = NULL;
82
goto done;
83
}
84
85
/* Tell AppArmor to transition into the new profile on the
86
* next exec */
87
if ((ret = aa_change_onexec(new_profile)) != 0) {
88
sudo_warn(U_("unable to change AppArmor profile to %s"), new_profile);
89
goto done;
90
}
91
92
if (mode == NULL) {
93
sudo_debug_printf(SUDO_DEBUG_INFO,
94
"%s: changing AppArmor profile: %s -> %s", __func__,
95
old_profile, new_profile ? new_profile : "?");
96
} else {
97
sudo_debug_printf(SUDO_DEBUG_INFO,
98
"%s: changing AppArmor profile: %s (%s) -> %s", __func__,
99
old_profile, mode, new_profile ? new_profile : "?");
100
}
101
102
done:
103
/*
104
* The profile string returned by aa_getcon must be free'd, while the
105
* mode string must _not_ be free'd.
106
*/
107
if (old_profile != NULL)
108
free(old_profile);
109
110
debug_return_int(ret);
111
}
112
113
#endif /* HAVE_APPARMOR */
114
115