Skip to content

Commit

Permalink
libsemanage: Preserve file context and ownership in policy store
Browse files Browse the repository at this point in the history
Make sure that file context (all parts) and ownership of
files/directories in policy store does not change no matter which user
and under which context executes policy rebuild.

Fixes:
  # semodule -B
  # ls -lZ  /etc/selinux/targeted/contexts/files

-rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0 421397 Jul 11 09:57 file_contexts
-rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0 593470 Jul 11 09:57 file_contexts.bin
-rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0  14704 Jul 11 09:57 file_contexts.homedirs
-rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0  20289 Jul 11 09:57 file_contexts.homedirs.bin

  SELinux user changed from system_u to the user used to execute semodule

  # capsh --user=testuser --caps="cap_dac_override,cap_chown+eip" --addamb=cap_dac_override,cap_chown -- -c "semodule -B"
  # ls -lZ  /etc/selinux/targeted/contexts/files

-rw-r--r--. 1 testuser testuser unconfined_u:object_r:file_context_t:s0 421397 Jul 19 09:10 file_contexts
-rw-r--r--. 1 testuser testuser unconfined_u:object_r:file_context_t:s0 593470 Jul 19 09:10 file_contexts.bin
-rw-r--r--. 1 testuser testuser unconfined_u:object_r:file_context_t:s0  14704 Jul 19 09:10 file_contexts.homedirs
-rw-r--r--. 1 testuser testuser unconfined_u:object_r:file_context_t:s0  20289 Jul 19 09:10 file_contexts.homedirs.bin

  Both file context and ownership changed -- causes remote login
  failures and other issues in some scenarios.

Signed-off-by: Vit Mojzis <[email protected]>
[sds: amended to print a message on fchown failure to appease warning]
Signed-off-by: Stephen Smalley <[email protected]>
  • Loading branch information
vmojzis authored and stephensmalley committed Jul 26, 2024
1 parent 6a23546 commit 2defbce
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
34 changes: 34 additions & 0 deletions libsemanage/src/semanage_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ typedef struct dbase_policydb dbase_t;
#include "database_policydb.h"
#include "handle.h"

#include <selinux/restorecon.h>
#include <selinux/selinux.h>
#include <sepol/policydb.h>
#include <sepol/module.h>
Expand Down Expand Up @@ -767,6 +768,7 @@ int semanage_copy_file(const char *src, const char *dst, mode_t mode,
if (!retval && rename(tmp, dst) == -1)
return -1;

semanage_setfiles(dst);
out:
errno = errsv;
return retval;
Expand Down Expand Up @@ -819,6 +821,8 @@ static int semanage_copy_dir_flags(const char *src, const char *dst, int flag)
goto cleanup;
}
umask(mask);

semanage_setfiles(dst);
}

for (i = 0; i < len; i++) {
Expand All @@ -837,6 +841,7 @@ static int semanage_copy_dir_flags(const char *src, const char *dst, int flag)
goto cleanup;
}
umask(mask);
semanage_setfiles(path2);
} else if (S_ISREG(sb.st_mode) && flag == 1) {
mask = umask(0077);
if (semanage_copy_file(path, path2, sb.st_mode,
Expand Down Expand Up @@ -938,6 +943,7 @@ int semanage_mkdir(semanage_handle_t *sh, const char *path)

}
umask(mask);
semanage_setfiles(path);
}
else {
/* check that it really is a directory */
Expand Down Expand Up @@ -1614,16 +1620,19 @@ static int semanage_validate_and_compile_fcontexts(semanage_handle_t * sh)
semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC)) != 0) {
goto cleanup;
}
semanage_setfiles(semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_BIN));

if (sefcontext_compile(sh,
semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL)) != 0) {
goto cleanup;
}
semanage_setfiles(semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL_BIN));

if (sefcontext_compile(sh,
semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS)) != 0) {
goto cleanup;
}
semanage_setfiles(semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS_BIN));

status = 0;
cleanup:
Expand Down Expand Up @@ -3018,3 +3027,28 @@ int semanage_nc_sort(semanage_handle_t * sh, const char *buf, size_t buf_len,

return 0;
}

/* Make sure the file context and ownership of files in the policy
* store does not change */
void semanage_setfiles(const char *path){
struct stat sb;
int fd;
/* Fix the user and role portions of the context, ignore errors
* since this is not a critical operation */
(void) selinux_restorecon(path, SELINUX_RESTORECON_SET_SPECFILE_CTX | SELINUX_RESTORECON_IGNORE_NOENTRY);

/* Make sure "path" is owned by root */
if ((geteuid() != 0 || getegid() != 0) &&
((fd = open(path, O_RDONLY)) != -1)){
/* Skip files with the SUID or SGID bit set -- abuse protection */
if ((fstat(fd, &sb) != -1) &&
!(S_ISREG(sb.st_mode) &&
(sb.st_mode & (S_ISUID | S_ISGID)))) {
int rc = fchown(fd, 0, 0);
if (rc)
fprintf(stderr, "Could not set ownership on %s\n", path);
}

close(fd);
}
}
1 change: 1 addition & 0 deletions libsemanage/src/semanage_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ int semanage_get_cil_paths(semanage_handle_t * sh, semanage_module_info_t *modin
int semanage_get_active_modules(semanage_handle_t *sh,
semanage_module_info_t **modinfo, int *num_modules);

void semanage_setfiles(const char *path);

/* lock file routines */
int semanage_get_trans_lock(semanage_handle_t * sh);
Expand Down

0 comments on commit 2defbce

Please sign in to comment.