-
Notifications
You must be signed in to change notification settings - Fork 251
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SELINUX_CHILD: only cap_set*id is required
:packaging:*Important note for downstream maintainers.* A set of capabilities required by privileged binaries was further reduced to: ``` krb5_child cap_dac_read_search,cap_setgid,cap_setuid=p ldap_child cap_dac_read_search=p selinux_child cap_setgid,cap_setuid=p sssd_pam cap_dac_read_search=p ``` Keep in mind that even with limited set of fine graned capabilities, usual precautions still should be taken while packaging binaries with file capabilities: it's very important to make sure that those are executable only by root/sssd service user. For this reason upstream spec file packages it as: ``` -rwxr-x---. 1 root sssd ``` Failing to do so (i.e. allowing non-privileged users to execute those binaries) can impose systems installing the package to a security risk. Reviewed-by: Justin Stephenson <[email protected]> Reviewed-by: Sumit Bose <[email protected]> (cherry picked from commit 84baae4)
- Loading branch information
1 parent
89627db
commit 1614c5e
Showing
3 changed files
with
47 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,9 +22,10 @@ | |
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include "config.h" | ||
|
||
#include <sys/types.h> | ||
#include <unistd.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <popt.h> | ||
#include <sys/prctl.h> | ||
|
@@ -236,6 +237,8 @@ int main(int argc, const char *argv[]) | |
const char *username; | ||
const char *opt_logger = NULL; | ||
long chain_id; | ||
uid_t ruid, euid, suid; | ||
gid_t rgid, egid, sgid; | ||
|
||
struct poptOption long_options[] = { | ||
POPT_AUTOHELP | ||
|
@@ -291,10 +294,7 @@ int main(int argc, const char *argv[]) | |
DEBUG_INIT(debug_level, opt_logger); | ||
sss_set_debug_backtrace_enable((backtrace == 0) ? false : true); | ||
|
||
DEBUG(SSSDBG_TRACE_FUNC, "selinux_child started.\n"); | ||
DEBUG(SSSDBG_TRACE_INTERNAL, | ||
"Running with effective IDs: [%"SPRIuid"][%"SPRIgid"].\n", | ||
geteuid(), getegid()); | ||
sss_log_process_caps("Starting"); | ||
|
||
/* The functions semanage_genhomedircon and getseuserbyname use gepwnam_r | ||
* and they might fail to return values if they are not in memory cache. | ||
|
@@ -312,31 +312,6 @@ int main(int argc, const char *argv[]) | |
"fail.\n"); | ||
} | ||
|
||
/* libsemanage calls access(2) which works with real IDs, not effective. | ||
* We need to switch also the real ID to 0. | ||
*/ | ||
if (getuid() != 0) { | ||
ret = setuid(0); | ||
if (ret == -1) { | ||
ret = errno; | ||
DEBUG(SSSDBG_CRIT_FAILURE, | ||
"setuid failed: %d, selinux_child might not work!\n", ret); | ||
} | ||
} | ||
|
||
if (getgid() != 0) { | ||
ret = setgid(0); | ||
if (ret == -1) { | ||
ret = errno; | ||
DEBUG(SSSDBG_CRIT_FAILURE, | ||
"setgid failed: %d, selinux_child might not work!\n", ret); | ||
} | ||
} | ||
|
||
DEBUG(SSSDBG_TRACE_INTERNAL, | ||
"Running with real IDs [%"SPRIuid"][%"SPRIgid"].\n", | ||
getuid(), getgid()); | ||
|
||
main_ctx = talloc_new(NULL); | ||
if (main_ctx == NULL) { | ||
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); | ||
|
@@ -376,8 +351,6 @@ int main(int argc, const char *argv[]) | |
goto fail; | ||
} | ||
|
||
DEBUG(SSSDBG_TRACE_FUNC, "performing selinux operations\n"); | ||
|
||
/* When using domain_resolution_order the username will always be | ||
* fully-qualified, what has been causing some SELinux issues as mappings | ||
* for user 'admin' are not applied for '[email protected]'. | ||
|
@@ -396,6 +369,32 @@ int main(int argc, const char *argv[]) | |
username = passwd->pw_name; | ||
} | ||
|
||
/* libsemanage calls access(2) which works with real IDs, not effective. | ||
* We need to switch also the real ID to 0. | ||
*/ | ||
if (getuid() != 0) { | ||
sss_set_cap_effective(CAP_SETUID, true); | ||
ret = setresuid(0, 0, -1); | ||
if (ret == -1) { | ||
ret = errno; | ||
DEBUG(SSSDBG_CRIT_FAILURE, | ||
"setuid() failed: %d, selinux_child might not work!\n", ret); | ||
} | ||
} | ||
if (getgid() != 0) { | ||
sss_set_cap_effective(CAP_SETGID, true); | ||
setgroups(0, NULL); | ||
ret = setresgid(0, 0, -1); | ||
if (ret == -1) { | ||
ret = errno; | ||
DEBUG(SSSDBG_CRIT_FAILURE, | ||
"setgid() failed: %d, selinux_child might not work!\n", ret); | ||
} | ||
} | ||
sss_drop_all_caps(); | ||
|
||
sss_log_process_caps("Performing selinux operations"); | ||
|
||
needs_update = seuser_needs_update(username, ibuf->seuser, | ||
ibuf->mls_range); | ||
if (needs_update == true) { | ||
|
@@ -406,6 +405,15 @@ int main(int argc, const char *argv[]) | |
} | ||
} | ||
|
||
if (getresuid(&ruid, &euid, &suid) == 0) { | ||
setresuid(suid, suid, suid); | ||
} | ||
if (getresgid(&rgid, &egid, &sgid) == 0) { | ||
setresgid(sgid, sgid, sgid); | ||
} | ||
|
||
sss_log_process_caps("Sending response"); | ||
|
||
ret = prepare_response(main_ctx, ret, &resp); | ||
if (ret != EOK) { | ||
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to prepare response buffer.\n"); | ||
|