Merge pull request #323 from cgzones/selinux

SELinux modernizations
This commit is contained in:
Serge Hallyn 2021-05-07 08:32:01 -05:00 committed by GitHub
commit 3ac8d97825
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 65 additions and 38 deletions

View File

@ -974,7 +974,7 @@ int commonio_close (struct commonio_db *db)
snprintf (buf, sizeof buf, "%s-", db->filename); snprintf (buf, sizeof buf, "%s-", db->filename);
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
if (set_selinux_file_context (buf) != 0) { if (set_selinux_file_context (db->filename, S_IFREG) != 0) {
errors++; errors++;
} }
#endif #endif
@ -1007,7 +1007,7 @@ int commonio_close (struct commonio_db *db)
snprintf (buf, sizeof buf, "%s+", db->filename); snprintf (buf, sizeof buf, "%s+", db->filename);
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
if (set_selinux_file_context (buf) != 0) { if (set_selinux_file_context (db->filename, S_IFREG) != 0) {
errors++; errors++;
} }
#endif #endif

View File

@ -34,10 +34,6 @@
#ifndef COMMONIO_H #ifndef COMMONIO_H
#define COMMONIO_H #define COMMONIO_H
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif
#include "defines.h" /* bool */ #include "defines.h" /* bool */
/* /*
@ -121,7 +117,7 @@ struct commonio_db {
/*@dependent@*/ /*@null@*/FILE *fp; /*@dependent@*/ /*@null@*/FILE *fp;
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
/*@null@*/security_context_t scontext; /*@null@*/char *scontext;
#endif #endif
/* /*
* Default permissions and owner for newly created data file. * Default permissions and owner for newly created data file.

View File

@ -403,7 +403,7 @@ extern /*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const
/* selinux.c */ /* selinux.c */
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
extern int set_selinux_file_context (const char *dst_name); extern int set_selinux_file_context (const char *dst_name, mode_t mode);
extern int reset_selinux_file_context (void); extern int reset_selinux_file_context (void);
extern int check_selinux_permit (const char *perm_name); extern int check_selinux_permit (const char *perm_name);
#endif #endif

View File

@ -35,11 +35,20 @@
#include "defines.h" #include "defines.h"
#include <selinux/selinux.h> #include <selinux/selinux.h>
#include <selinux/context.h> #include <selinux/label.h>
#include "prototypes.h" #include "prototypes.h"
static bool selinux_checked = false; static bool selinux_checked = false;
static bool selinux_enabled; static bool selinux_enabled;
static /*@null@*/struct selabel_handle *selabel_hnd = NULL;
static void cleanup(void)
{
if (selabel_hnd) {
selabel_close(selabel_hnd);
selabel_hnd = NULL;
}
}
/* /*
* set_selinux_file_context - Set the security context before any file or * set_selinux_file_context - Set the security context before any file or
@ -51,10 +60,8 @@ static bool selinux_enabled;
* Callers may have to Reset SELinux to create files with default * Callers may have to Reset SELinux to create files with default
* contexts with reset_selinux_file_context * contexts with reset_selinux_file_context
*/ */
int set_selinux_file_context (const char *dst_name) int set_selinux_file_context (const char *dst_name, mode_t mode)
{ {
/*@null@*/security_context_t scontext = NULL;
if (!selinux_checked) { if (!selinux_checked) {
selinux_enabled = is_selinux_enabled () > 0; selinux_enabled = is_selinux_enabled () > 0;
selinux_checked = true; selinux_checked = true;
@ -62,20 +69,35 @@ int set_selinux_file_context (const char *dst_name)
if (selinux_enabled) { if (selinux_enabled) {
/* Get the default security context for this file */ /* Get the default security context for this file */
if (matchpathcon (dst_name, 0, &scontext) < 0) {
if (security_getenforce () != 0) { /*@null@*/char *fcontext_raw = NULL;
return 1; int r;
if (selabel_hnd == NULL) {
selabel_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
if (selabel_hnd == NULL) {
return security_getenforce () != 0;
} }
(void) atexit(cleanup);
} }
r = selabel_lookup_raw(selabel_hnd, &fcontext_raw, dst_name, mode);
if (r < 0) {
/* No context specified for the searched path */
if (errno == ENOENT) {
return 0;
}
return security_getenforce () != 0;
}
/* Set the security context for the next created file */ /* Set the security context for the next created file */
if (setfscreatecon (scontext) < 0) { r = setfscreatecon_raw (fcontext_raw);
if (security_getenforce () != 0) { freecon (fcontext_raw);
freecon (scontext); if (r < 0) {
return 1; return security_getenforce () != 0;
} }
} }
freecon (scontext);
}
return 0; return 0;
} }
@ -93,8 +115,8 @@ int reset_selinux_file_context (void)
selinux_checked = true; selinux_checked = true;
} }
if (selinux_enabled) { if (selinux_enabled) {
if (setfscreatecon (NULL) != 0) { if (setfscreatecon_raw (NULL) != 0) {
return 1; return security_getenforce () != 0;
} }
} }
return 0; return 0;
@ -175,7 +197,7 @@ skip_syslog:
*/ */
int check_selinux_permit (const char *perm_name) int check_selinux_permit (const char *perm_name)
{ {
char *user_context_str; char *user_context_raw;
int r; int r;
if (0 == is_selinux_enabled ()) { if (0 == is_selinux_enabled ()) {
@ -184,7 +206,7 @@ int check_selinux_permit (const char *perm_name)
selinux_set_callback (SELINUX_CB_LOG, (union selinux_callback) selinux_log_cb); selinux_set_callback (SELINUX_CB_LOG, (union selinux_callback) selinux_log_cb);
if (getprevcon (&user_context_str) != 0) { if (getprevcon_raw (&user_context_raw) != 0) {
fprintf (stderr, fprintf (stderr,
_("%s: can not get previous SELinux process context: %s\n"), _("%s: can not get previous SELinux process context: %s\n"),
Prog, strerror (errno)); Prog, strerror (errno));
@ -194,8 +216,8 @@ int check_selinux_permit (const char *perm_name)
return (security_getenforce () != 0); return (security_getenforce () != 0);
} }
r = selinux_check_access (user_context_str, user_context_str, "passwd", perm_name, NULL); r = selinux_check_access (user_context_raw, user_context_raw, "passwd", perm_name, NULL);
freecon (user_context_str); freecon (user_context_raw);
return r; return r;
} }

View File

@ -484,7 +484,7 @@ static int copy_dir (const char *src, const char *dst,
*/ */
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
if (set_selinux_file_context (dst) != 0) { if (set_selinux_file_context (dst, S_IFDIR) != 0) {
return -1; return -1;
} }
#endif /* WITH_SELINUX */ #endif /* WITH_SELINUX */
@ -605,7 +605,7 @@ static int copy_symlink (const char *src, const char *dst,
} }
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
if (set_selinux_file_context (dst) != 0) { if (set_selinux_file_context (dst, S_IFLNK) != 0) {
free (oldlink); free (oldlink);
return -1; return -1;
} }
@ -684,7 +684,7 @@ static int copy_special (const char *src, const char *dst,
int err = 0; int err = 0;
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
if (set_selinux_file_context (dst) != 0) { if (set_selinux_file_context (dst, statp->st_mode & S_IFMT) != 0) {
return -1; return -1;
} }
#endif /* WITH_SELINUX */ #endif /* WITH_SELINUX */
@ -744,7 +744,7 @@ static int copy_file (const char *src, const char *dst,
return -1; return -1;
} }
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
if (set_selinux_file_context (dst) != 0) { if (set_selinux_file_context (dst, S_IFREG) != 0) {
return -1; return -1;
} }
#endif /* WITH_SELINUX */ #endif /* WITH_SELINUX */

View File

@ -69,6 +69,9 @@
#include "sgroupio.h" #include "sgroupio.h"
#endif #endif
#include "shadowio.h" #include "shadowio.h"
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif /* WITH_SELINUX */
#ifdef ENABLE_SUBIDS #ifdef ENABLE_SUBIDS
#include "subordinateio.h" #include "subordinateio.h"
#endif /* ENABLE_SUBIDS */ #endif /* ENABLE_SUBIDS */
@ -2174,7 +2177,7 @@ static void create_home (void)
++bhome; ++bhome;
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
if (set_selinux_file_context (prefix_user_home) != 0) { if (set_selinux_file_context (prefix_user_home, S_IFDIR) != 0) {
fprintf (stderr, fprintf (stderr,
_("%s: cannot set SELinux context for home directory %s\n"), _("%s: cannot set SELinux context for home directory %s\n"),
Prog, user_home); Prog, user_home);
@ -2302,7 +2305,7 @@ static void create_mail (void)
sprintf (file, "%s/%s", spool, user_name); sprintf (file, "%s/%s", spool, user_name);
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
if (set_selinux_file_context (file) != 0) { if (set_selinux_file_context (file, S_IFREG) != 0) {
fprintf (stderr, fprintf (stderr,
_("%s: cannot set SELinux context for mailbox file %s\n"), _("%s: cannot set SELinux context for mailbox file %s\n"),
Prog, file); Prog, file);

View File

@ -59,6 +59,9 @@
#ifdef SHADOWGRP #ifdef SHADOWGRP
#include "sgroupio.h" #include "sgroupio.h"
#endif /* SHADOWGRP */ #endif /* SHADOWGRP */
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif /* WITH_SELINUX */
#ifdef WITH_TCB #ifdef WITH_TCB
#include <tcb.h> #include <tcb.h>
#include "tcbfuncs.h" #include "tcbfuncs.h"

View File

@ -68,6 +68,9 @@
#ifdef ENABLE_SUBIDS #ifdef ENABLE_SUBIDS
#include "subordinateio.h" #include "subordinateio.h"
#endif /* ENABLE_SUBIDS */ #endif /* ENABLE_SUBIDS */
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif /* WITH_SELINUX */
#ifdef WITH_TCB #ifdef WITH_TCB
#include "tcbfuncs.h" #include "tcbfuncs.h"
#endif #endif

View File

@ -243,13 +243,13 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
/* if SE Linux is enabled then set the context of all new files /* if SE Linux is enabled then set the context of all new files
to be the context of the file we are editing */ to be the context of the file we are editing */
if (is_selinux_enabled () != 0) { if (is_selinux_enabled () != 0) {
security_context_t passwd_context=NULL; char *passwd_context_raw = NULL;
int ret = 0; int ret = 0;
if (getfilecon (file, &passwd_context) < 0) { if (getfilecon_raw (file, &passwd_context_raw) < 0) {
vipwexit (_("Couldn't get file context"), errno, 1); vipwexit (_("Couldn't get file context"), errno, 1);
} }
ret = setfscreatecon (passwd_context); ret = setfscreatecon_raw (passwd_context_raw);
freecon (passwd_context); freecon (passwd_context_raw);
if (0 != ret) { if (0 != ret) {
vipwexit (_("setfscreatecon () failed"), errno, 1); vipwexit (_("setfscreatecon () failed"), errno, 1);
} }
@ -401,7 +401,7 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
/* unset the fscreatecon */ /* unset the fscreatecon */
if (is_selinux_enabled () != 0) { if (is_selinux_enabled () != 0) {
if (setfscreatecon (NULL) != 0) { if (setfscreatecon_raw (NULL) != 0) {
vipwexit (_("setfscreatecon () failed"), errno, 1); vipwexit (_("setfscreatecon () failed"), errno, 1);
} }
} }