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

View File

@ -34,10 +34,6 @@
#ifndef COMMONIO_H
#define COMMONIO_H
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif
#include "defines.h" /* bool */
/*
@ -121,7 +117,7 @@ struct commonio_db {
/*@dependent@*/ /*@null@*/FILE *fp;
#ifdef WITH_SELINUX
/*@null@*/security_context_t scontext;
/*@null@*/char *scontext;
#endif
/*
* 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 */
#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 check_selinux_permit (const char *perm_name);
#endif

View File

@ -35,11 +35,20 @@
#include "defines.h"
#include <selinux/selinux.h>
#include <selinux/context.h>
#include <selinux/label.h>
#include "prototypes.h"
static bool selinux_checked = false;
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
@ -51,10 +60,8 @@ static bool selinux_enabled;
* Callers may have to Reset SELinux to create files with default
* 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) {
selinux_enabled = is_selinux_enabled () > 0;
selinux_checked = true;
@ -62,19 +69,34 @@ int set_selinux_file_context (const char *dst_name)
if (selinux_enabled) {
/* Get the default security context for this file */
if (matchpathcon (dst_name, 0, &scontext) < 0) {
if (security_getenforce () != 0) {
return 1;
/*@null@*/char *fcontext_raw = NULL;
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 */
if (setfscreatecon (scontext) < 0) {
if (security_getenforce () != 0) {
freecon (scontext);
return 1;
}
r = setfscreatecon_raw (fcontext_raw);
freecon (fcontext_raw);
if (r < 0) {
return security_getenforce () != 0;
}
freecon (scontext);
}
return 0;
}
@ -93,8 +115,8 @@ int reset_selinux_file_context (void)
selinux_checked = true;
}
if (selinux_enabled) {
if (setfscreatecon (NULL) != 0) {
return 1;
if (setfscreatecon_raw (NULL) != 0) {
return security_getenforce () != 0;
}
}
return 0;
@ -175,7 +197,7 @@ skip_syslog:
*/
int check_selinux_permit (const char *perm_name)
{
char *user_context_str;
char *user_context_raw;
int r;
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);
if (getprevcon (&user_context_str) != 0) {
if (getprevcon_raw (&user_context_raw) != 0) {
fprintf (stderr,
_("%s: can not get previous SELinux process context: %s\n"),
Prog, strerror (errno));
@ -194,8 +216,8 @@ int check_selinux_permit (const char *perm_name)
return (security_getenforce () != 0);
}
r = selinux_check_access (user_context_str, user_context_str, "passwd", perm_name, NULL);
freecon (user_context_str);
r = selinux_check_access (user_context_raw, user_context_raw, "passwd", perm_name, NULL);
freecon (user_context_raw);
return r;
}

View File

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

View File

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

View File

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

View File

@ -68,6 +68,9 @@
#ifdef ENABLE_SUBIDS
#include "subordinateio.h"
#endif /* ENABLE_SUBIDS */
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif /* WITH_SELINUX */
#ifdef WITH_TCB
#include "tcbfuncs.h"
#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
to be the context of the file we are editing */
if (is_selinux_enabled () != 0) {
security_context_t passwd_context=NULL;
char *passwd_context_raw = NULL;
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);
}
ret = setfscreatecon (passwd_context);
freecon (passwd_context);
ret = setfscreatecon_raw (passwd_context_raw);
freecon (passwd_context_raw);
if (0 != ret) {
vipwexit (_("setfscreatecon () failed"), errno, 1);
}
@ -401,7 +401,7 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
#ifdef WITH_SELINUX
/* unset the fscreatecon */
if (is_selinux_enabled () != 0) {
if (setfscreatecon (NULL) != 0) {
if (setfscreatecon_raw (NULL) != 0) {
vipwexit (_("setfscreatecon () failed"), errno, 1);
}
}