merge upstream 3.4
This commit is contained in:
parent
08d0753084
commit
b6f30e98e8
24
Makefile
24
Makefile
|
@ -1,9 +1,10 @@
|
|||
SUBDIRS = src include utils man
|
||||
SUBDIRS = include src utils man
|
||||
|
||||
PKG_CONFIG ?= pkg-config
|
||||
DISABLE_SETRANS ?= n
|
||||
DISABLE_RPM ?= n
|
||||
ANDROID_HOST ?= n
|
||||
LABEL_BACKEND_ANDROID ?= n
|
||||
ifeq ($(ANDROID_HOST),y)
|
||||
override DISABLE_SETRANS=y
|
||||
override DISABLE_BOOL=y
|
||||
|
@ -17,9 +18,12 @@ endif
|
|||
ifeq ($(DISABLE_BOOL),y)
|
||||
DISABLE_FLAGS+= -DDISABLE_BOOL
|
||||
endif
|
||||
export DISABLE_SETRANS DISABLE_RPM DISABLE_FLAGS ANDROID_HOST
|
||||
ifeq ($(DISABLE_X11),y)
|
||||
DISABLE_FLAGS+= -DNO_X_BACKEND
|
||||
endif
|
||||
export DISABLE_SETRANS DISABLE_RPM DISABLE_FLAGS ANDROID_HOST DISABLE_X11 LABEL_BACKEND_ANDROID
|
||||
|
||||
USE_PCRE2 ?= n
|
||||
USE_PCRE2 ?= y
|
||||
ifeq ($(USE_PCRE2),y)
|
||||
PCRE_MODULE := libpcre2-8
|
||||
PCRE_CFLAGS := -DUSE_PCRE2 -DPCRE2_CODE_UNIT_WIDTH=8
|
||||
|
@ -46,24 +50,24 @@ all install relabel clean distclean indent:
|
|||
done
|
||||
|
||||
swigify: all
|
||||
$(MAKE) -C src swigify $@
|
||||
$(MAKE) -C src $@
|
||||
|
||||
pywrap:
|
||||
$(MAKE) -C src pywrap $@
|
||||
$(MAKE) -C src $@
|
||||
|
||||
rubywrap:
|
||||
$(MAKE) -C src rubywrap $@
|
||||
$(MAKE) -C src $@
|
||||
|
||||
install-pywrap:
|
||||
$(MAKE) -C src install-pywrap $@
|
||||
$(MAKE) -C src $@
|
||||
|
||||
install-rubywrap:
|
||||
$(MAKE) -C src install-rubywrap $@
|
||||
$(MAKE) -C src $@
|
||||
|
||||
clean-pywrap:
|
||||
$(MAKE) -C src clean-pywrap $@
|
||||
$(MAKE) -C src $@
|
||||
|
||||
clean-rubywrap:
|
||||
$(MAKE) -C src clean-rubywrap $@
|
||||
$(MAKE) -C src $@
|
||||
|
||||
test:
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
libselinux (3.4-ok1) yangtze; urgency=medium
|
||||
|
||||
* Update upstream version.
|
||||
|
||||
-- sufang <sufang@kylinos.cn> Fri, 17 Feb 2023 16:03:29 +0800
|
||||
|
||||
libselinux (3.0-ok1) yangtze; urgency=medium
|
||||
|
||||
* Build for openKylin.
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
From: Laurent Bigonville <bigon@debian.org>
|
||||
Date: Sat, 14 May 2022 01:18:46 +0800
|
||||
Subject: Fix installation layout for debian-like distributions
|
||||
|
||||
Forwarded: no
|
||||
---
|
||||
src/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/Makefile b/src/Makefile
|
||||
index 7f5a5d7..e42d612 100644
|
||||
--- a/src/Makefile
|
||||
+++ b/src/Makefile
|
||||
@@ -173,7 +173,7 @@ install: all
|
||||
ln -sf --relative $(DESTDIR)$(SHLIBDIR)/$(LIBSO) $(DESTDIR)$(LIBDIR)/$(TARGET)
|
||||
|
||||
install-pywrap: pywrap
|
||||
- $(PYTHON) setup.py install --prefix=$(PREFIX) `test -n "$(DESTDIR)" && echo --root $(DESTDIR)`
|
||||
+ $(PYTHON) setup.py install --prefix=$(PREFIX) `test -n "$(DESTDIR)" && echo --root $(DESTDIR)` --install-layout=deb
|
||||
install -m 644 $(SWIGPYOUT) $(DESTDIR)$(PYTHONLIBDIR)/selinux/__init__.py
|
||||
ln -sf --relative $(DESTDIR)$(PYTHONLIBDIR)/selinux/_selinux$(PYCEXT) $(DESTDIR)$(PYTHONLIBDIR)/_selinux$(PYCEXT)
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -64,7 +64,11 @@ extern int avc_context_to_sid_raw(const char * ctx, security_id_t * sid);
|
|||
* reference count). Note that avc_context_to_sid() also
|
||||
* increments reference counts.
|
||||
*/
|
||||
extern int sidget(security_id_t sid);
|
||||
extern int sidget(security_id_t sid)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated))
|
||||
#endif
|
||||
;
|
||||
|
||||
/**
|
||||
* sidput - decrement SID reference counter.
|
||||
|
@ -76,7 +80,11 @@ extern int sidget(security_id_t sid);
|
|||
* zero, the SID is invalid, and avc_context_to_sid() must
|
||||
* be called to obtain a new SID for the security context.
|
||||
*/
|
||||
extern int sidput(security_id_t sid);
|
||||
extern int sidput(security_id_t sid)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated))
|
||||
#endif
|
||||
;
|
||||
|
||||
/**
|
||||
* avc_get_initial_sid - get SID for an initial kernel security identifier
|
||||
|
@ -192,7 +200,11 @@ extern int avc_init(const char *msgprefix,
|
|||
const struct avc_memory_callback *mem_callbacks,
|
||||
const struct avc_log_callback *log_callbacks,
|
||||
const struct avc_thread_callback *thread_callbacks,
|
||||
const struct avc_lock_callback *lock_callbacks);
|
||||
const struct avc_lock_callback *lock_callbacks)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated("Use avc_open and selinux_set_callback")))
|
||||
#endif
|
||||
;
|
||||
|
||||
/**
|
||||
* avc_open - Initialize the AVC.
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
/* This file is automatically generated. Do not edit. */
|
||||
#ifndef _SELINUX_FLASK_H_
|
||||
#define _SELINUX_FLASK_H_
|
||||
|
||||
#warning "Please remove any #include's of this header in your source code."
|
||||
#warning "Instead, use string_to_security_class() to map the class name to a value."
|
||||
|
||||
/*
|
||||
* Security object class definitions
|
||||
*/
|
||||
#define SECCLASS_SECURITY 1
|
||||
#define SECCLASS_PROCESS 2
|
||||
#define SECCLASS_SYSTEM 3
|
||||
#define SECCLASS_CAPABILITY 4
|
||||
#define SECCLASS_FILESYSTEM 5
|
||||
#define SECCLASS_FILE 6
|
||||
#define SECCLASS_DIR 7
|
||||
#define SECCLASS_FD 8
|
||||
#define SECCLASS_LNK_FILE 9
|
||||
#define SECCLASS_CHR_FILE 10
|
||||
#define SECCLASS_BLK_FILE 11
|
||||
#define SECCLASS_SOCK_FILE 12
|
||||
#define SECCLASS_FIFO_FILE 13
|
||||
#define SECCLASS_SOCKET 14
|
||||
#define SECCLASS_TCP_SOCKET 15
|
||||
#define SECCLASS_UDP_SOCKET 16
|
||||
#define SECCLASS_RAWIP_SOCKET 17
|
||||
#define SECCLASS_NODE 18
|
||||
#define SECCLASS_NETIF 19
|
||||
#define SECCLASS_NETLINK_SOCKET 20
|
||||
#define SECCLASS_PACKET_SOCKET 21
|
||||
#define SECCLASS_KEY_SOCKET 22
|
||||
#define SECCLASS_UNIX_STREAM_SOCKET 23
|
||||
#define SECCLASS_UNIX_DGRAM_SOCKET 24
|
||||
#define SECCLASS_SEM 25
|
||||
#define SECCLASS_MSG 26
|
||||
#define SECCLASS_MSGQ 27
|
||||
#define SECCLASS_SHM 28
|
||||
#define SECCLASS_IPC 29
|
||||
#define SECCLASS_PASSWD 30
|
||||
#define SECCLASS_X_DRAWABLE 31
|
||||
#define SECCLASS_X_SCREEN 32
|
||||
#define SECCLASS_X_GC 33
|
||||
#define SECCLASS_X_FONT 34
|
||||
#define SECCLASS_X_COLORMAP 35
|
||||
#define SECCLASS_X_PROPERTY 36
|
||||
#define SECCLASS_X_SELECTION 37
|
||||
#define SECCLASS_X_CURSOR 38
|
||||
#define SECCLASS_X_CLIENT 39
|
||||
#define SECCLASS_X_DEVICE 40
|
||||
#define SECCLASS_X_SERVER 41
|
||||
#define SECCLASS_X_EXTENSION 42
|
||||
#define SECCLASS_NETLINK_ROUTE_SOCKET 43
|
||||
#define SECCLASS_NETLINK_FIREWALL_SOCKET 44
|
||||
#define SECCLASS_NETLINK_TCPDIAG_SOCKET 45
|
||||
#define SECCLASS_NETLINK_NFLOG_SOCKET 46
|
||||
#define SECCLASS_NETLINK_XFRM_SOCKET 47
|
||||
#define SECCLASS_NETLINK_SELINUX_SOCKET 48
|
||||
#define SECCLASS_NETLINK_AUDIT_SOCKET 49
|
||||
#define SECCLASS_NETLINK_IP6FW_SOCKET 50
|
||||
#define SECCLASS_NETLINK_DNRT_SOCKET 51
|
||||
#define SECCLASS_DBUS 52
|
||||
#define SECCLASS_NSCD 53
|
||||
#define SECCLASS_ASSOCIATION 54
|
||||
#define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET 55
|
||||
#define SECCLASS_APPLETALK_SOCKET 56
|
||||
#define SECCLASS_PACKET 57
|
||||
#define SECCLASS_KEY 58
|
||||
#define SECCLASS_CONTEXT 59
|
||||
#define SECCLASS_DCCP_SOCKET 60
|
||||
#define SECCLASS_MEMPROTECT 61
|
||||
#define SECCLASS_DB_DATABASE 62
|
||||
#define SECCLASS_DB_TABLE 63
|
||||
#define SECCLASS_DB_PROCEDURE 64
|
||||
#define SECCLASS_DB_COLUMN 65
|
||||
#define SECCLASS_DB_TUPLE 66
|
||||
#define SECCLASS_DB_BLOB 67
|
||||
#define SECCLASS_PEER 68
|
||||
#define SECCLASS_CAPABILITY2 69
|
||||
#define SECCLASS_X_RESOURCE 70
|
||||
#define SECCLASS_X_EVENT 71
|
||||
#define SECCLASS_X_SYNTHETIC_EVENT 72
|
||||
#define SECCLASS_X_APPLICATION_DATA 73
|
||||
|
||||
/*
|
||||
* Security identifier indices for initial entities
|
||||
*/
|
||||
#define SECINITSID_KERNEL 1
|
||||
#define SECINITSID_SECURITY 2
|
||||
#define SECINITSID_UNLABELED 3
|
||||
#define SECINITSID_FS 4
|
||||
#define SECINITSID_FILE 5
|
||||
#define SECINITSID_FILE_LABELS 6
|
||||
#define SECINITSID_INIT 7
|
||||
#define SECINITSID_ANY_SOCKET 8
|
||||
#define SECINITSID_PORT 9
|
||||
#define SECINITSID_NETIF 10
|
||||
#define SECINITSID_NETMSG 11
|
||||
#define SECINITSID_NODE 12
|
||||
#define SECINITSID_IGMP_PACKET 13
|
||||
#define SECINITSID_ICMP_SOCKET 14
|
||||
#define SECINITSID_TCP_SOCKET 15
|
||||
#define SECINITSID_SYSCTL_MODPROBE 16
|
||||
#define SECINITSID_SYSCTL 17
|
||||
#define SECINITSID_SYSCTL_FS 18
|
||||
#define SECINITSID_SYSCTL_KERNEL 19
|
||||
#define SECINITSID_SYSCTL_NET 20
|
||||
#define SECINITSID_SYSCTL_NET_UNIX 21
|
||||
#define SECINITSID_SYSCTL_VM 22
|
||||
#define SECINITSID_SYSCTL_DEV 23
|
||||
#define SECINITSID_KMOD 24
|
||||
#define SECINITSID_POLICY 25
|
||||
#define SECINITSID_SCMP_PACKET 26
|
||||
#define SECINITSID_DEVNULL 27
|
||||
|
||||
#define SECINITSID_NUM 27
|
||||
|
||||
#endif
|
|
@ -17,14 +17,14 @@ extern "C" {
|
|||
If 'fromcon' is NULL, defaults to current context.
|
||||
Caller must free via freeconary. */
|
||||
extern int get_ordered_context_list(const char *user,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char *** list);
|
||||
|
||||
/* As above, but use the provided MLS level rather than the
|
||||
default level for the user. */
|
||||
extern int get_ordered_context_list_with_level(const char *user,
|
||||
const char *level,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char *** list);
|
||||
|
||||
/* Get the default security context for a user session for 'user'
|
||||
|
@ -35,14 +35,14 @@ extern "C" {
|
|||
Returns 0 on success or -1 otherwise.
|
||||
Caller must free via freecon. */
|
||||
extern int get_default_context(const char *user,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char ** newcon);
|
||||
|
||||
/* As above, but use the provided MLS level rather than the
|
||||
default level for the user. */
|
||||
extern int get_default_context_with_level(const char *user,
|
||||
const char *level,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char ** newcon);
|
||||
|
||||
/* Same as get_default_context, but only return a context
|
||||
|
@ -50,7 +50,7 @@ extern "C" {
|
|||
for the user with that role, then return -1. */
|
||||
extern int get_default_context_with_role(const char *user,
|
||||
const char *role,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char ** newcon);
|
||||
|
||||
/* Same as get_default_context, but only return a context
|
||||
|
@ -59,7 +59,7 @@ extern "C" {
|
|||
extern int get_default_context_with_rolelevel(const char *user,
|
||||
const char *role,
|
||||
const char *level,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char ** newcon);
|
||||
|
||||
/* Given a list of authorized security contexts for the user,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _RESTORECON_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -23,6 +24,19 @@ extern "C" {
|
|||
*/
|
||||
extern int selinux_restorecon(const char *pathname,
|
||||
unsigned int restorecon_flags);
|
||||
/**
|
||||
* selinux_restorecon_parallel - Relabel files, optionally use more threads.
|
||||
* @pathname: specifies file/directory to relabel.
|
||||
* @restorecon_flags: specifies the actions to be performed when relabeling.
|
||||
* @nthreads: specifies the number of threads to use (0 = use number of CPUs
|
||||
* currently online)
|
||||
*
|
||||
* Same as selinux_restorecon(3), but allows to use multiple threads to do
|
||||
* the work.
|
||||
*/
|
||||
extern int selinux_restorecon_parallel(const char *pathname,
|
||||
unsigned int restorecon_flags,
|
||||
size_t nthreads);
|
||||
/*
|
||||
* restorecon_flags options
|
||||
*/
|
||||
|
@ -30,77 +44,87 @@ extern int selinux_restorecon(const char *pathname,
|
|||
* Force the checking of labels even if the stored SHA1 digest
|
||||
* matches the specfiles SHA1 digest (requires CAP_SYS_ADMIN).
|
||||
*/
|
||||
#define SELINUX_RESTORECON_IGNORE_DIGEST 0x0001
|
||||
#define SELINUX_RESTORECON_IGNORE_DIGEST 0x00001
|
||||
/*
|
||||
* Do not change file labels.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_NOCHANGE 0x0002
|
||||
#define SELINUX_RESTORECON_NOCHANGE 0x00002
|
||||
/*
|
||||
* If set, change file label to that in spec file.
|
||||
* If not, only change type component to that in spec file.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_SET_SPECFILE_CTX 0x0004
|
||||
#define SELINUX_RESTORECON_SET_SPECFILE_CTX 0x00004
|
||||
/*
|
||||
* Recursively descend directories.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_RECURSE 0x0008
|
||||
#define SELINUX_RESTORECON_RECURSE 0x00008
|
||||
/*
|
||||
* Log changes to selinux log. Note that if VERBOSE and
|
||||
* PROGRESS are set, then PROGRESS will take precedence.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_VERBOSE 0x0010
|
||||
#define SELINUX_RESTORECON_VERBOSE 0x00010
|
||||
/*
|
||||
* If SELINUX_RESTORECON_PROGRESS is true and
|
||||
* SELINUX_RESTORECON_MASS_RELABEL is true, then output approx % complete,
|
||||
* else output the number of files in 1k blocks processed to stdout.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_PROGRESS 0x0020
|
||||
#define SELINUX_RESTORECON_PROGRESS 0x00020
|
||||
/*
|
||||
* Convert passed-in pathname to canonical pathname.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_REALPATH 0x0040
|
||||
#define SELINUX_RESTORECON_REALPATH 0x00040
|
||||
/*
|
||||
* Prevent descending into directories that have a different
|
||||
* device number than the pathname from which the descent began.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_XDEV 0x0080
|
||||
#define SELINUX_RESTORECON_XDEV 0x00080
|
||||
/*
|
||||
* Attempt to add an association between an inode and a specification.
|
||||
* If there is already an association for the inode and it conflicts
|
||||
* with the specification, then use the last matching specification.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_ADD_ASSOC 0x0100
|
||||
#define SELINUX_RESTORECON_ADD_ASSOC 0x00100
|
||||
/*
|
||||
* Abort on errors during the file tree walk.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_ABORT_ON_ERROR 0x0200
|
||||
#define SELINUX_RESTORECON_ABORT_ON_ERROR 0x00200
|
||||
/*
|
||||
* Log any label changes to syslog.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_SYSLOG_CHANGES 0x0400
|
||||
#define SELINUX_RESTORECON_SYSLOG_CHANGES 0x00400
|
||||
/*
|
||||
* Log what spec matched each file.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_LOG_MATCHES 0x0800
|
||||
#define SELINUX_RESTORECON_LOG_MATCHES 0x00800
|
||||
/*
|
||||
* Ignore files that do not exist.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_IGNORE_NOENTRY 0x1000
|
||||
#define SELINUX_RESTORECON_IGNORE_NOENTRY 0x01000
|
||||
/*
|
||||
* Do not read /proc/mounts to obtain a list of non-seclabel
|
||||
* mounts to be excluded from relabeling checks.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_IGNORE_MOUNTS 0x2000
|
||||
#define SELINUX_RESTORECON_IGNORE_MOUNTS 0x02000
|
||||
/*
|
||||
* Set if there is a mass relabel required.
|
||||
* See SELINUX_RESTORECON_PROGRESS flag for details.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_MASS_RELABEL 0x4000
|
||||
#define SELINUX_RESTORECON_MASS_RELABEL 0x04000
|
||||
/*
|
||||
* Set if no digest is to be read or written (as only processes
|
||||
* running with CAP_SYS_ADMIN can read/write digests).
|
||||
*/
|
||||
#define SELINUX_RESTORECON_SKIP_DIGEST 0x8000
|
||||
#define SELINUX_RESTORECON_SKIP_DIGEST 0x08000
|
||||
|
||||
/*
|
||||
* Set to treat conflicting specifications as errors.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_CONFLICT_ERROR 0x10000
|
||||
|
||||
/*
|
||||
* Count, but otherwise ignore, errors during the file tree walk.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_COUNT_ERRORS 0x20000
|
||||
|
||||
/**
|
||||
* selinux_restorecon_set_sehandle - Set the global fc handle.
|
||||
|
@ -186,6 +210,16 @@ extern int selinux_restorecon_xattr(const char *pathname,
|
|||
/* Do not read /proc/mounts. */
|
||||
#define SELINUX_RESTORECON_XATTR_IGNORE_MOUNTS 0x0008
|
||||
|
||||
/* selinux_restorecon_get_skipped_errors - Get the number of errors ignored
|
||||
* during re-labeling.
|
||||
*
|
||||
* If SELINUX_RESTORECON_COUNT_ERRORS was passed to selinux_restorecon(3) or
|
||||
* selinux_restorecon_parallel(3), and that function returned successfully
|
||||
* (i.e., with a zero return value), then this function returns the number of
|
||||
* errors ignored during the file tree walk.
|
||||
*/
|
||||
extern long unsigned selinux_restorecon_get_skipped_errors(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -8,13 +8,17 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Return 1 if we are running on a SELinux kernel, or 0 if not or -1 if we get an error. */
|
||||
/* Return 1 if we are running on a SELinux kernel, or 0 otherwise. */
|
||||
extern int is_selinux_enabled(void);
|
||||
/* Return 1 if we are running on a SELinux MLS kernel, or 0 otherwise. */
|
||||
extern int is_selinux_mls_enabled(void);
|
||||
|
||||
/* No longer used; here for compatibility with legacy callers. */
|
||||
typedef char *security_context_t;
|
||||
typedef char *security_context_t
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated))
|
||||
#endif
|
||||
;
|
||||
|
||||
/* Free the memory allocated for a context by any of the below get* calls. */
|
||||
extern void freecon(char * con);
|
||||
|
@ -178,6 +182,8 @@ extern void selinux_set_callback(int type, union selinux_callback cb);
|
|||
#define SELINUX_WARNING 1
|
||||
#define SELINUX_INFO 2
|
||||
#define SELINUX_AVC 3
|
||||
#define SELINUX_POLICYLOAD 4
|
||||
#define SELINUX_SETENFORCE 5
|
||||
#define SELINUX_TRANS_DIR "/var/run/setrans"
|
||||
|
||||
/* Compute an access decision. */
|
||||
|
@ -246,8 +252,12 @@ extern int security_compute_member_raw(const char * scon,
|
|||
security_class_t tclass,
|
||||
char ** newcon);
|
||||
|
||||
/* Compute the set of reachable user contexts and set *con to refer to
|
||||
the NULL-terminated array of contexts. Caller must free via freeconary. */
|
||||
/*
|
||||
* Compute the set of reachable user contexts and set *con to refer to
|
||||
* the NULL-terminated array of contexts. Caller must free via freeconary.
|
||||
* These interfaces are deprecated. Use get_ordered_context_list() or
|
||||
* one of its variant interfaces instead.
|
||||
*/
|
||||
extern int security_compute_user(const char * scon,
|
||||
const char *username,
|
||||
char *** con);
|
||||
|
@ -319,9 +329,13 @@ extern int security_set_boolean_list(size_t boolcnt,
|
|||
SELboolean * boollist, int permanent);
|
||||
|
||||
/* Load policy boolean settings. Deprecated as local policy booleans no
|
||||
* longer supported. Will always return 0.
|
||||
* longer supported. Will always return -1.
|
||||
*/
|
||||
extern int security_load_booleans(char *path);
|
||||
extern int security_load_booleans(char *path)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated))
|
||||
#endif
|
||||
;
|
||||
|
||||
/* Check the validity of a security context. */
|
||||
extern int security_check_context(const char * con);
|
||||
|
@ -418,6 +432,9 @@ extern int security_av_string(security_class_t tclass,
|
|||
/* Display an access vector in a string representation. */
|
||||
extern void print_access_vector(security_class_t tclass, access_vector_t av);
|
||||
|
||||
/* Flush the SELinux class cache, e.g. upon a policy reload. */
|
||||
extern void selinux_flush_class_cache(void);
|
||||
|
||||
/* Set the function used by matchpathcon_init when displaying
|
||||
errors about the file_contexts configuration. If not set,
|
||||
then this defaults to fprintf(stderr, fmt, ...). */
|
||||
|
@ -454,14 +471,22 @@ extern void set_matchpathcon_flags(unsigned int flags);
|
|||
function also checks for a 'path'.homedirs file and
|
||||
a 'path'.local file and loads additional specifications
|
||||
from them if present. */
|
||||
extern int matchpathcon_init(const char *path);
|
||||
extern int matchpathcon_init(const char *path)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated("Use selabel_open with backend SELABEL_CTX_FILE")))
|
||||
#endif
|
||||
;
|
||||
|
||||
/* Same as matchpathcon_init, but only load entries with
|
||||
regexes that have stems that are prefixes of 'prefix'. */
|
||||
extern int matchpathcon_init_prefix(const char *path, const char *prefix);
|
||||
|
||||
/* Free the memory allocated by matchpathcon_init. */
|
||||
extern void matchpathcon_fini(void);
|
||||
extern void matchpathcon_fini(void)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated("Use selabel_close")))
|
||||
#endif
|
||||
;
|
||||
|
||||
/* Resolve all of the symlinks and relative portions of a pathname, but NOT
|
||||
* the final component (same a realpath() unless the final component is a
|
||||
|
@ -475,7 +500,11 @@ extern int realpath_not_final(const char *name, char *resolved_path);
|
|||
If matchpathcon_init has not already been called, then this function
|
||||
will call it upon its first invocation with a NULL path. */
|
||||
extern int matchpathcon(const char *path,
|
||||
mode_t mode, char ** con);
|
||||
mode_t mode, char ** con)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated("Use selabel_lookup instead")))
|
||||
#endif
|
||||
;
|
||||
|
||||
/* Same as above, but return a specification index for
|
||||
later use in a matchpathcon_filespec_add() call - see below. */
|
||||
|
@ -568,10 +597,18 @@ extern const char *selinux_contexts_path(void);
|
|||
extern const char *selinux_securetty_types_path(void);
|
||||
extern const char *selinux_booleans_subs_path(void);
|
||||
/* Deprecated as local policy booleans no longer supported. */
|
||||
extern const char *selinux_booleans_path(void);
|
||||
extern const char *selinux_booleans_path(void)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated))
|
||||
#endif
|
||||
;
|
||||
extern const char *selinux_customizable_types_path(void);
|
||||
/* Deprecated as policy ./users no longer supported. */
|
||||
extern const char *selinux_users_path(void);
|
||||
extern const char *selinux_users_path(void)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated))
|
||||
#endif
|
||||
;
|
||||
extern const char *selinux_usersconf_path(void);
|
||||
extern const char *selinux_translations_path(void);
|
||||
extern const char *selinux_colors_path(void);
|
||||
|
@ -599,8 +636,17 @@ extern int selinux_check_access(const char * scon, const char * tcon, const char
|
|||
|
||||
/* Check a permission in the passwd class.
|
||||
Return 0 if granted or -1 otherwise. */
|
||||
extern int selinux_check_passwd_access(access_vector_t requested);
|
||||
extern int checkPasswdAccess(access_vector_t requested);
|
||||
extern int selinux_check_passwd_access(access_vector_t requested)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated("Use selinux_check_access")))
|
||||
#endif
|
||||
;
|
||||
|
||||
extern int checkPasswdAccess(access_vector_t requested)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated("Use selinux_check_access")))
|
||||
#endif
|
||||
;
|
||||
|
||||
/* Check if the tty_context is defined as a securetty
|
||||
Return 0 if secure, < 0 otherwise. */
|
||||
|
@ -626,7 +672,11 @@ extern int setexecfilecon(const char *filename, const char *fallback_type);
|
|||
/* Execute a helper for rpm in an appropriate security context. */
|
||||
extern int rpm_execcon(unsigned int verified,
|
||||
const char *filename,
|
||||
char *const argv[], char *const envp[]);
|
||||
char *const argv[], char *const envp[])
|
||||
#ifdef __GNUC__
|
||||
__attribute__((deprecated("Use setexecfilecon and execve")))
|
||||
#endif
|
||||
;
|
||||
#endif
|
||||
|
||||
/* Returns whether a file context is customizable, and should not
|
||||
|
|
|
@ -34,6 +34,36 @@ avc_has_perm, avc_has_perm_noaudit, avc_audit, avc_entry_ref_init \- obtain and
|
|||
.in
|
||||
.
|
||||
.SH "DESCRIPTION"
|
||||
|
||||
Direct use of these functions is generally discouraged in favor of
|
||||
the higher level interface
|
||||
.BR selinux_check_access(3)
|
||||
since the latter automatically handles the dynamic mapping of class
|
||||
and permission names to their policy values and proper handling of
|
||||
allow_unknown.
|
||||
|
||||
When using any of the functions that take policy integer values for
|
||||
classes or permissions as inputs, use
|
||||
.BR string_to_security_class(3)
|
||||
and
|
||||
.BR string_to_av_perm(3)
|
||||
to map the class and permission names to their policy values.
|
||||
These values may change across a policy reload, so they should be
|
||||
re-acquired on every use or using a
|
||||
.B SELINUX_CB_POLICYLOAD
|
||||
callback set via
|
||||
.BR selinux_set_callback(3).
|
||||
|
||||
An alternative approach is to use
|
||||
.BR selinux_set_mapping(3)
|
||||
to create a mapping from class and permission index values
|
||||
used by the application to the policy values,
|
||||
thereby allowing the application to pass its own
|
||||
fixed constants for the classes and permissions to
|
||||
these functions and internally mapping them on demand.
|
||||
However, this also requires setting up a callback as above
|
||||
to address policy reloads.
|
||||
|
||||
.BR avc_entry_ref_init ()
|
||||
initializes an
|
||||
.B avc_entry_ref
|
||||
|
@ -146,11 +176,16 @@ Make sure that userspace object managers are granted appropriate access to
|
|||
netlink by the policy.
|
||||
.
|
||||
.SH "AUTHOR"
|
||||
Eamon Walsh <ewalsh@tycho.nsa.gov>
|
||||
Originally Eamon Walsh. Updated by Stephen Smalley <sds@tycho.nsa.gov>
|
||||
.
|
||||
.SH "SEE ALSO"
|
||||
.ad l
|
||||
.nh
|
||||
.BR selinux_check_access(3),
|
||||
.BR string_to_security_class(3),
|
||||
.BR string_to_av_perm(3),
|
||||
.BR selinux_set_callback(3),
|
||||
.BR selinux_set_mapping(3),
|
||||
.BR avc_init (3),
|
||||
.BR avc_context_to_sid (3),
|
||||
.BR avc_cache_stats (3),
|
||||
|
|
|
@ -117,6 +117,8 @@ argument, which does not return under normal conditions. The
|
|||
callback should cancel the running thread referenced by
|
||||
.IR thread .
|
||||
By default, threading is not used; see
|
||||
.B KERNEL STATUS PAGE
|
||||
and
|
||||
.B NETLINK NOTIFICATION
|
||||
below.
|
||||
|
||||
|
@ -153,14 +155,49 @@ callback should destroy
|
|||
.IR lock ,
|
||||
freeing any resources associated with it. The default behavior is not to perform any locking. Note that undefined behavior may result if threading is used without appropriate locking.
|
||||
.
|
||||
.SH "NETLINK NOTIFICATION"
|
||||
Beginning with version 2.6.4, the Linux kernel supports SELinux status change notification via netlink. Two message types are currently implemented, indicating changes to the enforcing mode and to the loaded policy in the kernel, respectively. The userspace AVC listens for these messages and takes the appropriate action, modifying the behavior of
|
||||
.BR avc_has_perm (3)
|
||||
to reflect the current enforcing mode and flushing the cache on receipt of a policy load notification. Audit messages are produced when netlink notifications are processed.
|
||||
.SH "KERNEL STATUS PAGE"
|
||||
Linux kernel version 2.6.37 supports the SELinux kernel status page, enabling userspace applications to
|
||||
.BR mmap (2)
|
||||
SELinux status state in read-only mode to avoid system calls during the cache hit code path.
|
||||
|
||||
In the default single-threaded mode, the userspace AVC checks for new netlink messages at the start of each permission query. If threading and locking callbacks are passed to
|
||||
.BR avc_init ()
|
||||
however, a dedicated thread will be started to listen on the netlink socket. This may increase performance and will ensure that log messages are generated immediately rather than at the time of the next permission query.
|
||||
calls
|
||||
.BR selinux_status_open (3)
|
||||
to initialize the selinux status state. If successfully initialized, the userspace AVC will default to single-threaded mode and ignore the
|
||||
.B func_create_thread
|
||||
and
|
||||
.B func_stop_thread
|
||||
callbacks. All callbacks set via
|
||||
.BR selinux_set_callback (3)
|
||||
will still be honored.
|
||||
|
||||
.BR avc_has_perm (3)
|
||||
and
|
||||
.BR selinux_check_access (3)
|
||||
both check for status updates through calls to
|
||||
.BR selinux_status_updated (3)
|
||||
at the start of each permission query and take the appropriate action.
|
||||
|
||||
Two status types are currently implemented.
|
||||
.B setenforce
|
||||
events will change the effective enforcing state used within the AVC, and
|
||||
.B policyload
|
||||
events will result in a cache flush.
|
||||
.
|
||||
.SH "NETLINK NOTIFICATION"
|
||||
In the event that the kernel status page is not successfully
|
||||
.BR mmap (2)'ed
|
||||
the AVC will default to the netlink fallback mechanism, which opens a netlink socket for receiving status updates.
|
||||
.B setenforce
|
||||
and
|
||||
.B policyload
|
||||
events will have the same results as for the status page implementation, but all status update checks will now require a system call.
|
||||
|
||||
By default,
|
||||
.BR avc_open (3)
|
||||
does not set threading or locking callbacks. In the fallback case, the userspace AVC checks for new netlink messages at the start of each permission query. If threading and locking callbacks are passed to
|
||||
.BR avc_init (),
|
||||
a dedicated thread will be started to listen on the netlink socket. This may increase performance in the absence of the status page and will ensure that log messages are generated immediately rather than at the time of the next permission query.
|
||||
.
|
||||
.SH "RETURN VALUE"
|
||||
Functions with a return value return zero on success. On error, \-1 is returned and
|
||||
|
@ -192,5 +229,7 @@ Eamon Walsh <ewalsh@tycho.nsa.gov>
|
|||
.
|
||||
.SH "SEE ALSO"
|
||||
.BR avc_open (3),
|
||||
.BR selinux_status_open (3),
|
||||
.BR selinux_status_updated (3),
|
||||
.BR selinux_set_callback (3),
|
||||
.BR selinux (8)
|
||||
|
|
|
@ -54,6 +54,11 @@ closes the netlink socket. This function is called automatically by
|
|||
returns the netlink socket descriptor number and informs the userspace AVC
|
||||
not to check the socket descriptor automatically on calls to
|
||||
.BR avc_has_perm (3).
|
||||
If no such socket descriptor exists,
|
||||
.BR avc_netlink_acquire_fd (3)
|
||||
will first call
|
||||
.BR avc_netlink_open (3)
|
||||
and then return the resulting fd.
|
||||
|
||||
.BR avc_netlink_release_fd ()
|
||||
returns control of the netlink socket to the userspace AVC, re-enabling
|
||||
|
@ -78,6 +83,9 @@ with a return value return zero on success. On error, \-1 is returned and
|
|||
.I errno
|
||||
is set appropriately.
|
||||
.
|
||||
.SH "AUTHOR"
|
||||
Originally KaiGai Kohei. Updated by Mike Palmiotto <mike.palmiotto@crunchydata.com>
|
||||
.
|
||||
.SH "SEE ALSO"
|
||||
.BR avc_open (3),
|
||||
.BR selinux_set_callback (3),
|
||||
|
|
|
@ -26,6 +26,9 @@ initializes the userspace AVC and must be called before any other AVC operation
|
|||
destroys the userspace AVC, freeing all internal memory structures. After this call has been made,
|
||||
.BR avc_open ()
|
||||
must be called again before any AVC operations can be performed.
|
||||
.BR avc_destroy ()
|
||||
also closes the SELinux status page, which might have been opened manually by
|
||||
.BR selinux_status_open (3).
|
||||
|
||||
.BR avc_reset ()
|
||||
flushes the userspace AVC, causing it to forget any cached access decisions. The userspace AVC normally calls this function automatically when needed, see
|
||||
|
@ -46,10 +49,37 @@ include the following:
|
|||
.B AVC_OPT_SETENFORCE
|
||||
This option forces the userspace AVC into enforcing mode if the option value is non-NULL; permissive mode otherwise. The system enforcing mode will be ignored.
|
||||
.
|
||||
.SH "NETLINK NOTIFICATION"
|
||||
Beginning with version 2.6.4, the Linux kernel supports SELinux status change notification via netlink. Two message types are currently implemented, indicating changes to the enforcing mode and to the loaded policy in the kernel, respectively. The userspace AVC listens for these messages and takes the appropriate action, modifying the behavior of
|
||||
.SH "KERNEL STATUS PAGE"
|
||||
Linux kernel version 2.6.37 supports the SELinux kernel status page, enabling userspace applications to
|
||||
.BR mmap (2)
|
||||
SELinux status state in read-only mode to avoid system calls during the cache hit code path.
|
||||
|
||||
.BR avc_open ()
|
||||
calls
|
||||
.BR selinux_status_open (3)
|
||||
to initialize the selinux status state.
|
||||
|
||||
.BR avc_has_perm (3)
|
||||
to reflect the current enforcing mode and flushing the cache on receipt of a policy load notification. Audit messages are produced when netlink notifications are processed.
|
||||
and
|
||||
.BR selinux_check_access (3)
|
||||
both check for status updates through calls to
|
||||
.BR selinux_status_updated (3)
|
||||
at the start of each permission query and take the appropriate action.
|
||||
|
||||
Two status types are currently implemented.
|
||||
.B setenforce
|
||||
events will change the effective enforcing state used within the AVC, and
|
||||
.B policyload
|
||||
events will result in a cache flush.
|
||||
.
|
||||
.SH "NETLINK NOTIFICATION"
|
||||
In the event that the kernel status page is not successfully
|
||||
.BR mmap (2)'ed
|
||||
the AVC will default to the netlink fallback mechanism, which opens a netlink socket for receiving status updates.
|
||||
.B setenforce
|
||||
and
|
||||
.B policyload
|
||||
events will have the same results as for the status page implementation, but all status update checks will now require a system call.
|
||||
.
|
||||
.SH "RETURN VALUE"
|
||||
Functions with a return value return zero on success. On error, \-1 is returned and
|
||||
|
@ -61,9 +91,12 @@ Eamon Walsh <ewalsh@tycho.nsa.gov>
|
|||
.
|
||||
.SH "SEE ALSO"
|
||||
.BR selinux (8),
|
||||
.BR selinux_check_access (3),
|
||||
.BR avc_has_perm (3),
|
||||
.BR avc_context_to_sid (3),
|
||||
.BR avc_cache_stats (3),
|
||||
.BR avc_add_callback (3),
|
||||
.BR selinux_status_open (3),
|
||||
.BR selinux_status_updated (3),
|
||||
.BR selinux_set_callback (3),
|
||||
.BR security_compute_av (3)
|
||||
|
|
|
@ -7,17 +7,17 @@ get_ordered_context_list, get_ordered_context_list_with_level, get_default_conte
|
|||
.br
|
||||
.B #include <selinux/get_context_list.h>
|
||||
.sp
|
||||
.BI "int get_ordered_context_list(const char *" user ", char *" fromcon ", char ***" list );
|
||||
.BI "int get_ordered_context_list(const char *" user ", const char *" fromcon ", char ***" list );
|
||||
.sp
|
||||
.BI "int get_ordered_context_list_with_level(const char *" user ", const char *" level ", char *" fromcon ", char ***" list );
|
||||
.BI "int get_ordered_context_list_with_level(const char *" user ", const char *" level ", const char *" fromcon ", char ***" list );
|
||||
.sp
|
||||
.BI "int get_default_context(const char *" user ", char *" fromcon ", char **" newcon );
|
||||
.BI "int get_default_context(const char *" user ", const char *" fromcon ", char **" newcon );
|
||||
.sp
|
||||
.BI "int get_default_context_with_level(const char *" user ", const char *" level ", char *" fromcon ", char **" newcon );
|
||||
.BI "int get_default_context_with_level(const char *" user ", const char *" level ", const char *" fromcon ", char **" newcon );
|
||||
.sp
|
||||
.BI "int get_default_context_with_role(const char *" user ", const char *" role ", char *" fromcon ", char **" newcon ");
|
||||
.BI "int get_default_context_with_role(const char *" user ", const char *" role ", const char *" fromcon ", char **" newcon ");
|
||||
.sp
|
||||
.BI "int get_default_context_with_rolelevel(const char *" user ", const char *" role ", const char *" level ", char *" fromcon ", char **" newcon ");
|
||||
.BI "int get_default_context_with_rolelevel(const char *" user ", const char *" role ", const char *" level ", const char *" fromcon ", char **" newcon ");
|
||||
.sp
|
||||
.BI "int query_user_context(char **" list ", char **" newcon );
|
||||
.sp
|
||||
|
@ -26,14 +26,28 @@ get_ordered_context_list, get_ordered_context_list_with_level, get_default_conte
|
|||
.BI "int get_default_type(const char *" role ", char **" type );
|
||||
.
|
||||
.SH "DESCRIPTION"
|
||||
|
||||
This family of functions can be used to obtain either a prioritized list of
|
||||
all reachable security contexts for a given SELinux user or a single default
|
||||
(highest priority) context for a given SELinux user for use by login-like
|
||||
programs. These functions takes a SELinux user identity that must
|
||||
be defined in the SELinux policy as their input, not a Linux username.
|
||||
Most callers should typically first call
|
||||
.BR getseuserbyname(3)
|
||||
to look up the SELinux user identity and level for a given
|
||||
Linux username and then invoke one of
|
||||
.BR get_ordered_context_list_with_level ()
|
||||
or
|
||||
.BR get_default_context_with_level ()
|
||||
with the returned SELinux user and level as inputs.
|
||||
|
||||
.BR get_ordered_context_list ()
|
||||
invokes the
|
||||
.BR security_compute_user (3)
|
||||
function to obtain the list of contexts for the specified
|
||||
obtains the list of contexts for the specified
|
||||
SELinux
|
||||
.I user
|
||||
that are reachable from the specified
|
||||
identity that are reachable from the specified
|
||||
.I fromcon
|
||||
context. The function then orders the resulting list based on the global
|
||||
context based on the global
|
||||
.I \%/etc/selinux/{SELINUXTYPE}/contexts/default_contexts
|
||||
file and the per-user
|
||||
.I \%/etc/selinux/{SELINUXTYPE}/contexts/users/<username>
|
||||
|
|
|
@ -7,7 +7,7 @@ freecon, freeconary \- free memory associated with SELinux security contexts
|
|||
getpeercon \- get security context of a peer socket
|
||||
|
||||
setcon \- set current security context of a process
|
||||
.
|
||||
|
||||
.SH "SYNOPSIS"
|
||||
.B #include <selinux/selinux.h>
|
||||
.sp
|
||||
|
@ -31,30 +31,39 @@ setcon \- set current security context of a process
|
|||
.sp
|
||||
.BI "void freeconary(char **" con );
|
||||
.sp
|
||||
.BI "int setcon(char *" context );
|
||||
.BI "int setcon(const char *" context );
|
||||
.sp
|
||||
.BI "int setcon_raw(char *" context );
|
||||
.
|
||||
.BI "int setcon_raw(const char *" context );
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
.TP
|
||||
.BR getcon ()
|
||||
retrieves the context of the current process, which must be free'd with
|
||||
freecon.
|
||||
.BR freecon ().
|
||||
|
||||
.TP
|
||||
.BR getprevcon ()
|
||||
same as getcon but gets the context before the last exec.
|
||||
|
||||
.TP
|
||||
.BR getpidcon ()
|
||||
returns the process context for the specified PID.
|
||||
|
||||
.BR getpeercon ()
|
||||
retrieves context of peer socket, and set
|
||||
.BI * context
|
||||
to refer to it, which must be free'd with
|
||||
returns the process context for the specified PID, which must be free'd with
|
||||
.BR freecon ().
|
||||
|
||||
.TP
|
||||
.BR getpeercon ()
|
||||
retrieves the context of the peer socket, which must be free'd with
|
||||
.BR freecon ().
|
||||
|
||||
.TP
|
||||
.BR freecon ()
|
||||
frees the memory allocated for a security context.
|
||||
|
||||
If
|
||||
.I con
|
||||
is NULL, no operation is performed.
|
||||
|
||||
.TP
|
||||
.BR freeconary ()
|
||||
frees the memory allocated for a context array.
|
||||
|
||||
|
@ -62,6 +71,7 @@ If
|
|||
.I con
|
||||
is NULL, no operation is performed.
|
||||
|
||||
.TP
|
||||
.BR setcon ()
|
||||
sets the current security context of the process to a new value. Note
|
||||
that use of this function requires that the entire application be
|
||||
|
@ -110,6 +120,8 @@ context and the
|
|||
.BR setcon ()
|
||||
will fail if it is not allowed by policy.
|
||||
|
||||
.TP
|
||||
.BR *_raw()
|
||||
.BR getcon_raw (),
|
||||
.BR getprevcon_raw (),
|
||||
.BR getpidcon_raw (),
|
||||
|
@ -118,9 +130,14 @@ and
|
|||
.BR setcon_raw ()
|
||||
behave identically to their non-raw counterparts but do not perform context
|
||||
translation.
|
||||
.
|
||||
|
||||
.SH "RETURN VALUE"
|
||||
On error \-1 is returned. On success 0 is returned.
|
||||
.
|
||||
On error \-1 is returned with errno set. On success 0 is returned.
|
||||
|
||||
.SH "NOTES"
|
||||
The retrieval functions might return success and set
|
||||
.I *context
|
||||
to NULL if and only if SELinux is not enabled.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR selinux "(8), " setexeccon "(3)"
|
||||
|
|
|
@ -33,7 +33,9 @@ is identical to
|
|||
.BR getfilecon (),
|
||||
only the open file pointed to by filedes (as returned by
|
||||
.BR open (2))
|
||||
is interrogated in place of path.
|
||||
is interrogated in place of path. Since libselinux 3.4 a file opened via
|
||||
.I O_PATH
|
||||
is supported.
|
||||
|
||||
.BR getfilecon_raw (),
|
||||
.BR lgetfilecon_raw ()
|
||||
|
|
|
@ -15,7 +15,6 @@ is_selinux_mls_enabled \- check whether SELinux is enabled for (Multi Level Secu
|
|||
.SH "DESCRIPTION"
|
||||
.BR is_selinux_enabled ()
|
||||
returns 1 if SELinux is running or 0 if it is not.
|
||||
On error, \-1 is returned.
|
||||
|
||||
.BR is_selinux_mls_enabled ()
|
||||
returns 1 if SELinux is capable of running in MLS mode or 0 if it is not. To
|
||||
|
|
|
@ -5,9 +5,9 @@ security_check_context \- check the validity of a SELinux context
|
|||
.SH "SYNOPSIS"
|
||||
.B #include <selinux/selinux.h>
|
||||
.sp
|
||||
.BI "int security_check_context(char *" con );
|
||||
.BI "int security_check_context(const char *" con );
|
||||
.sp
|
||||
.BI "int security_check_context_raw(char *" con );
|
||||
.BI "int security_check_context_raw(const char *" con );
|
||||
.
|
||||
.SH "DESCRIPTION"
|
||||
.BR security_check_context ()
|
||||
|
|
|
@ -50,6 +50,39 @@ the SELinux policy database in the kernel
|
|||
.BI "int checkPasswdAccess(access_vector_t " requested );
|
||||
.
|
||||
.SH "DESCRIPTION"
|
||||
|
||||
This family of functions is used to obtain policy decisions from the
|
||||
SELinux kernel security server (policy engine). In general, direct use of
|
||||
.BR security_compute_av ()
|
||||
and its variant interfaces is discouraged in favor of using
|
||||
.BR selinux_check_access ()
|
||||
since the latter automatically handles the dynamic mapping of class
|
||||
and permission names to their policy values, initialization and use of
|
||||
the Access Vector Cache (AVC), and proper handling of per-domain and
|
||||
global permissive mode and allow_unknown.
|
||||
|
||||
When using any of the functions that take policy integer values for
|
||||
classes or permissions as inputs, use
|
||||
.BR string_to_security_class(3)
|
||||
and
|
||||
.BR string_to_av_perm(3)
|
||||
to map the class and permission names to their policy values.
|
||||
These values may change across a policy reload, so they should be
|
||||
re-acquired on every use or using a
|
||||
.B SELINUX_CB_POLICYLOAD
|
||||
callback set via
|
||||
.BR selinux_set_callback(3).
|
||||
|
||||
An alternative approach is to use
|
||||
.BR selinux_set_mapping(3)
|
||||
to create a mapping from class and permission index values
|
||||
used by the application to the policy values,
|
||||
thereby allowing the application to pass its own
|
||||
fixed constants for the classes and permissions to
|
||||
these functions and internally mapping them on demand.
|
||||
However, this also requires setting up a callback as above
|
||||
to address policy reloads.
|
||||
|
||||
.BR security_compute_av ()
|
||||
queries whether the policy permits the source context
|
||||
.I scon
|
||||
|
@ -101,8 +134,9 @@ instance.
|
|||
|
||||
.BR security_compute_user ()
|
||||
is used to determine the set of user contexts that can be reached from a
|
||||
source context. It is mainly used by
|
||||
.BR get_ordered_context_list ().
|
||||
source context. This function is deprecated; use
|
||||
.BR get_ordered_context_list (3)
|
||||
instead.
|
||||
|
||||
.BR security_validatetrans ()
|
||||
is used to determine if a transition from scon to newcon using tcon as the object
|
||||
|
@ -135,7 +169,9 @@ is used to check for a permission in the
|
|||
.I passwd
|
||||
class.
|
||||
.BR selinux_check_passwd_access ()
|
||||
uses getprevcon() for the source and target security contexts.
|
||||
uses
|
||||
.BR getprevcon(3)
|
||||
for the source and target security contexts.
|
||||
|
||||
.BR checkPasswdAccess ()
|
||||
is a deprecated alias of the
|
||||
|
@ -146,4 +182,10 @@ function.
|
|||
Returns zero on success or \-1 on error.
|
||||
.
|
||||
.SH "SEE ALSO"
|
||||
.BR selinux "(8), " getcon "(3), " getfilecon "(3), " get_ordered_context_list "(3)"
|
||||
.BR string_to_security_class (3),
|
||||
.BR string_to_av_perm (3),
|
||||
.BR selinux_set_callback (3),
|
||||
.BR selinux_set_mapping (3),
|
||||
.BR getprevcon (3),
|
||||
.BR get_ordered_context_list (3),
|
||||
.BR selinux (8)
|
||||
|
|
|
@ -10,7 +10,7 @@ selabel_open, selabel_close \- userspace SELinux labeling interface
|
|||
.br
|
||||
.B #include <selinux/label.h>
|
||||
.sp
|
||||
.BI "struct selabel_handle *selabel_open(int " backend ,
|
||||
.BI "struct selabel_handle *selabel_open(unsigned int " backend ,
|
||||
.in +\w'struct selabel_handle *selabel_open('u
|
||||
.BI "const struct selinux_opt *" options ,
|
||||
.br
|
||||
|
|
|
@ -11,6 +11,14 @@ selinux_restorecon \- restore file(s) default SELinux security contexts
|
|||
.br
|
||||
.BI "unsigned int " restorecon_flags ");"
|
||||
.in
|
||||
.sp
|
||||
.BI "int selinux_restorecon_parallel(const char *" pathname ,
|
||||
.in +\w'int selinux_restorecon_parallel('u
|
||||
.br
|
||||
.BI "unsigned int " restorecon_flags ","
|
||||
.br
|
||||
.BI "size_t " nthreads ");"
|
||||
.in
|
||||
.
|
||||
.SH "DESCRIPTION"
|
||||
.BR selinux_restorecon ()
|
||||
|
@ -70,7 +78,10 @@ specfile entries SHA1 digest. The specfile entries digest will be written to the
|
|||
.IR security.sehash
|
||||
extended attribute once relabeling has been completed successfully provided the
|
||||
.B SELINUX_RESTORECON_NOCHANGE
|
||||
flag has not been set.
|
||||
flag has not been set, and no errors have been skipped during the file tree walk
|
||||
due to the
|
||||
.B SELINUX_RESTORECON_COUNT_ERRORS
|
||||
flag.
|
||||
.sp
|
||||
.B SELINUX_RESTORECON_NOCHANGE
|
||||
don't change any file labels (passive check) or update the digest in the
|
||||
|
@ -152,6 +163,25 @@ Setting
|
|||
.B SELINUX_RESTORECON_IGNORE_MOUNTS
|
||||
is useful where there is a non-seclabel fs mounted with a seclabel fs mounted
|
||||
on a directory below this.
|
||||
.sp
|
||||
.B SELINUX_RESTORECON_CONFLICT_ERROR
|
||||
to treat conflicting specifications, such as where two hardlinks for the
|
||||
same inode have different contexts, as errors.
|
||||
.sp
|
||||
.B SELINUX_RESTORECON_COUNT_ERRORS
|
||||
Count, but otherwise ignore, errors during the file tree walk. Only makes a
|
||||
difference if the
|
||||
.B SELINUX_RESTORECON_ABORT_ON_ERROR
|
||||
flag is clear. Call
|
||||
.BR selinux_restorecon_get_skipped_errors (3)
|
||||
for fetching the ignored (skipped) error count after
|
||||
.BR selinux_restorecon (3)
|
||||
or
|
||||
.BR selinux_restorecon_parallel (3)
|
||||
completes with success. In case any errors were skipped during the file tree
|
||||
walk, the specfile entries SHA1 digest will not have been written to the
|
||||
.IR security.sehash
|
||||
extended attribute.
|
||||
.RE
|
||||
.sp
|
||||
The behavior regarding the checking and updating of the SHA1 digest described
|
||||
|
@ -183,6 +213,27 @@ unless the
|
|||
.B SELINUX_RESTORECON_IGNORE_MOUNTS
|
||||
flag has been set.
|
||||
.RE
|
||||
.sp
|
||||
.BR selinux_restorecon_parallel()
|
||||
is similar to
|
||||
.BR selinux_restorecon (3),
|
||||
but accepts another parameter that allows to run relabeling over multiple
|
||||
threads:
|
||||
.sp
|
||||
.RS
|
||||
.IR nthreads
|
||||
specifies the number of threads to use during relabeling. When set to 1,
|
||||
the behavior is the same as calling
|
||||
.BR selinux_restorecon (3).
|
||||
When set to 0, the function will try to use as many threads as there are
|
||||
online CPU cores. When set to any other number, the function will try to use
|
||||
the given number of threads.
|
||||
.sp
|
||||
Note that to use the parallel relabeling capability, the calling process
|
||||
must be linked with the
|
||||
.B libpthread
|
||||
library (either at compile time or dynamically at run time). Otherwise the
|
||||
function will print a warning and fall back to the single threaded mode.
|
||||
.
|
||||
.SH "RETURN VALUE"
|
||||
On success, zero is returned. On error, \-1 is returned and
|
||||
|
@ -246,6 +297,8 @@ option.
|
|||
.br
|
||||
.BR selinux_restorecon_default_handle (3),
|
||||
.br
|
||||
.BR selinux_restorecon_get_skipped_errors (3),
|
||||
.br
|
||||
.BR selinux_restorecon_set_exclude_list (3),
|
||||
.br
|
||||
.BR selinux_restorecon_set_alt_rootpath (3),
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
.TH "selinux_restorecon_get_skipped_errors" "3" "27 Apr 2022" "Security Enhanced Linux" "SELinux API documentation"
|
||||
|
||||
.SH "NAME"
|
||||
selinux_restorecon_get_skipped_errors \- get the number of errors ignored by
|
||||
.BR selinux_restorecon (3)
|
||||
or
|
||||
.BR selinux_restorecon_parallel (3)
|
||||
during the file tree walk
|
||||
.
|
||||
.SH "SYNOPSIS"
|
||||
.B #include <selinux/restorecon.h>
|
||||
.sp
|
||||
.BI "long unsigned selinux_restorecon_get_skipped_errors(void);"
|
||||
.in +\w'long unsigned selinux_restorecon_get_skipped_errors('u
|
||||
.
|
||||
.SH "DESCRIPTION"
|
||||
If
|
||||
.B SELINUX_RESTORECON_COUNT_ERRORS
|
||||
was passed to
|
||||
.BR selinux_restorecon (3)
|
||||
or
|
||||
.BR selinux_restorecon_parallel (3)
|
||||
and that function returned successfully (i.e., with a zero return value), then
|
||||
.BR selinux_restorecon_get_skipped_errors ()
|
||||
returns the number of errors ignored during the file tree walk.
|
||||
.
|
||||
.SH "SEE ALSO"
|
||||
.BR selinux_restorecon (3)
|
|
@ -0,0 +1 @@
|
|||
.so man3/selinux_restorecon.3
|
|
@ -46,6 +46,20 @@ argument indicates the type of message and will be set to one of the following:
|
|||
.B SELINUX_INFO
|
||||
|
||||
.B SELINUX_AVC
|
||||
|
||||
.B SELINUX_POLICYLOAD
|
||||
|
||||
.B SELINUX_SETENFORCE
|
||||
|
||||
SELINUX_ERROR, SELINUX_WARNING, and SELINUX_INFO indicate standard log severity
|
||||
levels and are not auditable messages.
|
||||
|
||||
The SELINUX_AVC, SELINUX_POLICYLOAD, and SELINUX_SETENFORCE message types can be
|
||||
audited with AUDIT_USER_AVC, AUDIT_USER_MAC_POLICY_LOAD, and AUDIT_USER_MAC_STATUS
|
||||
values from libaudit, respectively. If they are not audited, SELINUX_AVC should be
|
||||
considered equivalent to SELINUX_ERROR; similarly, SELINUX_POLICYLOAD and
|
||||
SELINUX_SETENFORCE should be considered equivalent to SELINUX_INFO.
|
||||
|
||||
.
|
||||
.TP
|
||||
.B SELINUX_CB_AUDIT
|
||||
|
|
|
@ -19,7 +19,19 @@ struct security_class_mapping {
|
|||
.
|
||||
.SH "DESCRIPTION"
|
||||
.BR selinux_set_mapping ()
|
||||
establishes a mapping from a user-provided ordering of object classes and permissions to the numbers actually used by the loaded system policy. Use of this function is highly preferred over the generated constants in the libselinux header files, as this method allows the policy's class and permission values to change over time.
|
||||
establishes a mapping from a user-provided ordering of object classes and permissions to the numbers actually used by the loaded system policy. If using this function, applications should also set a
|
||||
.B SELINUX_CB_POLICYLOAD
|
||||
callback via
|
||||
.BR selinux_set_callback(3)
|
||||
that calls this function again upon a policy reload to re-create the mapping
|
||||
in case the class or permission values change in the new policy.
|
||||
Generally it is preferred to instead use
|
||||
.BR selinux_check_access(3)
|
||||
instead of
|
||||
.BR avc_has_perm(3)
|
||||
or
|
||||
.BR security_compute_av(3)
|
||||
and not use this function at all.
|
||||
|
||||
After the mapping is established, all libselinux functions that operate on class and permission values take the user-provided numbers, which are determined as follows:
|
||||
|
||||
|
@ -81,8 +93,10 @@ and
|
|||
class) will be identified by 1, 2, 4, and 8 respectively. Classes and permissions not listed in the mapping cannot be used.
|
||||
.
|
||||
.SH "AUTHOR"
|
||||
Eamon Walsh <ewalsh@tycho.nsa.gov>
|
||||
Originally Eamon Walsh. Updated by Stephen Smalley <sds@tycho.nsa.gov>
|
||||
.
|
||||
.SH "SEE ALSO"
|
||||
.BR avc_open (8),
|
||||
.BR selinux_check_access (3),
|
||||
.BR selinux_set_callback (3),
|
||||
.BR avc_has_perm (3),
|
||||
.BR selinux (8)
|
||||
|
|
|
@ -48,7 +48,7 @@ Set 1 on the
|
|||
argument to handle a case of older kernels without kernel status page support.
|
||||
In this case, this function tries to open a netlink socket using
|
||||
.BR avc_netlink_open (3)
|
||||
and overwrite corresponding callbacks ( setenforce and policyload).
|
||||
and overwrite corresponding callbacks (setenforce and policyload).
|
||||
Thus, we need to pay attention to the interaction with these interfaces,
|
||||
when fallback mode is enabled.
|
||||
.sp
|
||||
|
@ -57,9 +57,14 @@ unmap the kernel status page and close its file descriptor, or close the
|
|||
netlink socket if fallbacked.
|
||||
.sp
|
||||
.BR selinux_status_updated ()
|
||||
informs us whether something has been updated since the last call.
|
||||
It returns 0 if nothing was happened, however, 1 if something has been
|
||||
updated in this duration, or \-1 on error.
|
||||
processes status update events. There are two kinds of status updates.
|
||||
.B setenforce
|
||||
events will change the effective enforcing state used within the AVC, and
|
||||
.B policyload
|
||||
events will result in a cache flush.
|
||||
|
||||
This function returns 0 if there have been no updates since the last call,
|
||||
1 if there have been updates since the last call, or \-1 on error.
|
||||
.sp
|
||||
.BR selinux_status_getenforce ()
|
||||
returns 0 if SELinux is running in permissive mode, 1 if enforcing mode,
|
||||
|
|
|
@ -5,17 +5,17 @@ setfilecon, fsetfilecon, lsetfilecon \- set SELinux security context of a file
|
|||
.SH "SYNOPSIS"
|
||||
.B #include <selinux/selinux.h>
|
||||
.sp
|
||||
.BI "int setfilecon(const char *" path ", char *" con );
|
||||
.BI "int setfilecon(const char *" path ", const char *" con );
|
||||
.sp
|
||||
.BI "int setfilecon_raw(const char *" path ", char *" con );
|
||||
.BI "int setfilecon_raw(const char *" path ", const char *" con );
|
||||
.sp
|
||||
.BI "int lsetfilecon(const char *" path ", char *" con );
|
||||
.BI "int lsetfilecon(const char *" path ", const char *" con );
|
||||
.sp
|
||||
.BI "int lsetfilecon_raw(const char *" path ", char *" con );
|
||||
.BI "int lsetfilecon_raw(const char *" path ", const char *" con );
|
||||
.sp
|
||||
.BI "int fsetfilecon(int "fd ", char *" con );
|
||||
.BI "int fsetfilecon(int "fd ", const char *" con );
|
||||
.sp
|
||||
.BI "int fsetfilecon_raw(int "fd ", char *" con );
|
||||
.BI "int fsetfilecon_raw(int "fd ", const char *" con );
|
||||
.
|
||||
.SH "DESCRIPTION"
|
||||
.BR setfilecon ()
|
||||
|
@ -29,7 +29,9 @@ link itself has it's context set, not the file that it refers to.
|
|||
is identical to setfilecon, only the open file pointed to by filedes (as
|
||||
returned by
|
||||
.BR open (2))
|
||||
has it's context set in place of path.
|
||||
has it's context set in place of path. Since libselinux 3.4 a file opened via
|
||||
.I O_PATH
|
||||
is supported.
|
||||
|
||||
.BR setfilecon_raw (),
|
||||
.BR lsetfilecon_raw (),
|
||||
|
|
|
@ -125,7 +125,14 @@ Where:
|
|||
.RS
|
||||
.I pathname
|
||||
.RS
|
||||
An entry that defines the pathname that may be in the form of a regular expression.
|
||||
An entry that defines the path to be labeled.
|
||||
May contain either a fully qualified path,
|
||||
or a Perl compatible regular expression (PCRE),
|
||||
describing fully qualified path(s).
|
||||
The only PCRE flag in use is PCRE2_DOTALL,
|
||||
which causes a wildcard '.' to match anything, including a new line.
|
||||
Strings representing paths are processed as bytes (as opposed to Unicode),
|
||||
meaning that non-ASCII characters are not matched by a single wildcard.
|
||||
.RE
|
||||
.I file_type
|
||||
.RS
|
||||
|
|
|
@ -19,18 +19,36 @@ enabled or disabled, and if enabled, whether SELinux operates in
|
|||
permissive mode or enforcing mode. The
|
||||
.B SELINUX
|
||||
variable may be set to
|
||||
any one of disabled, permissive, or enforcing to select one of these
|
||||
options. The disabled option completely disables the SELinux kernel
|
||||
and application code, leaving the system running without any SELinux
|
||||
protection. The permissive option enables the SELinux code, but
|
||||
causes it to operate in a mode where accesses that would be denied by
|
||||
policy are permitted but audited. The enforcing option enables the
|
||||
SELinux code and causes it to enforce access denials as well as
|
||||
auditing them. Permissive mode may yield a different set of denials
|
||||
than enforcing mode, both because enforcing mode will prevent an
|
||||
operation from proceeding past the first denial and because some
|
||||
application code will fall back to a less privileged mode of operation
|
||||
if denied access.
|
||||
any one of \fIdisabled\fR, \fIpermissive\fR, or \fIenforcing\fR to
|
||||
select one of these options. The \fIdisabled\fR disables most of the
|
||||
SELinux kernel and application code, leaving the system
|
||||
running without any SELinux protection. The \fIpermissive\fR option
|
||||
enables the SELinux code, but causes it to operate in a mode where
|
||||
accesses that would be denied by policy are permitted but audited. The
|
||||
\fIenforcing\fR option enables the SELinux code and causes it to enforce
|
||||
access denials as well as auditing them. \fIpermissive\fR mode may
|
||||
yield a different set of denials than enforcing mode, both because
|
||||
enforcing mode will prevent an operation from proceeding past the first
|
||||
denial and because some application code will fall back to a less
|
||||
privileged mode of operation if denied access.
|
||||
|
||||
.B NOTE:
|
||||
Disabling SELinux by setting
|
||||
.B SELINUX=disabled
|
||||
in
|
||||
.I /etc/selinux/config
|
||||
is deprecated and depending on kernel version and configuration it might
|
||||
not lead to SELinux being completely disabled. Specifically, the
|
||||
SELinux hooks will still be executed internally, but the SELinux policy
|
||||
will not be loaded and no operation will be denied. In such state, the
|
||||
system will act as if SELinux was disabled, although some operations
|
||||
might behave slightly differently. To properly disable SELinux, it is
|
||||
recommended to use the
|
||||
.B selinux=0
|
||||
kernel boot option instead. In that case SELinux will be disabled
|
||||
regardless of what is set in the
|
||||
.I /etc/selinux/config
|
||||
file.
|
||||
|
||||
The
|
||||
.I /etc/selinux/config
|
||||
|
@ -76,6 +94,13 @@ and reboot.
|
|||
also has this capability. The
|
||||
.BR restorecon / fixfiles
|
||||
commands are also available for relabeling files.
|
||||
|
||||
Please note that using mount flag
|
||||
.I nosuid
|
||||
also disables SELinux domain transitions, unless permission
|
||||
.I nosuid_transition
|
||||
is used in the policy to allow this, which in turn needs also policy capability
|
||||
.IR nnp_nosuid_transition .
|
||||
.
|
||||
.SH AUTHOR
|
||||
This manual page was written by Dan Walsh <dwalsh@redhat.com>.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.TH "failsafe_context" "5" "28 ноября 2011" "Security Enhanced Linux" "Конфигурация SELinux"
|
||||
.SH "ИМЯ"
|
||||
failsafe_context \- файл конфигурации надёжного контекста SELinux
|
||||
failsafe_context \- файл конфигурации резервного контекста SELinux
|
||||
.
|
||||
.SH "ОПИСАНИЕ"
|
||||
Файл
|
||||
|
@ -10,7 +10,7 @@ failsafe_context \- файл конфигурации надёжного кон
|
|||
получать известный действительный контекст входа для администратора, если в других расположениях отсутствуют действительные записи по умолчанию.
|
||||
.sp
|
||||
.BR selinux_failsafe_context_path "(3) "
|
||||
возвращает путь активной политики к этому файлу. Файл надёжного контекста по умолчанию:
|
||||
возвращает путь активной политики к этому файлу. Файл резервного контекста по умолчанию:
|
||||
.RS
|
||||
.I /etc/selinux/{SELINUXTYPE}/contexts/failsafe_context
|
||||
.RE
|
||||
|
|
22
src/Makefile
22
src/Makefile
|
@ -15,7 +15,7 @@ INCLUDEDIR ?= $(PREFIX)/include
|
|||
PYINC ?= $(shell $(PKG_CONFIG) --cflags $(PYPREFIX))
|
||||
PYLIBS ?= $(shell $(PKG_CONFIG) --libs $(PYPREFIX))
|
||||
PYTHONLIBDIR ?= $(shell $(PYTHON) -c "from distutils.sysconfig import *; print(get_python_lib(plat_specific=1, prefix='$(PREFIX)'))")
|
||||
PYCEXT ?= $(shell $(PYTHON) -c 'import imp;print([s for s,m,t in imp.get_suffixes() if t == imp.C_EXTENSION][0])')
|
||||
PYCEXT ?= $(shell $(PYTHON) -c 'import importlib.machinery;print(importlib.machinery.EXTENSION_SUFFIXES[0])')
|
||||
RUBYINC ?= $(shell $(RUBY) -e 'puts "-I" + RbConfig::CONFIG["rubyarchhdrdir"] + " -I" + RbConfig::CONFIG["rubyhdrdir"]')
|
||||
RUBYLIBS ?= $(shell $(RUBY) -e 'puts "-L" + RbConfig::CONFIG["libdir"] + " -L" + RbConfig::CONFIG["archlibdir"] + " " + RbConfig::CONFIG["LIBRUBYARG_SHARED"]')
|
||||
RUBYINSTALL ?= $(shell $(RUBY) -e 'puts RbConfig::CONFIG["vendorarchdir"]')
|
||||
|
@ -65,7 +65,7 @@ EXTRA_CFLAGS = -fipa-pure-const -Wlogical-op -Wpacked-bitfield-compat -Wsync-nan
|
|||
-Wcoverage-mismatch -Wcpp -Wformat-contains-nul -Wnormalized=nfc -Wsuggest-attribute=const \
|
||||
-Wsuggest-attribute=noreturn -Wsuggest-attribute=pure -Wtrampolines -Wjump-misses-init \
|
||||
-Wno-suggest-attribute=pure -Wno-suggest-attribute=const -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 \
|
||||
-Wstrict-overflow=5
|
||||
-Wstrict-overflow=5 -fno-semantic-interposition
|
||||
else
|
||||
EXTRA_CFLAGS = -Wunused-command-line-argument
|
||||
endif
|
||||
|
@ -90,7 +90,7 @@ CFLAGS ?= -O -Wall -W -Wundef -Wformat-y2k -Wformat-security -Winit-self -Wmissi
|
|||
-Werror -Wno-aggregate-return -Wno-redundant-decls \
|
||||
$(EXTRA_CFLAGS)
|
||||
|
||||
LD_SONAME_FLAGS=-soname,$(LIBSO),-z,defs,-z,relro
|
||||
LD_SONAME_FLAGS=-soname,$(LIBSO),--version-script=libselinux.map,-z,defs,-z,relro
|
||||
|
||||
ifeq ($(OS), Darwin)
|
||||
override CFLAGS += -I/opt/local/include
|
||||
|
@ -98,14 +98,14 @@ override LDFLAGS += -L/opt/local/lib -undefined dynamic_lookup
|
|||
LD_SONAME_FLAGS=-install_name,$(LIBSO)
|
||||
endif
|
||||
|
||||
PCRE_LDLIBS ?= -lpcre
|
||||
# override with -lfts when building on Musl libc to use fts-standalone
|
||||
FTS_LDLIBS ?=
|
||||
|
||||
override CFLAGS += -I../include -D_GNU_SOURCE $(DISABLE_FLAGS) $(PCRE_CFLAGS)
|
||||
|
||||
SWIG_CFLAGS += -Wno-error -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unused-parameter \
|
||||
-Wno-shadow -Wno-uninitialized -Wno-missing-prototypes -Wno-missing-declarations
|
||||
-Wno-shadow -Wno-uninitialized -Wno-missing-prototypes -Wno-missing-declarations \
|
||||
-Wno-deprecated-declarations
|
||||
|
||||
RANLIB ?= ranlib
|
||||
|
||||
|
@ -121,8 +121,16 @@ SRCS= callbacks.c freecon.c label.c label_file.c \
|
|||
label_backends_android.c regex.c label_support.c \
|
||||
matchpathcon.c setrans_client.c sha1.c booleans.c
|
||||
else
|
||||
DISABLE_FLAGS+= -DNO_ANDROID_BACKEND
|
||||
LABEL_BACKEND_ANDROID=y
|
||||
endif
|
||||
|
||||
ifneq ($(LABEL_BACKEND_ANDROIDT),y)
|
||||
SRCS:= $(filter-out label_backends_android.c, $(SRCS))
|
||||
DISABLE_FLAGS+= -DNO_ANDROID_BACKEND
|
||||
endif
|
||||
|
||||
ifeq ($(DISABLE_X11),y)
|
||||
SRCS:= $(filter-out label_x.c, $(SRCS))
|
||||
endif
|
||||
|
||||
SWIGRUBY = swig -Wall -ruby -o $(SWIGRUBYCOUT) -outdir ./ $(DISABLE_FLAGS)
|
||||
|
@ -173,7 +181,7 @@ install: all
|
|||
ln -sf --relative $(DESTDIR)$(SHLIBDIR)/$(LIBSO) $(DESTDIR)$(LIBDIR)/$(TARGET)
|
||||
|
||||
install-pywrap: pywrap
|
||||
$(PYTHON) setup.py install --prefix=$(PREFIX) `test -n "$(DESTDIR)" && echo --root $(DESTDIR)` --install-layout=deb
|
||||
$(PYTHON) setup.py install --prefix=$(PREFIX) `test -n "$(DESTDIR)" && echo --root $(DESTDIR)` $(PYTHON_SETUP_ARGS)
|
||||
install -m 644 $(SWIGPYOUT) $(DESTDIR)$(PYTHONLIBDIR)/selinux/__init__.py
|
||||
ln -sf --relative $(DESTDIR)$(PYTHONLIBDIR)/selinux/_selinux$(PYCEXT) $(DESTDIR)$(PYTHONLIBDIR)/_selinux$(PYCEXT)
|
||||
|
||||
|
|
|
@ -204,8 +204,8 @@ static int __policy_init(const char *init_path)
|
|||
fp = fopen(path, "re");
|
||||
if (!fp) {
|
||||
snprintf(errormsg, sizeof(errormsg),
|
||||
"unable to open %s: %s\n",
|
||||
path, strerror(errno));
|
||||
"unable to open %s: %m\n",
|
||||
path);
|
||||
PyErr_SetString( PyExc_ValueError, errormsg);
|
||||
return 1;
|
||||
}
|
||||
|
@ -221,9 +221,8 @@ static int __policy_init(const char *init_path)
|
|||
fp = fopen(curpolicy, "re");
|
||||
if (!fp) {
|
||||
snprintf(errormsg, sizeof(errormsg),
|
||||
"unable to open %s: %s\n",
|
||||
curpolicy,
|
||||
strerror(errno));
|
||||
"unable to open %s: %m\n",
|
||||
curpolicy);
|
||||
PyErr_SetString( PyExc_ValueError, errormsg);
|
||||
return 1;
|
||||
}
|
||||
|
@ -242,7 +241,7 @@ static int __policy_init(const char *init_path)
|
|||
if (sepol_policy_file_create(&pf) ||
|
||||
sepol_policydb_create(&avc->policydb)) {
|
||||
snprintf(errormsg, sizeof(errormsg),
|
||||
"policydb_init failed: %s\n", strerror(errno));
|
||||
"policydb_init failed: %m\n");
|
||||
PyErr_SetString( PyExc_RuntimeError, errormsg);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
|
@ -275,7 +274,7 @@ static int __policy_init(const char *init_path)
|
|||
}
|
||||
|
||||
sepol_bool_iterate(avc->handle, avc->policydb,
|
||||
load_booleans, (void *)NULL);
|
||||
load_booleans, NULL);
|
||||
|
||||
/* Initialize the sidtab for subsequent use by sepol_context_to_sid
|
||||
and sepol_compute_av_reason. */
|
||||
|
|
68
src/avc.c
68
src/avc.c
|
@ -50,7 +50,6 @@ struct avc_callback_node {
|
|||
struct avc_callback_node *next;
|
||||
};
|
||||
|
||||
static void *avc_netlink_thread = NULL;
|
||||
static void *avc_lock = NULL;
|
||||
static void *avc_log_lock = NULL;
|
||||
static struct avc_node *avc_node_freelist = NULL;
|
||||
|
@ -145,22 +144,7 @@ int avc_get_initial_sid(const char * name, security_id_t * sid)
|
|||
return rc;
|
||||
}
|
||||
|
||||
int avc_open(struct selinux_opt *opts, unsigned nopts)
|
||||
{
|
||||
avc_setenforce = 0;
|
||||
|
||||
while (nopts--)
|
||||
switch(opts[nopts].type) {
|
||||
case AVC_OPT_SETENFORCE:
|
||||
avc_setenforce = 1;
|
||||
avc_enforcing = !!opts[nopts].value;
|
||||
break;
|
||||
}
|
||||
|
||||
return avc_init("avc", NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
int avc_init(const char *prefix,
|
||||
static int avc_init_internal(const char *prefix,
|
||||
const struct avc_memory_callback *mem_cb,
|
||||
const struct avc_log_callback *log_cb,
|
||||
const struct avc_thread_callback *thread_cb,
|
||||
|
@ -222,30 +206,49 @@ int avc_init(const char *prefix,
|
|||
rc = security_getenforce();
|
||||
if (rc < 0) {
|
||||
avc_log(SELINUX_ERROR,
|
||||
"%s: could not determine enforcing mode: %s\n",
|
||||
avc_prefix,
|
||||
strerror(errno));
|
||||
"%s: could not determine enforcing mode: %m\n",
|
||||
avc_prefix);
|
||||
goto out;
|
||||
}
|
||||
avc_enforcing = rc;
|
||||
}
|
||||
|
||||
rc = avc_netlink_open(0);
|
||||
rc = selinux_status_open(0);
|
||||
if (rc < 0) {
|
||||
avc_log(SELINUX_ERROR,
|
||||
"%s: can't open netlink socket: %d (%s)\n",
|
||||
avc_prefix, errno, strerror(errno));
|
||||
"%s: could not open selinux status page: %d (%m)\n",
|
||||
avc_prefix, errno);
|
||||
goto out;
|
||||
}
|
||||
if (avc_using_threads) {
|
||||
avc_netlink_thread = avc_create_thread(&avc_netlink_loop);
|
||||
avc_netlink_trouble = 0;
|
||||
}
|
||||
avc_running = 1;
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int avc_open(struct selinux_opt *opts, unsigned nopts)
|
||||
{
|
||||
avc_setenforce = 0;
|
||||
|
||||
while (nopts--)
|
||||
switch(opts[nopts].type) {
|
||||
case AVC_OPT_SETENFORCE:
|
||||
avc_setenforce = 1;
|
||||
avc_enforcing = !!opts[nopts].value;
|
||||
break;
|
||||
}
|
||||
|
||||
return avc_init_internal("avc", NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
int avc_init(const char *prefix,
|
||||
const struct avc_memory_callback *mem_cb,
|
||||
const struct avc_log_callback *log_cb,
|
||||
const struct avc_thread_callback *thread_cb,
|
||||
const struct avc_lock_callback *lock_cb)
|
||||
{
|
||||
return avc_init_internal(prefix, mem_cb, log_cb, thread_cb, lock_cb);
|
||||
}
|
||||
|
||||
void avc_cache_stats(struct avc_cache_stats *p)
|
||||
{
|
||||
memcpy(p, &cache_stats, sizeof(cache_stats));
|
||||
|
@ -294,7 +297,6 @@ void avc_av_stats(void)
|
|||
slots_used, AVC_CACHE_SLOTS, max_chain_len);
|
||||
}
|
||||
|
||||
hidden_def(avc_av_stats)
|
||||
|
||||
static inline struct avc_node *avc_reclaim_node(void)
|
||||
{
|
||||
|
@ -494,7 +496,6 @@ void avc_cleanup(void)
|
|||
{
|
||||
}
|
||||
|
||||
hidden_def(avc_cleanup)
|
||||
|
||||
int avc_reset(void)
|
||||
{
|
||||
|
@ -539,7 +540,6 @@ int avc_reset(void)
|
|||
return rc;
|
||||
}
|
||||
|
||||
hidden_def(avc_reset)
|
||||
|
||||
void avc_destroy(void)
|
||||
{
|
||||
|
@ -551,9 +551,7 @@ void avc_destroy(void)
|
|||
|
||||
avc_get_lock(avc_lock);
|
||||
|
||||
if (avc_using_threads)
|
||||
avc_stop_thread(avc_netlink_thread);
|
||||
avc_netlink_close();
|
||||
selinux_status_close();
|
||||
|
||||
for (i = 0; i < AVC_CACHE_SLOTS; i++) {
|
||||
node = avc_cache.slots[i];
|
||||
|
@ -733,7 +731,6 @@ void avc_audit(security_id_t ssid, security_id_t tsid,
|
|||
avc_release_lock(avc_log_lock);
|
||||
}
|
||||
|
||||
hidden_def(avc_audit)
|
||||
|
||||
|
||||
static void avd_init(struct av_decision *avd)
|
||||
|
@ -761,7 +758,7 @@ int avc_has_perm_noaudit(security_id_t ssid,
|
|||
avd_init(avd);
|
||||
|
||||
if (!avc_using_threads && !avc_app_main_loop) {
|
||||
(void)avc_netlink_check_nb();
|
||||
(void) selinux_status_updated();
|
||||
}
|
||||
|
||||
if (!aeref) {
|
||||
|
@ -825,7 +822,6 @@ int avc_has_perm_noaudit(security_id_t ssid,
|
|||
return rc;
|
||||
}
|
||||
|
||||
hidden_def(avc_has_perm_noaudit)
|
||||
|
||||
int avc_has_perm(security_id_t ssid, security_id_t tsid,
|
||||
security_class_t tclass, access_vector_t requested,
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "callbacks.h"
|
||||
#include "selinux_netlink.h"
|
||||
#include "avc_internal.h"
|
||||
#include "selinux_internal.h"
|
||||
|
||||
#ifndef NETLINK_SELINUX
|
||||
#define NETLINK_SELINUX 7
|
||||
|
@ -52,6 +53,49 @@ int avc_enforcing = 1;
|
|||
int avc_setenforce = 0;
|
||||
int avc_netlink_trouble = 0;
|
||||
|
||||
/* process setenforce events for netlink and sestatus */
|
||||
int avc_process_setenforce(int enforcing)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
avc_log(SELINUX_SETENFORCE,
|
||||
"%s: op=setenforce lsm=selinux enforcing=%d res=1",
|
||||
avc_prefix, enforcing);
|
||||
if (avc_setenforce)
|
||||
goto out;
|
||||
avc_enforcing = enforcing;
|
||||
if (avc_enforcing && (rc = avc_ss_reset(0)) < 0) {
|
||||
avc_log(SELINUX_ERROR,
|
||||
"%s: cache reset returned %d (errno %d)\n",
|
||||
avc_prefix, rc, errno);
|
||||
return rc;
|
||||
}
|
||||
|
||||
out:
|
||||
return selinux_netlink_setenforce(enforcing);
|
||||
}
|
||||
|
||||
/* process policyload events for netlink and sestatus */
|
||||
int avc_process_policyload(uint32_t seqno)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
avc_log(SELINUX_POLICYLOAD,
|
||||
"%s: op=load_policy lsm=selinux seqno=%u res=1",
|
||||
avc_prefix, seqno);
|
||||
rc = avc_ss_reset(seqno);
|
||||
if (rc < 0) {
|
||||
avc_log(SELINUX_ERROR,
|
||||
"%s: cache reset returned %d (errno %d)\n",
|
||||
avc_prefix, rc, errno);
|
||||
return rc;
|
||||
}
|
||||
|
||||
selinux_flush_class_cache();
|
||||
|
||||
return selinux_netlink_policyload(seqno);
|
||||
}
|
||||
|
||||
/* netlink socket code */
|
||||
static int fd = -1;
|
||||
|
||||
|
@ -176,20 +220,7 @@ static int avc_netlink_process(void *buf)
|
|||
|
||||
case SELNL_MSG_SETENFORCE:{
|
||||
struct selnl_msg_setenforce *msg = NLMSG_DATA(nlh);
|
||||
msg->val = !!msg->val;
|
||||
avc_log(SELINUX_INFO,
|
||||
"%s: received setenforce notice (enforcing=%d)\n",
|
||||
avc_prefix, msg->val);
|
||||
if (avc_setenforce)
|
||||
break;
|
||||
avc_enforcing = msg->val;
|
||||
if (avc_enforcing && (rc = avc_ss_reset(0)) < 0) {
|
||||
avc_log(SELINUX_ERROR,
|
||||
"%s: cache reset returned %d (errno %d)\n",
|
||||
avc_prefix, rc, errno);
|
||||
return rc;
|
||||
}
|
||||
rc = selinux_netlink_setenforce(msg->val);
|
||||
rc = avc_process_setenforce(!!msg->val);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
break;
|
||||
|
@ -197,17 +228,7 @@ static int avc_netlink_process(void *buf)
|
|||
|
||||
case SELNL_MSG_POLICYLOAD:{
|
||||
struct selnl_msg_policyload *msg = NLMSG_DATA(nlh);
|
||||
avc_log(SELINUX_INFO,
|
||||
"%s: received policyload notice (seqno=%u)\n",
|
||||
avc_prefix, msg->seqno);
|
||||
rc = avc_ss_reset(msg->seqno);
|
||||
if (rc < 0) {
|
||||
avc_log(SELINUX_ERROR,
|
||||
"%s: cache reset returned %d (errno %d)\n",
|
||||
avc_prefix, rc, errno);
|
||||
return rc;
|
||||
}
|
||||
rc = selinux_netlink_policyload(msg->seqno);
|
||||
rc = avc_process_policyload(msg->seqno);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
break;
|
||||
|
@ -282,6 +303,17 @@ void avc_netlink_loop(void)
|
|||
|
||||
int avc_netlink_acquire_fd(void)
|
||||
{
|
||||
if (fd < 0) {
|
||||
int rc = 0;
|
||||
rc = avc_netlink_open(0);
|
||||
if (rc < 0) {
|
||||
avc_log(SELINUX_ERROR,
|
||||
"%s: could not open netlink socket: %d (%m)\n",
|
||||
avc_prefix, errno);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
avc_app_main_loop = 1;
|
||||
|
||||
return fd;
|
||||
|
|
|
@ -14,24 +14,27 @@
|
|||
#include <string.h>
|
||||
#include <selinux/avc.h>
|
||||
#include "callbacks.h"
|
||||
#include "dso.h"
|
||||
|
||||
/* callback pointers */
|
||||
extern void *(*avc_func_malloc) (size_t) hidden;
|
||||
extern void (*avc_func_free) (void *)hidden;
|
||||
extern void *(*avc_func_malloc) (size_t) ;
|
||||
extern void (*avc_func_free) (void *);
|
||||
|
||||
extern void (*avc_func_log) (const char *, ...) __attribute__((__format__(printf,1,2))) hidden;
|
||||
extern void (*avc_func_audit) (void *, security_class_t, char *, size_t)hidden;
|
||||
extern void (*avc_func_log) (const char *, ...) __attribute__((__format__(printf,1,2))) ;
|
||||
extern void (*avc_func_audit) (void *, security_class_t, char *, size_t);
|
||||
|
||||
extern int avc_using_threads hidden;
|
||||
extern int avc_app_main_loop hidden;
|
||||
extern void *(*avc_func_create_thread) (void (*)(void))hidden;
|
||||
extern void (*avc_func_stop_thread) (void *)hidden;
|
||||
extern int avc_using_threads ;
|
||||
extern int avc_app_main_loop ;
|
||||
extern void *(*avc_func_create_thread) (void (*)(void));
|
||||
extern void (*avc_func_stop_thread) (void *);
|
||||
|
||||
extern void *(*avc_func_alloc_lock) (void)hidden;
|
||||
extern void (*avc_func_get_lock) (void *)hidden;
|
||||
extern void (*avc_func_release_lock) (void *)hidden;
|
||||
extern void (*avc_func_free_lock) (void *)hidden;
|
||||
extern void *(*avc_func_alloc_lock) (void);
|
||||
extern void (*avc_func_get_lock) (void *);
|
||||
extern void (*avc_func_release_lock) (void *);
|
||||
extern void (*avc_func_free_lock) (void *);
|
||||
|
||||
/* selinux status processing for netlink and sestatus */
|
||||
extern int avc_process_setenforce(int enforcing);
|
||||
extern int avc_process_policyload(uint32_t seqno);
|
||||
|
||||
static inline void set_callbacks(const struct avc_memory_callback *mem_cb,
|
||||
const struct avc_log_callback *log_cb,
|
||||
|
@ -61,10 +64,10 @@ static inline void set_callbacks(const struct avc_memory_callback *mem_cb,
|
|||
|
||||
/* message prefix and enforcing mode*/
|
||||
#define AVC_PREFIX_SIZE 16
|
||||
extern char avc_prefix[AVC_PREFIX_SIZE] hidden;
|
||||
extern int avc_running hidden;
|
||||
extern int avc_enforcing hidden;
|
||||
extern int avc_setenforce hidden;
|
||||
extern char avc_prefix[AVC_PREFIX_SIZE] ;
|
||||
extern int avc_running ;
|
||||
extern int avc_enforcing ;
|
||||
extern int avc_setenforce ;
|
||||
|
||||
/* user-supplied callback interface for avc */
|
||||
static inline void *avc_malloc(size_t size)
|
||||
|
@ -82,10 +85,12 @@ static inline void avc_free(void *ptr)
|
|||
|
||||
/* this is a macro in order to use the variadic capability. */
|
||||
#define avc_log(type, format...) \
|
||||
if (avc_func_log) \
|
||||
avc_func_log(format); \
|
||||
else \
|
||||
selinux_log(type, format);
|
||||
do { \
|
||||
if (avc_func_log) \
|
||||
avc_func_log(format); \
|
||||
else \
|
||||
selinux_log(type, format); \
|
||||
} while (0)
|
||||
|
||||
static inline void avc_suppl_audit(void *ptr, security_class_t class,
|
||||
char *buf, size_t len)
|
||||
|
@ -134,14 +139,18 @@ static inline void avc_free_lock(void *lock)
|
|||
#ifdef AVC_CACHE_STATS
|
||||
|
||||
#define avc_cache_stats_incr(field) \
|
||||
cache_stats.field ++;
|
||||
do { \
|
||||
cache_stats.field ++; \
|
||||
} while (0)
|
||||
#define avc_cache_stats_add(field, num) \
|
||||
cache_stats.field += num;
|
||||
do { \
|
||||
cache_stats.field += num; \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define avc_cache_stats_incr(field)
|
||||
#define avc_cache_stats_add(field, num)
|
||||
#define avc_cache_stats_incr(field) do {} while (0)
|
||||
#define avc_cache_stats_add(field, num) do {} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -155,28 +164,23 @@ static inline void avc_free_lock(void *lock)
|
|||
/* internal callbacks */
|
||||
int avc_ss_grant(security_id_t ssid, security_id_t tsid,
|
||||
security_class_t tclass, access_vector_t perms,
|
||||
uint32_t seqno) hidden;
|
||||
uint32_t seqno) ;
|
||||
int avc_ss_try_revoke(security_id_t ssid, security_id_t tsid,
|
||||
security_class_t tclass,
|
||||
access_vector_t perms, uint32_t seqno,
|
||||
access_vector_t * out_retained) hidden;
|
||||
access_vector_t * out_retained) ;
|
||||
int avc_ss_revoke(security_id_t ssid, security_id_t tsid,
|
||||
security_class_t tclass, access_vector_t perms,
|
||||
uint32_t seqno) hidden;
|
||||
int avc_ss_reset(uint32_t seqno) hidden;
|
||||
uint32_t seqno) ;
|
||||
int avc_ss_reset(uint32_t seqno) ;
|
||||
int avc_ss_set_auditallow(security_id_t ssid, security_id_t tsid,
|
||||
security_class_t tclass, access_vector_t perms,
|
||||
uint32_t seqno, uint32_t enable) hidden;
|
||||
uint32_t seqno, uint32_t enable) ;
|
||||
int avc_ss_set_auditdeny(security_id_t ssid, security_id_t tsid,
|
||||
security_class_t tclass, access_vector_t perms,
|
||||
uint32_t seqno, uint32_t enable) hidden;
|
||||
uint32_t seqno, uint32_t enable) ;
|
||||
|
||||
/* netlink kernel message code */
|
||||
extern int avc_netlink_trouble hidden;
|
||||
extern int avc_netlink_trouble ;
|
||||
|
||||
hidden_proto(avc_av_stats)
|
||||
hidden_proto(avc_cleanup)
|
||||
hidden_proto(avc_reset)
|
||||
hidden_proto(avc_audit)
|
||||
hidden_proto(avc_has_perm_noaudit)
|
||||
#endif /* _SELINUX_AVC_INTERNAL_H_ */
|
||||
|
|
|
@ -15,14 +15,13 @@
|
|||
|
||||
static inline unsigned sidtab_hash(const char * key)
|
||||
{
|
||||
char *p, *keyp;
|
||||
const char *p;
|
||||
unsigned int size;
|
||||
unsigned int val;
|
||||
|
||||
val = 0;
|
||||
keyp = (char *)key;
|
||||
size = strlen(keyp);
|
||||
for (p = keyp; (unsigned int)(p - keyp) < size; p++)
|
||||
size = strlen(key);
|
||||
for (p = key; (unsigned int)(p - key) < size; p++)
|
||||
val =
|
||||
(val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p);
|
||||
return val & (SIDTAB_SIZE - 1);
|
||||
|
@ -57,7 +56,7 @@ int sidtab_insert(struct sidtab *s, const char * ctx)
|
|||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
newctx = (char *) strdup(ctx);
|
||||
newctx = strdup(ctx);
|
||||
if (!newctx) {
|
||||
rc = -1;
|
||||
avc_free(newnode);
|
||||
|
@ -101,7 +100,7 @@ sidtab_context_to_sid(struct sidtab *s,
|
|||
return rc;
|
||||
}
|
||||
|
||||
void sidtab_sid_stats(struct sidtab *h, char *buf, int buflen)
|
||||
void sidtab_sid_stats(struct sidtab *s, char *buf, int buflen)
|
||||
{
|
||||
int i, chain_len, slots_used, max_chain_len;
|
||||
struct sidtab_node *cur;
|
||||
|
@ -109,7 +108,7 @@ void sidtab_sid_stats(struct sidtab *h, char *buf, int buflen)
|
|||
slots_used = 0;
|
||||
max_chain_len = 0;
|
||||
for (i = 0; i < SIDTAB_SIZE; i++) {
|
||||
cur = h->htable[i];
|
||||
cur = s->htable[i];
|
||||
if (cur) {
|
||||
slots_used++;
|
||||
chain_len = 0;
|
||||
|
@ -125,7 +124,7 @@ void sidtab_sid_stats(struct sidtab *h, char *buf, int buflen)
|
|||
|
||||
snprintf(buf, buflen,
|
||||
"%s: %u SID entries and %d/%d buckets used, longest "
|
||||
"chain length %d\n", avc_prefix, h->nel, slots_used,
|
||||
"chain length %d\n", avc_prefix, s->nel, slots_used,
|
||||
SIDTAB_SIZE, max_chain_len);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
#include <selinux/selinux.h>
|
||||
#include <selinux/avc.h>
|
||||
#include "dso.h"
|
||||
|
||||
struct sidtab_node {
|
||||
struct security_id sid_s;
|
||||
|
@ -24,13 +23,13 @@ struct sidtab {
|
|||
unsigned nel;
|
||||
};
|
||||
|
||||
int sidtab_init(struct sidtab *s) hidden;
|
||||
int sidtab_insert(struct sidtab *s, const char * ctx) hidden;
|
||||
int sidtab_init(struct sidtab *s) ;
|
||||
int sidtab_insert(struct sidtab *s, const char * ctx) ;
|
||||
|
||||
int sidtab_context_to_sid(struct sidtab *s,
|
||||
const char * ctx, security_id_t * sid) hidden;
|
||||
const char * ctx, security_id_t * sid) ;
|
||||
|
||||
void sidtab_sid_stats(struct sidtab *s, char *buf, int buflen) hidden;
|
||||
void sidtab_destroy(struct sidtab *s) hidden;
|
||||
void sidtab_sid_stats(struct sidtab *s, char *buf, int buflen) ;
|
||||
void sidtab_destroy(struct sidtab *s) ;
|
||||
|
||||
#endif /* _SELINUX_AVC_SIDTAB_H_ */
|
||||
|
|
|
@ -414,8 +414,3 @@ char *selinux_boolean_sub(const char *name __attribute__((unused)))
|
|||
}
|
||||
#endif
|
||||
|
||||
hidden_def(security_get_boolean_names)
|
||||
hidden_def(selinux_boolean_sub)
|
||||
hidden_def(security_get_boolean_active)
|
||||
hidden_def(security_set_boolean)
|
||||
hidden_def(security_commit_booleans)
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include <selinux/selinux.h>
|
||||
#include "callbacks.h"
|
||||
|
||||
pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* default implementations */
|
||||
static int __attribute__ ((format(printf, 2, 3)))
|
||||
default_selinux_log(int type __attribute__((unused)), const char *fmt, ...)
|
||||
|
@ -56,7 +58,7 @@ default_selinux_policyload(int seqno __attribute__((unused)))
|
|||
|
||||
/* callback pointers */
|
||||
int __attribute__ ((format(printf, 2, 3)))
|
||||
(*selinux_log)(int, const char *, ...) =
|
||||
(*selinux_log_direct)(int, const char *, ...) =
|
||||
default_selinux_log;
|
||||
|
||||
int
|
||||
|
@ -81,7 +83,7 @@ selinux_set_callback(int type, union selinux_callback cb)
|
|||
{
|
||||
switch (type) {
|
||||
case SELINUX_CB_LOG:
|
||||
selinux_log = cb.func_log;
|
||||
selinux_log_direct = cb.func_log;
|
||||
break;
|
||||
case SELINUX_CB_AUDIT:
|
||||
selinux_audit = cb.func_audit;
|
||||
|
@ -106,7 +108,7 @@ selinux_get_callback(int type)
|
|||
|
||||
switch (type) {
|
||||
case SELINUX_CB_LOG:
|
||||
cb.func_log = selinux_log;
|
||||
cb.func_log = selinux_log_direct;
|
||||
break;
|
||||
case SELINUX_CB_AUDIT:
|
||||
cb.func_audit = selinux_audit;
|
||||
|
|
|
@ -5,26 +5,39 @@
|
|||
#ifndef _SELINUX_CALLBACKS_H_
|
||||
#define _SELINUX_CALLBACKS_H_
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <selinux/selinux.h>
|
||||
#include "dso.h"
|
||||
|
||||
#include "selinux_internal.h"
|
||||
|
||||
/* callback pointers */
|
||||
extern int __attribute__ ((format(printf, 2, 3)))
|
||||
(*selinux_log) (int type, const char *, ...) hidden;
|
||||
(*selinux_log_direct) (int type, const char *, ...) ;
|
||||
|
||||
extern int
|
||||
(*selinux_audit) (void *, security_class_t, char *, size_t) hidden;
|
||||
(*selinux_audit) (void *, security_class_t, char *, size_t) ;
|
||||
|
||||
extern int
|
||||
(*selinux_validate)(char **ctx) hidden;
|
||||
(*selinux_validate)(char **ctx) ;
|
||||
|
||||
extern int
|
||||
(*selinux_netlink_setenforce) (int enforcing) hidden;
|
||||
(*selinux_netlink_setenforce) (int enforcing) ;
|
||||
|
||||
extern int
|
||||
(*selinux_netlink_policyload) (int seqno) hidden;
|
||||
(*selinux_netlink_policyload) (int seqno) ;
|
||||
|
||||
/* Thread-safe selinux_log() function */
|
||||
extern pthread_mutex_t log_mutex;
|
||||
|
||||
#define selinux_log(type, ...) do { \
|
||||
int saved_errno__ = errno; \
|
||||
__pthread_mutex_lock(&log_mutex); \
|
||||
selinux_log_direct(type, __VA_ARGS__); \
|
||||
__pthread_mutex_unlock(&log_mutex); \
|
||||
errno = saved_errno__; \
|
||||
} while(0)
|
||||
|
||||
#endif /* _SELINUX_CALLBACKS_H_ */
|
||||
|
|
|
@ -60,7 +60,6 @@ int security_canonicalize_context_raw(const char * con,
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_canonicalize_context_raw)
|
||||
|
||||
int security_canonicalize_context(const char * con,
|
||||
char ** canoncon)
|
||||
|
@ -83,4 +82,3 @@ int security_canonicalize_context(const char * con,
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_canonicalize_context)
|
||||
|
|
|
@ -10,25 +10,12 @@
|
|||
static pthread_once_t once = PTHREAD_ONCE_INIT;
|
||||
static int selinux_enabled;
|
||||
|
||||
static int avc_reset_callback(uint32_t event __attribute__((unused)),
|
||||
security_id_t ssid __attribute__((unused)),
|
||||
security_id_t tsid __attribute__((unused)),
|
||||
security_class_t tclass __attribute__((unused)),
|
||||
access_vector_t perms __attribute__((unused)),
|
||||
access_vector_t *out_retained __attribute__((unused)))
|
||||
{
|
||||
flush_class_cache();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void avc_init_once(void)
|
||||
{
|
||||
selinux_enabled = is_selinux_enabled();
|
||||
if (selinux_enabled == 1) {
|
||||
if (avc_open(NULL, 0))
|
||||
return;
|
||||
avc_add_callback(avc_reset_callback, AVC_CALLBACK_RESET,
|
||||
0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +39,7 @@ int selinux_check_access(const char *scon, const char *tcon, const char *class,
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
(void) avc_netlink_check_nb();
|
||||
(void) selinux_status_updated();
|
||||
|
||||
sclass = string_to_security_class(class);
|
||||
if (sclass == 0) {
|
||||
|
@ -77,7 +64,7 @@ int selinux_check_access(const char *scon, const char *tcon, const char *class,
|
|||
return avc_has_perm (scon_id, tcon_id, sclass, av, NULL, aux);
|
||||
}
|
||||
|
||||
int selinux_check_passwd_access(access_vector_t requested)
|
||||
static int selinux_check_passwd_access_internal(access_vector_t requested)
|
||||
{
|
||||
int status = -1;
|
||||
char *user_context;
|
||||
|
@ -91,7 +78,9 @@ int selinux_check_passwd_access(access_vector_t requested)
|
|||
passwd_class = string_to_security_class("passwd");
|
||||
if (passwd_class == 0) {
|
||||
freecon(user_context);
|
||||
return 0;
|
||||
if (security_deny_unknown() == 0)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = security_compute_av_raw(user_context,
|
||||
|
@ -112,9 +101,11 @@ int selinux_check_passwd_access(access_vector_t requested)
|
|||
return status;
|
||||
}
|
||||
|
||||
hidden_def(selinux_check_passwd_access)
|
||||
int selinux_check_passwd_access(access_vector_t requested) {
|
||||
return selinux_check_passwd_access_internal(requested);
|
||||
}
|
||||
|
||||
int checkPasswdAccess(access_vector_t requested)
|
||||
{
|
||||
return selinux_check_passwd_access(requested);
|
||||
return selinux_check_passwd_access_internal(requested);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ int security_check_context_raw(const char * con)
|
|||
return 0;
|
||||
}
|
||||
|
||||
hidden_def(security_check_context_raw)
|
||||
|
||||
int security_check_context(const char * con)
|
||||
{
|
||||
|
@ -48,4 +47,3 @@ int security_check_context(const char * con)
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_check_context)
|
||||
|
|
|
@ -37,4 +37,3 @@ int security_get_checkreqprot(void)
|
|||
return checkreqprot;
|
||||
}
|
||||
|
||||
hidden_def(security_get_checkreqprot);
|
||||
|
|
|
@ -80,7 +80,6 @@ int security_compute_av_flags_raw(const char * scon,
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_compute_av_flags_raw)
|
||||
|
||||
int security_compute_av_raw(const char * scon,
|
||||
const char * tcon,
|
||||
|
@ -107,7 +106,6 @@ int security_compute_av_raw(const char * scon,
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_compute_av_raw)
|
||||
|
||||
int security_compute_av_flags(const char * scon,
|
||||
const char * tcon,
|
||||
|
@ -134,7 +132,6 @@ int security_compute_av_flags(const char * scon,
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_compute_av_flags)
|
||||
|
||||
int security_compute_av(const char * scon,
|
||||
const char * tcon,
|
||||
|
@ -162,4 +159,3 @@ int security_compute_av(const char * scon,
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_compute_av)
|
||||
|
|
|
@ -105,7 +105,6 @@ int security_compute_create_name_raw(const char * scon,
|
|||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
hidden_def(security_compute_create_name_raw)
|
||||
|
||||
int security_compute_create_raw(const char * scon,
|
||||
const char * tcon,
|
||||
|
@ -115,7 +114,6 @@ int security_compute_create_raw(const char * scon,
|
|||
return security_compute_create_name_raw(scon, tcon, tclass,
|
||||
NULL, newcon);
|
||||
}
|
||||
hidden_def(security_compute_create_raw)
|
||||
|
||||
int security_compute_create_name(const char * scon,
|
||||
const char * tcon,
|
||||
|
@ -146,7 +144,6 @@ int security_compute_create_name(const char * scon,
|
|||
|
||||
return ret;
|
||||
}
|
||||
hidden_def(security_compute_create_name)
|
||||
|
||||
int security_compute_create(const char * scon,
|
||||
const char * tcon,
|
||||
|
@ -155,4 +152,3 @@ int security_compute_create(const char * scon,
|
|||
{
|
||||
return security_compute_create_name(scon, tcon, tclass, NULL, newcon);
|
||||
}
|
||||
hidden_def(security_compute_create)
|
||||
|
|
|
@ -60,7 +60,6 @@ int security_compute_member_raw(const char * scon,
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_compute_member_raw)
|
||||
|
||||
int security_compute_member(const char * scon,
|
||||
const char * tcon,
|
||||
|
|
|
@ -60,7 +60,6 @@ int security_compute_relabel_raw(const char * scon,
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_compute_relabel_raw)
|
||||
|
||||
int security_compute_relabel(const char * scon,
|
||||
const char * tcon,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "selinux_internal.h"
|
||||
#include "policy.h"
|
||||
#include <limits.h>
|
||||
#include "callbacks.h"
|
||||
|
||||
int security_compute_user_raw(const char * scon,
|
||||
const char *user, char *** con)
|
||||
|
@ -24,6 +25,8 @@ int security_compute_user_raw(const char * scon,
|
|||
return -1;
|
||||
}
|
||||
|
||||
selinux_log(SELINUX_WARNING, "Direct use of security_compute_user() is deprecated, switch to get_ordered_context_list()\n");
|
||||
|
||||
snprintf(path, sizeof path, "%s/user", selinux_mnt);
|
||||
fd = open(path, O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
|
@ -77,7 +80,6 @@ int security_compute_user_raw(const char * scon,
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_compute_user_raw)
|
||||
|
||||
int security_compute_user(const char * scon,
|
||||
const char *user, char *** con)
|
||||
|
@ -107,4 +109,3 @@ int security_compute_user(const char * scon,
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_compute_user)
|
||||
|
|
|
@ -37,7 +37,7 @@ context_t context_new(const char *str)
|
|||
}
|
||||
n->current_str = n->component[0] = n->component[1] = n->component[2] =
|
||||
n->component[3] = 0;
|
||||
for (i = count = 0, p = str; *p; p++) {
|
||||
for (count = 0, p = str; *p; p++) {
|
||||
switch (*p) {
|
||||
case ':':
|
||||
count++;
|
||||
|
@ -82,7 +82,6 @@ context_t context_new(const char *str)
|
|||
return 0;
|
||||
}
|
||||
|
||||
hidden_def(context_new)
|
||||
|
||||
static void conditional_free(char **v)
|
||||
{
|
||||
|
@ -113,7 +112,6 @@ void context_free(context_t context)
|
|||
}
|
||||
}
|
||||
|
||||
hidden_def(context_free)
|
||||
|
||||
/*
|
||||
* Return a pointer to the string value of the context.
|
||||
|
@ -144,7 +142,6 @@ char *context_str(context_t context)
|
|||
return n->current_str;
|
||||
}
|
||||
|
||||
hidden_def(context_str)
|
||||
|
||||
/* Returns nonzero iff failed */
|
||||
static int set_comp(context_private_t * n, int idx, const char *str)
|
||||
|
@ -154,14 +151,14 @@ static int set_comp(context_private_t * n, int idx, const char *str)
|
|||
if (str) {
|
||||
t = (char *)malloc(strlen(str) + 1);
|
||||
if (!t) {
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
for (p = str; *p; p++) {
|
||||
if (*p == '\t' || *p == '\n' || *p == '\r' ||
|
||||
((*p == ':' || *p == ' ') && idx != COMP_RANGE)) {
|
||||
free(t);
|
||||
errno = EINVAL;
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
strcpy(t, str);
|
||||
|
@ -176,8 +173,7 @@ const char * context_ ## name ## _get(context_t context) \
|
|||
{ \
|
||||
context_private_t *n = context->ptr; \
|
||||
return n->component[tag]; \
|
||||
} \
|
||||
hidden_def(context_ ## name ## _get)
|
||||
}
|
||||
|
||||
def_get(type, COMP_TYPE)
|
||||
def_get(user, COMP_USER)
|
||||
|
@ -187,8 +183,7 @@ def_get(type, COMP_TYPE)
|
|||
int context_ ## name ## _set(context_t context, const char* str) \
|
||||
{ \
|
||||
return set_comp(context->ptr,tag,str);\
|
||||
} \
|
||||
hidden_def(context_ ## name ## _set)
|
||||
}
|
||||
def_set(type, COMP_TYPE)
|
||||
def_set(role, COMP_ROLE)
|
||||
def_set(user, COMP_USER)
|
||||
|
|
|
@ -1,14 +1,2 @@
|
|||
#include <selinux/context.h>
|
||||
#include "dso.h"
|
||||
|
||||
hidden_proto(context_new)
|
||||
hidden_proto(context_free)
|
||||
hidden_proto(context_str)
|
||||
hidden_proto(context_type_set)
|
||||
hidden_proto(context_type_get)
|
||||
hidden_proto(context_role_set)
|
||||
hidden_proto(context_role_get)
|
||||
hidden_proto(context_user_set)
|
||||
hidden_proto(context_user_get)
|
||||
hidden_proto(context_range_set)
|
||||
hidden_proto(context_range_get)
|
||||
|
|
|
@ -37,4 +37,3 @@ int security_deny_unknown(void)
|
|||
return deny_unknown;
|
||||
}
|
||||
|
||||
hidden_def(security_deny_unknown);
|
||||
|
|
|
@ -35,4 +35,3 @@ int security_disable(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
hidden_def(security_disable)
|
||||
|
|
23
src/dso.h
23
src/dso.h
|
@ -1,23 +0,0 @@
|
|||
#ifndef _SELINUX_DSO_H
|
||||
#define _SELINUX_DSO_H 1
|
||||
|
||||
#ifdef SHARED
|
||||
# define hidden __attribute__ ((visibility ("hidden")))
|
||||
# define hidden_proto(fct) __hidden_proto (fct, fct##_internal)
|
||||
# define __hidden_proto(fct, internal) \
|
||||
extern __typeof (fct) internal; \
|
||||
extern __typeof (fct) fct __asm (#internal) hidden;
|
||||
# if defined(__alpha__) || defined(__mips__)
|
||||
# define hidden_def(fct) \
|
||||
asm (".globl " #fct "\n" #fct " = " #fct "_internal");
|
||||
# else
|
||||
# define hidden_def(fct) \
|
||||
asm (".globl " #fct "\n.set " #fct ", " #fct "_internal");
|
||||
#endif
|
||||
#else
|
||||
# define hidden
|
||||
# define hidden_proto(fct)
|
||||
# define hidden_def(fct)
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -20,7 +20,6 @@ int is_selinux_enabled(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
hidden_def(is_selinux_enabled)
|
||||
|
||||
/*
|
||||
* Function: is_selinux_mls_enabled()
|
||||
|
@ -55,4 +54,3 @@ int is_selinux_mls_enabled(void)
|
|||
return enabled;
|
||||
}
|
||||
|
||||
hidden_def(is_selinux_mls_enabled)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
function except() {
|
||||
case $1 in
|
||||
selinux_file_context_cmp) # ignore
|
||||
|
@ -10,15 +12,26 @@ echo "
|
|||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
SWIG_fail;
|
||||
}
|
||||
}
|
||||
"
|
||||
}"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
if ! ${CC:-gcc} -x c -c -I../include -o temp.o - -aux-info temp.aux < ../include/selinux/selinux.h
|
||||
|
||||
# Make sure that selinux.h is included first in order not to depend on the order
|
||||
# in which "#include <selinux/selinux.h>" appears in other files.
|
||||
FILE_LIST=(
|
||||
../include/selinux/selinux.h
|
||||
../include/selinux/avc.h
|
||||
../include/selinux/context.h
|
||||
../include/selinux/get_context_list.h
|
||||
../include/selinux/get_default_type.h
|
||||
../include/selinux/label.h
|
||||
../include/selinux/restorecon.h
|
||||
)
|
||||
if ! cat "${FILE_LIST[@]}" | ${CC:-gcc} -x c -c -I../include -o temp.o - -aux-info temp.aux
|
||||
then
|
||||
# clang does not support -aux-info so fall back to gcc
|
||||
gcc -x c -c -I../include -o temp.o - -aux-info temp.aux < ../include/selinux/selinux.h
|
||||
cat "${FILE_LIST[@]}" | gcc -x c -c -I../include -o temp.o - -aux-info temp.aux
|
||||
fi
|
||||
for i in `awk '/<stdin>.*extern int/ { print $6 }' temp.aux`; do except $i ; done
|
||||
rm -f -- temp.aux temp.o
|
||||
|
|
|
@ -3,10 +3,32 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/xattr.h>
|
||||
#include "selinux_internal.h"
|
||||
#include "policy.h"
|
||||
|
||||
static ssize_t fgetxattr_wrapper(int fd, const char *name, void *value, size_t size) {
|
||||
char buf[40];
|
||||
int fd_flag, saved_errno = errno;
|
||||
ssize_t ret;
|
||||
|
||||
ret = fgetxattr(fd, name, value, size);
|
||||
if (ret != -1 || errno != EBADF)
|
||||
return ret;
|
||||
|
||||
/* Emulate O_PATH support */
|
||||
fd_flag = fcntl(fd, F_GETFL);
|
||||
if (fd_flag == -1 || (fd_flag & O_PATH) == 0) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
|
||||
errno = saved_errno;
|
||||
return getxattr(buf, name, value, size);
|
||||
}
|
||||
|
||||
int fgetfilecon_raw(int fd, char ** context)
|
||||
{
|
||||
char *buf;
|
||||
|
@ -19,11 +41,11 @@ int fgetfilecon_raw(int fd, char ** context)
|
|||
return -1;
|
||||
memset(buf, 0, size);
|
||||
|
||||
ret = fgetxattr(fd, XATTR_NAME_SELINUX, buf, size - 1);
|
||||
ret = fgetxattr_wrapper(fd, XATTR_NAME_SELINUX, buf, size - 1);
|
||||
if (ret < 0 && errno == ERANGE) {
|
||||
char *newbuf;
|
||||
|
||||
size = fgetxattr(fd, XATTR_NAME_SELINUX, NULL, 0);
|
||||
size = fgetxattr_wrapper(fd, XATTR_NAME_SELINUX, NULL, 0);
|
||||
if (size < 0)
|
||||
goto out;
|
||||
|
||||
|
@ -34,7 +56,7 @@ int fgetfilecon_raw(int fd, char ** context)
|
|||
|
||||
buf = newbuf;
|
||||
memset(buf, 0, size);
|
||||
ret = fgetxattr(fd, XATTR_NAME_SELINUX, buf, size - 1);
|
||||
ret = fgetxattr_wrapper(fd, XATTR_NAME_SELINUX, buf, size - 1);
|
||||
}
|
||||
out:
|
||||
if (ret == 0) {
|
||||
|
@ -49,7 +71,6 @@ int fgetfilecon_raw(int fd, char ** context)
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(fgetfilecon_raw)
|
||||
|
||||
int fgetfilecon(int fd, char ** context)
|
||||
{
|
||||
|
|
|
@ -8,4 +8,3 @@ void freecon(char * con)
|
|||
free(con);
|
||||
}
|
||||
|
||||
hidden_def(freecon)
|
||||
|
|
|
@ -16,4 +16,3 @@ void freeconary(char ** con)
|
|||
free(con);
|
||||
}
|
||||
|
||||
hidden_def(freeconary)
|
||||
|
|
|
@ -3,13 +3,34 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/xattr.h>
|
||||
#include "selinux_internal.h"
|
||||
#include "policy.h"
|
||||
|
||||
static int fsetxattr_wrapper(int fd, const char* name, const void* value, size_t size, int flags) {
|
||||
char buf[40];
|
||||
int rc, fd_flag, saved_errno = errno;
|
||||
|
||||
rc = fsetxattr(fd, name, value, size, flags);
|
||||
if (rc == 0 || errno != EBADF)
|
||||
return rc;
|
||||
|
||||
/* Emulate O_PATH support */
|
||||
fd_flag = fcntl(fd, F_GETFL);
|
||||
if (fd_flag == -1 || (fd_flag & O_PATH) == 0) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
|
||||
errno = saved_errno;
|
||||
return setxattr(buf, name, value, size, flags);
|
||||
}
|
||||
|
||||
int fsetfilecon_raw(int fd, const char * context)
|
||||
{
|
||||
int rc = fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1,
|
||||
int rc = fsetxattr_wrapper(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1,
|
||||
0);
|
||||
if (rc < 0 && errno == ENOTSUP) {
|
||||
char * ccontext = NULL;
|
||||
|
@ -25,7 +46,6 @@ int fsetfilecon_raw(int fd, const char * context)
|
|||
return rc;
|
||||
}
|
||||
|
||||
hidden_def(fsetfilecon_raw)
|
||||
|
||||
int fsetfilecon(int fd, const char *context)
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdio_ext.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
@ -12,7 +13,7 @@
|
|||
|
||||
int get_default_context_with_role(const char *user,
|
||||
const char *role,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char ** newcon)
|
||||
{
|
||||
char **conary;
|
||||
|
@ -51,28 +52,28 @@ int get_default_context_with_role(const char *user,
|
|||
return rc;
|
||||
}
|
||||
|
||||
hidden_def(get_default_context_with_role)
|
||||
|
||||
int get_default_context_with_rolelevel(const char *user,
|
||||
const char *role,
|
||||
const char *level,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char ** newcon)
|
||||
{
|
||||
|
||||
int rc = 0;
|
||||
int freefrom = 0;
|
||||
int rc;
|
||||
char *backup_fromcon = NULL;
|
||||
context_t con;
|
||||
char *newfromcon;
|
||||
const char *newfromcon;
|
||||
|
||||
if (!level)
|
||||
return get_default_context_with_role(user, role, fromcon,
|
||||
newcon);
|
||||
|
||||
if (!fromcon) {
|
||||
rc = getcon(&fromcon);
|
||||
rc = getcon(&backup_fromcon);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
freefrom = 1;
|
||||
fromcon = backup_fromcon;
|
||||
}
|
||||
|
||||
rc = -1;
|
||||
|
@ -91,14 +92,13 @@ int get_default_context_with_rolelevel(const char *user,
|
|||
|
||||
out:
|
||||
context_free(con);
|
||||
if (freefrom)
|
||||
freecon(fromcon);
|
||||
freecon(backup_fromcon);
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
int get_default_context(const char *user,
|
||||
char * fromcon, char ** newcon)
|
||||
const char *fromcon, char ** newcon)
|
||||
{
|
||||
char **conary;
|
||||
int rc;
|
||||
|
@ -114,64 +114,41 @@ int get_default_context(const char *user,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int find_partialcon(char ** list,
|
||||
unsigned int nreach, char *part)
|
||||
static int is_in_reachable(char **reachable, const char *usercon_str)
|
||||
{
|
||||
const char *conrole, *contype;
|
||||
char *partrole, *parttype, *ptr;
|
||||
context_t con;
|
||||
unsigned int i;
|
||||
if (!reachable)
|
||||
return 0;
|
||||
|
||||
partrole = part;
|
||||
ptr = part;
|
||||
while (*ptr && !isspace(*ptr) && *ptr != ':')
|
||||
ptr++;
|
||||
if (*ptr != ':')
|
||||
return -1;
|
||||
*ptr++ = 0;
|
||||
parttype = ptr;
|
||||
while (*ptr && !isspace(*ptr) && *ptr != ':')
|
||||
ptr++;
|
||||
*ptr = 0;
|
||||
|
||||
for (i = 0; i < nreach; i++) {
|
||||
con = context_new(list[i]);
|
||||
if (!con)
|
||||
return -1;
|
||||
conrole = context_role_get(con);
|
||||
contype = context_type_get(con);
|
||||
if (!conrole || !contype) {
|
||||
context_free(con);
|
||||
return -1;
|
||||
for (; *reachable != NULL; reachable++) {
|
||||
if (strcmp(*reachable, usercon_str) == 0) {
|
||||
return 1;
|
||||
}
|
||||
if (!strcmp(conrole, partrole) && !strcmp(contype, parttype)) {
|
||||
context_free(con);
|
||||
return i;
|
||||
}
|
||||
context_free(con);
|
||||
}
|
||||
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_context_order(FILE * fp,
|
||||
char * fromcon,
|
||||
char ** reachable,
|
||||
unsigned int nreach,
|
||||
unsigned int *ordering, unsigned int *nordered)
|
||||
static int get_context_user(FILE * fp,
|
||||
const char * fromcon,
|
||||
const char * user,
|
||||
char ***reachable,
|
||||
unsigned int *nreachable)
|
||||
{
|
||||
char *start, *end = NULL;
|
||||
char *line = NULL;
|
||||
size_t line_len = 0;
|
||||
size_t line_len = 0, usercon_len;
|
||||
size_t user_len = strlen(user);
|
||||
ssize_t len;
|
||||
int found = 0;
|
||||
const char *fromrole, *fromtype;
|
||||
const char *fromrole, *fromtype, *fromlevel;
|
||||
char *linerole, *linetype;
|
||||
unsigned int i;
|
||||
char **new_reachable = NULL;
|
||||
char *usercon_str;
|
||||
context_t con;
|
||||
context_t usercon;
|
||||
|
||||
int rc;
|
||||
|
||||
errno = -EINVAL;
|
||||
errno = EINVAL;
|
||||
|
||||
/* Extract the role and type of the fromcon for matching.
|
||||
User identity and MLS range can be variable. */
|
||||
|
@ -180,6 +157,7 @@ static int get_context_order(FILE * fp,
|
|||
return -1;
|
||||
fromrole = context_role_get(con);
|
||||
fromtype = context_type_get(con);
|
||||
fromlevel = context_range_get(con);
|
||||
if (!fromrole || !fromtype) {
|
||||
context_free(con);
|
||||
return -1;
|
||||
|
@ -243,23 +221,75 @@ static int get_context_order(FILE * fp,
|
|||
if (*end)
|
||||
*end++ = 0;
|
||||
|
||||
/* Check for a match in the reachable list. */
|
||||
rc = find_partialcon(reachable, nreach, start);
|
||||
if (rc < 0) {
|
||||
/* No match, skip it. */
|
||||
/* Check whether a new context is valid */
|
||||
if (SIZE_MAX - user_len < strlen(start) + 2) {
|
||||
fprintf(stderr, "%s: one of partial contexts is too big\n", __FUNCTION__);
|
||||
errno = EINVAL;
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
usercon_len = user_len + strlen(start) + 2;
|
||||
usercon_str = malloc(usercon_len);
|
||||
if (!usercon_str) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* set range from fromcon in the new usercon */
|
||||
snprintf(usercon_str, usercon_len, "%s:%s", user, start);
|
||||
usercon = context_new(usercon_str);
|
||||
if (!usercon) {
|
||||
if (errno != EINVAL) {
|
||||
free(usercon_str);
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
fprintf(stderr,
|
||||
"%s: can't create a context from %s, skipping\n",
|
||||
__FUNCTION__, usercon_str);
|
||||
free(usercon_str);
|
||||
start = end;
|
||||
continue;
|
||||
}
|
||||
free(usercon_str);
|
||||
if (context_range_set(usercon, fromlevel) != 0) {
|
||||
context_free(usercon);
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
usercon_str = context_str(usercon);
|
||||
if (!usercon_str) {
|
||||
context_free(usercon);
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If a match is found and the entry is not already ordered
|
||||
(e.g. due to prior match in prior config file), then set
|
||||
the ordering for it. */
|
||||
i = rc;
|
||||
if (ordering[i] == nreach)
|
||||
ordering[i] = (*nordered)++;
|
||||
/* check whether usercon is already in reachable */
|
||||
if (is_in_reachable(*reachable, usercon_str)) {
|
||||
context_free(usercon);
|
||||
start = end;
|
||||
continue;
|
||||
}
|
||||
if (security_check_context(usercon_str) == 0) {
|
||||
new_reachable = realloc(*reachable, (*nreachable + 2) * sizeof(char *));
|
||||
if (!new_reachable) {
|
||||
context_free(usercon);
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
*reachable = new_reachable;
|
||||
new_reachable[*nreachable] = strdup(usercon_str);
|
||||
if (new_reachable[*nreachable] == NULL) {
|
||||
context_free(usercon);
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
new_reachable[*nreachable + 1] = 0;
|
||||
*nreachable += 1;
|
||||
}
|
||||
context_free(usercon);
|
||||
start = end;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
|
@ -313,39 +343,24 @@ static int get_failsafe_context(const char *user, char ** newcon)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct context_order {
|
||||
char * con;
|
||||
unsigned int order;
|
||||
};
|
||||
|
||||
static int order_compare(const void *A, const void *B)
|
||||
{
|
||||
const struct context_order *c1 = A, *c2 = B;
|
||||
if (c1->order < c2->order)
|
||||
return -1;
|
||||
else if (c1->order > c2->order)
|
||||
return 1;
|
||||
return strcmp(c1->con, c2->con);
|
||||
}
|
||||
|
||||
int get_ordered_context_list_with_level(const char *user,
|
||||
const char *level,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char *** list)
|
||||
{
|
||||
int rc;
|
||||
int freefrom = 0;
|
||||
char *backup_fromcon = NULL;
|
||||
context_t con;
|
||||
char *newfromcon;
|
||||
const char *newfromcon;
|
||||
|
||||
if (!level)
|
||||
return get_ordered_context_list(user, fromcon, list);
|
||||
|
||||
if (!fromcon) {
|
||||
rc = getcon(&fromcon);
|
||||
rc = getcon(&backup_fromcon);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
freefrom = 1;
|
||||
fromcon = backup_fromcon;
|
||||
}
|
||||
|
||||
rc = -1;
|
||||
|
@ -364,16 +379,14 @@ int get_ordered_context_list_with_level(const char *user,
|
|||
|
||||
out:
|
||||
context_free(con);
|
||||
if (freefrom)
|
||||
freecon(fromcon);
|
||||
freecon(backup_fromcon);
|
||||
return rc;
|
||||
}
|
||||
|
||||
hidden_def(get_ordered_context_list_with_level)
|
||||
|
||||
int get_default_context_with_level(const char *user,
|
||||
const char *level,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char ** newcon)
|
||||
{
|
||||
char **conary;
|
||||
|
@ -391,15 +404,13 @@ int get_default_context_with_level(const char *user,
|
|||
}
|
||||
|
||||
int get_ordered_context_list(const char *user,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char *** list)
|
||||
{
|
||||
char **reachable = NULL;
|
||||
unsigned int *ordering = NULL;
|
||||
struct context_order *co = NULL;
|
||||
char **ptr;
|
||||
int rc = 0;
|
||||
unsigned int nreach = 0, nordered = 0, freefrom = 0, i;
|
||||
unsigned nreachable = 0;
|
||||
char *backup_fromcon = NULL;
|
||||
FILE *fp;
|
||||
char *fname = NULL;
|
||||
size_t fname_len;
|
||||
|
@ -407,29 +418,12 @@ int get_ordered_context_list(const char *user,
|
|||
|
||||
if (!fromcon) {
|
||||
/* Get the current context and use it for the starting context */
|
||||
rc = getcon(&fromcon);
|
||||
rc = getcon(&backup_fromcon);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
freefrom = 1;
|
||||
fromcon = backup_fromcon;
|
||||
}
|
||||
|
||||
/* Determine the set of reachable contexts for the user. */
|
||||
rc = security_compute_user(fromcon, user, &reachable);
|
||||
if (rc < 0)
|
||||
goto failsafe;
|
||||
nreach = 0;
|
||||
for (ptr = reachable; *ptr; ptr++)
|
||||
nreach++;
|
||||
if (!nreach)
|
||||
goto failsafe;
|
||||
|
||||
/* Initialize ordering array. */
|
||||
ordering = malloc(nreach * sizeof(unsigned int));
|
||||
if (!ordering)
|
||||
goto failsafe;
|
||||
for (i = 0; i < nreach; i++)
|
||||
ordering[i] = nreach;
|
||||
|
||||
/* Determine the ordering to apply from the optional per-user config
|
||||
and from the global config. */
|
||||
fname_len = strlen(user_contexts_path) + strlen(user) + 2;
|
||||
|
@ -440,8 +434,8 @@ int get_ordered_context_list(const char *user,
|
|||
fp = fopen(fname, "re");
|
||||
if (fp) {
|
||||
__fsetlocking(fp, FSETLOCKING_BYCALLER);
|
||||
rc = get_context_order(fp, fromcon, reachable, nreach, ordering,
|
||||
&nordered);
|
||||
rc = get_context_user(fp, fromcon, user, &reachable, &nreachable);
|
||||
|
||||
fclose(fp);
|
||||
if (rc < 0 && errno != ENOENT) {
|
||||
fprintf(stderr,
|
||||
|
@ -454,8 +448,7 @@ int get_ordered_context_list(const char *user,
|
|||
fp = fopen(selinux_default_context_path(), "re");
|
||||
if (fp) {
|
||||
__fsetlocking(fp, FSETLOCKING_BYCALLER);
|
||||
rc = get_context_order(fp, fromcon, reachable, nreach, ordering,
|
||||
&nordered);
|
||||
rc = get_context_user(fp, fromcon, user, &reachable, &nreachable);
|
||||
fclose(fp);
|
||||
if (rc < 0 && errno != ENOENT) {
|
||||
fprintf(stderr,
|
||||
|
@ -463,42 +456,20 @@ int get_ordered_context_list(const char *user,
|
|||
__FUNCTION__, selinux_default_context_path());
|
||||
/* Fall through */
|
||||
}
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
if (!nordered)
|
||||
if (!nreachable)
|
||||
goto failsafe;
|
||||
|
||||
/* Apply the ordering. */
|
||||
co = malloc(nreach * sizeof(struct context_order));
|
||||
if (!co)
|
||||
goto failsafe;
|
||||
for (i = 0; i < nreach; i++) {
|
||||
co[i].con = reachable[i];
|
||||
co[i].order = ordering[i];
|
||||
}
|
||||
qsort(co, nreach, sizeof(struct context_order), order_compare);
|
||||
for (i = 0; i < nreach; i++)
|
||||
reachable[i] = co[i].con;
|
||||
free(co);
|
||||
|
||||
/* Only report the ordered entries to the caller. */
|
||||
if (nordered <= nreach) {
|
||||
for (i = nordered; i < nreach; i++)
|
||||
free(reachable[i]);
|
||||
reachable[nordered] = NULL;
|
||||
rc = nordered;
|
||||
}
|
||||
|
||||
out:
|
||||
if (rc > 0)
|
||||
if (nreachable > 0) {
|
||||
*list = reachable;
|
||||
rc = nreachable;
|
||||
}
|
||||
else
|
||||
freeconary(reachable);
|
||||
|
||||
free(ordering);
|
||||
if (freefrom)
|
||||
freecon(fromcon);
|
||||
freecon(backup_fromcon);
|
||||
|
||||
return rc;
|
||||
|
||||
|
@ -519,8 +490,7 @@ int get_ordered_context_list(const char *user,
|
|||
reachable = NULL;
|
||||
goto out;
|
||||
}
|
||||
rc = 1; /* one context in the list */
|
||||
nreachable = 1; /* one context in the list */
|
||||
goto out;
|
||||
}
|
||||
|
||||
hidden_def(get_ordered_context_list)
|
||||
|
|
|
@ -1,6 +1,2 @@
|
|||
#include <selinux/get_context_list.h>
|
||||
#include "dso.h"
|
||||
|
||||
hidden_proto(get_ordered_context_list)
|
||||
hidden_proto(get_ordered_context_list_with_level)
|
||||
hidden_proto(get_default_context_with_role)
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
#include <selinux/get_default_type.h>
|
||||
#include "dso.h"
|
||||
|
||||
hidden_proto(selinux_default_type_path)
|
||||
|
|
|
@ -53,7 +53,6 @@ int security_get_initial_context_raw(const char * name, char ** con)
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_get_initial_context_raw)
|
||||
|
||||
int security_get_initial_context(const char * name, char ** con)
|
||||
{
|
||||
|
@ -69,4 +68,3 @@ int security_get_initial_context(const char * name, char ** con)
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_get_initial_context)
|
||||
|
|
|
@ -37,4 +37,3 @@ int security_getenforce(void)
|
|||
return !!enforce;
|
||||
}
|
||||
|
||||
hidden_def(security_getenforce)
|
||||
|
|
|
@ -49,7 +49,6 @@ int getfilecon_raw(const char *path, char ** context)
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(getfilecon_raw)
|
||||
|
||||
int getfilecon(const char *path, char ** context)
|
||||
{
|
||||
|
@ -70,4 +69,3 @@ int getfilecon(const char *path, char ** context)
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(getfilecon)
|
||||
|
|
|
@ -43,7 +43,6 @@ int getpeercon_raw(int fd, char ** context)
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(getpeercon_raw)
|
||||
|
||||
int getpeercon(int fd, char ** context)
|
||||
{
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "dso.h"
|
||||
#include "policy.h"
|
||||
#include "selinux_internal.h"
|
||||
#include "setrans_internal.h"
|
||||
|
@ -79,7 +78,6 @@ int selinuxfs_exists(void)
|
|||
fclose(fp);
|
||||
return exists;
|
||||
}
|
||||
hidden_def(selinuxfs_exists)
|
||||
|
||||
static void init_selinuxmnt(void)
|
||||
{
|
||||
|
@ -138,14 +136,12 @@ void fini_selinuxmnt(void)
|
|||
selinux_mnt = NULL;
|
||||
}
|
||||
|
||||
hidden_def(fini_selinuxmnt)
|
||||
|
||||
void set_selinuxmnt(const char *mnt)
|
||||
{
|
||||
selinux_mnt = strdup(mnt);
|
||||
}
|
||||
|
||||
hidden_def(set_selinuxmnt)
|
||||
|
||||
static void init_lib(void) __attribute__ ((constructor));
|
||||
static void init_lib(void)
|
||||
|
|
|
@ -9,7 +9,10 @@
|
|||
#include "selinux_internal.h"
|
||||
#include "context_internal.h"
|
||||
|
||||
static int get_customizable_type_list(char *** retlist)
|
||||
static char **customizable_list = NULL;
|
||||
static pthread_once_t customizable_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
static void customizable_init(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char *buf;
|
||||
|
@ -18,12 +21,12 @@ static int get_customizable_type_list(char *** retlist)
|
|||
|
||||
fp = fopen(selinux_customizable_types_path(), "re");
|
||||
if (!fp)
|
||||
return -1;
|
||||
return;
|
||||
|
||||
buf = malloc(selinux_page_size);
|
||||
if (!buf) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
while (fgets_unlocked(buf, selinux_page_size, fp) && ctr < UINT_MAX) {
|
||||
ctr++;
|
||||
|
@ -38,7 +41,7 @@ static int get_customizable_type_list(char *** retlist)
|
|||
while (fgets_unlocked(buf, selinux_page_size, fp)
|
||||
&& i < ctr) {
|
||||
buf[strlen(buf) - 1] = 0;
|
||||
list[i] = (char *) strdup(buf);
|
||||
list[i] = strdup(buf);
|
||||
if (!list[i]) {
|
||||
unsigned int j;
|
||||
for (j = 0; j < i; j++)
|
||||
|
@ -54,23 +57,19 @@ static int get_customizable_type_list(char *** retlist)
|
|||
fclose(fp);
|
||||
free(buf);
|
||||
if (!list)
|
||||
return -1;
|
||||
*retlist = list;
|
||||
return 0;
|
||||
return;
|
||||
customizable_list = list;
|
||||
}
|
||||
|
||||
static char **customizable_list = NULL;
|
||||
|
||||
int is_context_customizable(const char * scontext)
|
||||
{
|
||||
int i;
|
||||
const char *type;
|
||||
context_t c;
|
||||
|
||||
if (!customizable_list) {
|
||||
if (get_customizable_type_list(&customizable_list) != 0)
|
||||
return -1;
|
||||
}
|
||||
__selinux_once(customizable_once, customizable_init);
|
||||
if (!customizable_list)
|
||||
return -1;
|
||||
|
||||
c = context_new(scontext);
|
||||
if (!c)
|
||||
|
|
|
@ -226,6 +226,8 @@ struct selabel_handle *selabel_open(unsigned int backend,
|
|||
rec->digest = selabel_is_digest_set(opts, nopts, rec->digest);
|
||||
|
||||
if ((*initfuncs[backend])(rec, opts, nopts)) {
|
||||
if (rec->digest)
|
||||
selabel_digest_fini(rec->digest);
|
||||
free(rec->spec_file);
|
||||
free(rec);
|
||||
rec = NULL;
|
||||
|
|
|
@ -93,11 +93,15 @@ static int process_line(struct selabel_handle *rec,
|
|||
|
||||
items = read_spec_entries(line_buf, &errbuf, 2, &prop, &context);
|
||||
if (items < 0) {
|
||||
items = errno;
|
||||
selinux_log(SELINUX_ERROR,
|
||||
"%s: line %u error due to: %s\n", path,
|
||||
lineno, errbuf ?: strerror(errno));
|
||||
errno = items;
|
||||
if (errbuf) {
|
||||
selinux_log(SELINUX_ERROR,
|
||||
"%s: line %u error due to: %s\n", path,
|
||||
lineno, errbuf);
|
||||
} else {
|
||||
selinux_log(SELINUX_ERROR,
|
||||
"%s: line %u error due to: %m\n", path,
|
||||
lineno);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -277,7 +277,7 @@ db_init(const struct selinux_opt *opts, unsigned nopts,
|
|||
if (!path)
|
||||
path = selinux_sepgsql_context_path();
|
||||
|
||||
if ((filp = fopen(path, "rb")) == NULL) {
|
||||
if ((filp = fopen(path, "re")) == NULL) {
|
||||
free(catalog);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -188,6 +188,9 @@ static int load_mmap(FILE *fp, size_t len, struct selabel_handle *rec,
|
|||
|
||||
str_buf[entry_len] = '\0';
|
||||
if ((strcmp(str_buf, reg_version) != 0)) {
|
||||
COMPAT_LOG(SELINUX_ERROR,
|
||||
"Regex version mismatch, expected: %s actual: %s\n",
|
||||
reg_version, str_buf);
|
||||
free(str_buf);
|
||||
return -1;
|
||||
}
|
||||
|
@ -371,7 +374,7 @@ end_arch_check:
|
|||
|
||||
if (stem_id < 0 || stem_id >= (int32_t)stem_map_len)
|
||||
spec->stem_id = -1;
|
||||
else
|
||||
else
|
||||
spec->stem_id = stem_map[stem_id];
|
||||
|
||||
/* retrieve the hasMetaChars bit */
|
||||
|
@ -756,6 +759,10 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (!path)
|
||||
goto finish;
|
||||
|
||||
rec->spec_file = strdup(path);
|
||||
|
||||
/*
|
||||
|
@ -845,7 +852,7 @@ static void closef(struct selabel_handle *rec)
|
|||
// Finds all the matches of |key| in the given context. Returns the result in
|
||||
// the allocated array and updates the match count. If match_count is NULL,
|
||||
// stops early once the 1st match is found.
|
||||
static const struct spec **lookup_all(struct selabel_handle *rec,
|
||||
static struct spec **lookup_all(struct selabel_handle *rec,
|
||||
const char *key,
|
||||
int type,
|
||||
bool partial,
|
||||
|
@ -854,13 +861,14 @@ static const struct spec **lookup_all(struct selabel_handle *rec,
|
|||
struct saved_data *data = (struct saved_data *)rec->data;
|
||||
struct spec *spec_arr = data->spec_arr;
|
||||
int i, rc, file_stem;
|
||||
size_t len;
|
||||
mode_t mode = (mode_t)type;
|
||||
char *clean_key = NULL;
|
||||
const char *prev_slash, *next_slash;
|
||||
unsigned int sofar = 0;
|
||||
char *sub = NULL;
|
||||
|
||||
const struct spec **result = NULL;
|
||||
struct spec **result = NULL;
|
||||
if (match_count) {
|
||||
*match_count = 0;
|
||||
result = calloc(data->nspec, sizeof(struct spec*));
|
||||
|
@ -894,6 +902,27 @@ static const struct spec **lookup_all(struct selabel_handle *rec,
|
|||
key = clean_key;
|
||||
}
|
||||
|
||||
/* remove trailing slash */
|
||||
len = strlen(key);
|
||||
if (len == 0) {
|
||||
errno = EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (len > 1 && key[len - 1] == '/') {
|
||||
/* reuse clean_key from above if available */
|
||||
if (!clean_key) {
|
||||
clean_key = (char *) malloc(len);
|
||||
if (!clean_key)
|
||||
goto finish;
|
||||
|
||||
memcpy(clean_key, key, len - 1);
|
||||
}
|
||||
|
||||
clean_key[len - 1] = '\0';
|
||||
key = clean_key;
|
||||
}
|
||||
|
||||
sub = selabel_sub_key(data, key);
|
||||
if (sub)
|
||||
key = sub;
|
||||
|
@ -922,7 +951,12 @@ static const struct spec **lookup_all(struct selabel_handle *rec,
|
|||
rc = regex_match(spec->regex, key, partial);
|
||||
if (rc == REGEX_MATCH || (partial && rc == REGEX_MATCH_PARTIAL)) {
|
||||
if (rc == REGEX_MATCH) {
|
||||
spec->matches++;
|
||||
#ifdef __ATOMIC_RELAXED
|
||||
__atomic_store_n(&spec->any_matches,
|
||||
true, __ATOMIC_RELAXED);
|
||||
#else
|
||||
#error "Please use a compiler that supports __atomic builtins"
|
||||
#endif
|
||||
}
|
||||
|
||||
if (strcmp(spec_arr[i].lr.ctx_raw, "<<none>>") == 0) {
|
||||
|
@ -948,6 +982,8 @@ static const struct spec **lookup_all(struct selabel_handle *rec,
|
|||
goto finish;
|
||||
}
|
||||
}
|
||||
if (!result[0])
|
||||
errno = ENOENT;
|
||||
|
||||
finish:
|
||||
free(clean_key);
|
||||
|
@ -963,11 +999,11 @@ static struct spec *lookup_common(struct selabel_handle *rec,
|
|||
const char *key,
|
||||
int type,
|
||||
bool partial) {
|
||||
const struct spec **matches = lookup_all(rec, key, type, partial, NULL);
|
||||
struct spec **matches = lookup_all(rec, key, type, partial, NULL);
|
||||
if (!matches) {
|
||||
return NULL;
|
||||
}
|
||||
struct spec *result = (struct spec*)matches[0];
|
||||
struct spec *result = matches[0];
|
||||
free(matches);
|
||||
return result;
|
||||
}
|
||||
|
@ -985,7 +1021,11 @@ static bool get_digests_all_partial_matches(struct selabel_handle *rec,
|
|||
{
|
||||
uint8_t read_digest[SHA1_HASH_SIZE];
|
||||
ssize_t read_size = getxattr(pathname, RESTORECON_PARTIAL_MATCH_DIGEST,
|
||||
read_digest, SHA1_HASH_SIZE);
|
||||
read_digest, SHA1_HASH_SIZE
|
||||
#ifdef __APPLE__
|
||||
, 0, 0
|
||||
#endif /* __APPLE __ */
|
||||
);
|
||||
uint8_t hash_digest[SHA1_HASH_SIZE];
|
||||
bool status = selabel_hash_all_partial_matches(rec, pathname,
|
||||
hash_digest);
|
||||
|
@ -1026,7 +1066,7 @@ static bool hash_all_partial_matches(struct selabel_handle *rec, const char *key
|
|||
assert(digest);
|
||||
|
||||
size_t total_matches;
|
||||
const struct spec **matches = lookup_all(rec, key, 0, true, &total_matches);
|
||||
struct spec **matches = lookup_all(rec, key, 0, true, &total_matches);
|
||||
if (!matches) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1214,9 +1254,15 @@ static void stats(struct selabel_handle *rec)
|
|||
struct saved_data *data = (struct saved_data *)rec->data;
|
||||
unsigned int i, nspec = data->nspec;
|
||||
struct spec *spec_arr = data->spec_arr;
|
||||
bool any_matches;
|
||||
|
||||
for (i = 0; i < nspec; i++) {
|
||||
if (spec_arr[i].matches == 0) {
|
||||
#ifdef __ATOMIC_RELAXED
|
||||
any_matches = __atomic_load_n(&spec_arr[i].any_matches, __ATOMIC_RELAXED);
|
||||
#else
|
||||
#error "Please use a compiler that supports __atomic builtins"
|
||||
#endif
|
||||
if (!any_matches) {
|
||||
if (spec_arr[i].type_str) {
|
||||
COMPAT_LOG(SELINUX_WARNING,
|
||||
"Warning! No matches for (%s, %s, %s)\n",
|
||||
|
|
|
@ -51,7 +51,7 @@ struct spec {
|
|||
bool regex_compiled; /* bool to indicate if the regex is compiled */
|
||||
pthread_mutex_t regex_lock; /* lock for lazy compilation of regex */
|
||||
mode_t mode; /* mode format value */
|
||||
int matches; /* number of matching pathnames */
|
||||
bool any_matches; /* did any pathname match? */
|
||||
int stem_id; /* indicates which stem-compression item */
|
||||
char hasMetaChars; /* regular expression has meta-chars */
|
||||
char from_mmap; /* this spec is from an mmap of the data */
|
||||
|
@ -286,7 +286,6 @@ static inline int store_stem(struct saved_data *data, char *buf, int stem_len)
|
|||
tmp_arr = realloc(data->stem_arr,
|
||||
sizeof(*tmp_arr) * alloc_stems);
|
||||
if (!tmp_arr) {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
data->alloc_stems = alloc_stems;
|
||||
|
@ -308,6 +307,7 @@ static inline int find_stem_from_spec(struct saved_data *data, const char *buf)
|
|||
int stem_len = get_stem_from_spec(buf);
|
||||
int stemid;
|
||||
char *stem;
|
||||
int r;
|
||||
|
||||
if (!stem_len)
|
||||
return -1;
|
||||
|
@ -321,7 +321,11 @@ static inline int find_stem_from_spec(struct saved_data *data, const char *buf)
|
|||
if (!stem)
|
||||
return -1;
|
||||
|
||||
return store_stem(data, stem, stem_len);
|
||||
r = store_stem(data, stem, stem_len);
|
||||
if (r < 0)
|
||||
free(stem);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* This will always check for buffer over-runs and either read the next entry
|
||||
|
@ -440,11 +444,15 @@ static inline int process_line(struct selabel_handle *rec,
|
|||
|
||||
items = read_spec_entries(line_buf, &errbuf, 3, ®ex, &type, &context);
|
||||
if (items < 0) {
|
||||
rc = errno;
|
||||
selinux_log(SELINUX_ERROR,
|
||||
"%s: line %u error due to: %s\n", path,
|
||||
lineno, errbuf ?: strerror(errno));
|
||||
errno = rc;
|
||||
if (errbuf) {
|
||||
selinux_log(SELINUX_ERROR,
|
||||
"%s: line %u error due to: %s\n", path,
|
||||
lineno, errbuf);
|
||||
} else {
|
||||
selinux_log(SELINUX_ERROR,
|
||||
"%s: line %u error due to: %m\n", path,
|
||||
lineno);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <stdio.h>
|
||||
#include <selinux/selinux.h>
|
||||
#include <selinux/label.h>
|
||||
#include "dso.h"
|
||||
#include "sha1.h"
|
||||
|
||||
#if defined(ANDROID) || defined(__APPLE__)
|
||||
|
@ -26,22 +25,22 @@
|
|||
*/
|
||||
int selabel_file_init(struct selabel_handle *rec,
|
||||
const struct selinux_opt *opts,
|
||||
unsigned nopts) hidden;
|
||||
unsigned nopts) ;
|
||||
int selabel_media_init(struct selabel_handle *rec,
|
||||
const struct selinux_opt *opts,
|
||||
unsigned nopts) hidden;
|
||||
unsigned nopts) ;
|
||||
int selabel_x_init(struct selabel_handle *rec,
|
||||
const struct selinux_opt *opts,
|
||||
unsigned nopts) hidden;
|
||||
unsigned nopts) ;
|
||||
int selabel_db_init(struct selabel_handle *rec,
|
||||
const struct selinux_opt *opts,
|
||||
unsigned nopts) hidden;
|
||||
unsigned nopts) ;
|
||||
int selabel_property_init(struct selabel_handle *rec,
|
||||
const struct selinux_opt *opts,
|
||||
unsigned nopts) hidden;
|
||||
unsigned nopts) ;
|
||||
int selabel_service_init(struct selabel_handle *rec,
|
||||
const struct selinux_opt *opts,
|
||||
unsigned nopts) hidden;
|
||||
unsigned nopts) ;
|
||||
|
||||
/*
|
||||
* Labeling internal structures
|
||||
|
@ -120,24 +119,26 @@ struct selabel_handle {
|
|||
*/
|
||||
extern int
|
||||
selabel_validate(struct selabel_handle *rec,
|
||||
struct selabel_lookup_rec *contexts) hidden;
|
||||
struct selabel_lookup_rec *contexts) ;
|
||||
|
||||
/*
|
||||
* Compatibility support
|
||||
*/
|
||||
extern int myprintf_compat;
|
||||
extern void __attribute__ ((format(printf, 1, 2)))
|
||||
(*myprintf) (const char *fmt, ...) hidden;
|
||||
(*myprintf) (const char *fmt, ...) ;
|
||||
|
||||
#define COMPAT_LOG(type, fmt...) if (myprintf_compat) \
|
||||
myprintf(fmt); \
|
||||
else \
|
||||
selinux_log(type, fmt);
|
||||
#define COMPAT_LOG(type, fmt...) do { \
|
||||
if (myprintf_compat) \
|
||||
myprintf(fmt); \
|
||||
else \
|
||||
selinux_log(type, fmt); \
|
||||
} while (0)
|
||||
|
||||
extern int
|
||||
compat_validate(struct selabel_handle *rec,
|
||||
struct selabel_lookup_rec *contexts,
|
||||
const char *path, unsigned lineno) hidden;
|
||||
const char *path, unsigned lineno) ;
|
||||
|
||||
/*
|
||||
* The read_spec_entries function may be used to
|
||||
|
|
|
@ -95,10 +95,10 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
|
|||
__fsetlocking(fp, FSETLOCKING_BYCALLER);
|
||||
|
||||
if (fstat(fileno(fp), &sb) < 0)
|
||||
return -1;
|
||||
goto finish;
|
||||
if (!S_ISREG(sb.st_mode)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
goto finish;
|
||||
}
|
||||
rec->spec_file = strdup(path);
|
||||
|
||||
|
@ -119,7 +119,6 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
|
|||
if (process_line(path, line_buf, pass, ++lineno, rec))
|
||||
goto finish;
|
||||
}
|
||||
lineno = 0;
|
||||
|
||||
if (pass == 0) {
|
||||
if (data->nspec == 0) {
|
||||
|
|
|
@ -63,7 +63,7 @@ static inline int read_spec_entry(char **entry, char **ptr, int *len, const char
|
|||
* This function calls read_spec_entry() to do the actual string processing.
|
||||
* As such, can return anything from that function as well.
|
||||
*/
|
||||
int hidden read_spec_entries(char *line_buf, const char **errbuf, int num_args, ...)
|
||||
int read_spec_entries(char *line_buf, const char **errbuf, int num_args, ...)
|
||||
{
|
||||
char **spec_entry, *buf_p;
|
||||
int len, rc, items, entry_len = 0;
|
||||
|
@ -113,16 +113,28 @@ int hidden read_spec_entries(char *line_buf, const char **errbuf, int num_args,
|
|||
}
|
||||
|
||||
/* Once all the specfiles are in the hash_buf, generate the hash. */
|
||||
void hidden digest_gen_hash(struct selabel_digest *digest)
|
||||
void digest_gen_hash(struct selabel_digest *digest)
|
||||
{
|
||||
Sha1Context context;
|
||||
size_t remaining_size;
|
||||
const unsigned char *ptr;
|
||||
|
||||
/* If SELABEL_OPT_DIGEST not set then just return */
|
||||
if (!digest)
|
||||
return;
|
||||
|
||||
Sha1Initialise(&context);
|
||||
Sha1Update(&context, digest->hashbuf, digest->hashbuf_size);
|
||||
|
||||
/* Process in blocks of UINT32_MAX bytes */
|
||||
remaining_size = digest->hashbuf_size;
|
||||
ptr = digest->hashbuf;
|
||||
while (remaining_size > UINT32_MAX) {
|
||||
Sha1Update(&context, ptr, UINT32_MAX);
|
||||
remaining_size -= UINT32_MAX;
|
||||
ptr += UINT32_MAX;
|
||||
}
|
||||
Sha1Update(&context, ptr, remaining_size);
|
||||
|
||||
Sha1Finalise(&context, (SHA1_HASH *)digest->digest);
|
||||
free(digest->hashbuf);
|
||||
digest->hashbuf = NULL;
|
||||
|
@ -141,7 +153,7 @@ void hidden digest_gen_hash(struct selabel_digest *digest)
|
|||
*
|
||||
* Return %0 on success, -%1 with @errno set on failure.
|
||||
*/
|
||||
int hidden digest_add_specfile(struct selabel_digest *digest, FILE *fp,
|
||||
int digest_add_specfile(struct selabel_digest *digest, FILE *fp,
|
||||
char *from_addr, size_t buf_len,
|
||||
const char *path)
|
||||
{
|
||||
|
|
|
@ -122,10 +122,10 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
|
|||
__fsetlocking(fp, FSETLOCKING_BYCALLER);
|
||||
|
||||
if (fstat(fileno(fp), &sb) < 0)
|
||||
return -1;
|
||||
goto finish;
|
||||
if (!S_ISREG(sb.st_mode)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
goto finish;
|
||||
}
|
||||
rec->spec_file = strdup(path);
|
||||
|
||||
|
@ -146,7 +146,6 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
|
|||
if (process_line(path, line_buf, pass, ++lineno, rec))
|
||||
goto finish;
|
||||
}
|
||||
lineno = 0;
|
||||
|
||||
if (pass == 0) {
|
||||
if (data->nspec == 0) {
|
||||
|
|
|
@ -49,7 +49,6 @@ int lgetfilecon_raw(const char *path, char ** context)
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(lgetfilecon_raw)
|
||||
|
||||
int lgetfilecon(const char *path, char ** context)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,248 @@
|
|||
LIBSELINUX_1.0 {
|
||||
global:
|
||||
avc_add_callback;
|
||||
avc_audit;
|
||||
avc_av_stats;
|
||||
avc_cache_stats;
|
||||
avc_cleanup;
|
||||
avc_compute_create;
|
||||
avc_compute_member;
|
||||
avc_context_to_sid;
|
||||
avc_context_to_sid_raw;
|
||||
avc_destroy;
|
||||
avc_get_initial_sid;
|
||||
avc_has_perm;
|
||||
avc_has_perm_noaudit;
|
||||
avc_init;
|
||||
avc_netlink_acquire_fd;
|
||||
avc_netlink_check_nb;
|
||||
avc_netlink_close;
|
||||
avc_netlink_loop;
|
||||
avc_netlink_open;
|
||||
avc_netlink_release_fd;
|
||||
avc_open;
|
||||
avc_reset;
|
||||
avc_sid_stats;
|
||||
avc_sid_to_context;
|
||||
avc_sid_to_context_raw;
|
||||
checkPasswdAccess;
|
||||
context_free;
|
||||
context_new;
|
||||
context_range_get;
|
||||
context_range_set;
|
||||
context_role_get;
|
||||
context_role_set;
|
||||
context_str;
|
||||
context_type_get;
|
||||
context_type_set;
|
||||
context_user_get;
|
||||
context_user_set;
|
||||
fgetfilecon;
|
||||
fgetfilecon_raw;
|
||||
fini_selinuxmnt;
|
||||
freecon;
|
||||
freeconary;
|
||||
fsetfilecon;
|
||||
fsetfilecon_raw;
|
||||
getcon;
|
||||
getcon_raw;
|
||||
get_default_context;
|
||||
get_default_context_with_level;
|
||||
get_default_context_with_role;
|
||||
get_default_context_with_rolelevel;
|
||||
get_default_type;
|
||||
getexeccon;
|
||||
getexeccon_raw;
|
||||
getfilecon;
|
||||
getfilecon_raw;
|
||||
getfscreatecon;
|
||||
getfscreatecon_raw;
|
||||
getkeycreatecon;
|
||||
getkeycreatecon_raw;
|
||||
get_ordered_context_list;
|
||||
get_ordered_context_list_with_level;
|
||||
getpeercon;
|
||||
getpeercon_raw;
|
||||
getpidcon;
|
||||
getpidcon_raw;
|
||||
getprevcon;
|
||||
getprevcon_raw;
|
||||
getseuser;
|
||||
getseuserbyname;
|
||||
getsockcreatecon;
|
||||
getsockcreatecon_raw;
|
||||
is_context_customizable;
|
||||
is_selinux_enabled;
|
||||
is_selinux_mls_enabled;
|
||||
lgetfilecon;
|
||||
lgetfilecon_raw;
|
||||
lsetfilecon;
|
||||
lsetfilecon_raw;
|
||||
manual_user_enter_context;
|
||||
matchmediacon;
|
||||
matchpathcon;
|
||||
matchpathcon_checkmatches;
|
||||
matchpathcon_filespec_add;
|
||||
matchpathcon_filespec_destroy;
|
||||
matchpathcon_filespec_eval;
|
||||
matchpathcon_fini;
|
||||
matchpathcon_index;
|
||||
matchpathcon_init;
|
||||
matchpathcon_init_prefix;
|
||||
mode_to_security_class;
|
||||
print_access_vector;
|
||||
query_user_context;
|
||||
realpath_not_final;
|
||||
rpm_execcon;
|
||||
security_av_perm_to_string;
|
||||
security_av_string;
|
||||
security_canonicalize_context;
|
||||
security_canonicalize_context_raw;
|
||||
security_check_context;
|
||||
security_check_context_raw;
|
||||
security_class_to_string;
|
||||
security_commit_booleans;
|
||||
security_compute_av;
|
||||
security_compute_av_flags;
|
||||
security_compute_av_flags_raw;
|
||||
security_compute_av_raw;
|
||||
security_compute_create;
|
||||
security_compute_create_name;
|
||||
security_compute_create_name_raw;
|
||||
security_compute_create_raw;
|
||||
security_compute_member;
|
||||
security_compute_member_raw;
|
||||
security_compute_relabel;
|
||||
security_compute_relabel_raw;
|
||||
security_compute_user;
|
||||
security_compute_user_raw;
|
||||
security_deny_unknown;
|
||||
security_disable;
|
||||
security_get_boolean_active;
|
||||
security_get_boolean_names;
|
||||
security_get_boolean_pending;
|
||||
security_get_checkreqprot;
|
||||
security_getenforce;
|
||||
security_get_initial_context;
|
||||
security_get_initial_context_raw;
|
||||
security_load_booleans;
|
||||
security_load_policy;
|
||||
security_policyvers;
|
||||
security_reject_unknown;
|
||||
security_set_boolean;
|
||||
security_set_boolean_list;
|
||||
security_setenforce;
|
||||
security_validatetrans;
|
||||
security_validatetrans_raw;
|
||||
selabel_close;
|
||||
selabel_cmp;
|
||||
selabel_digest;
|
||||
selabel_get_digests_all_partial_matches;
|
||||
selabel_hash_all_partial_matches;
|
||||
selabel_lookup;
|
||||
selabel_lookup_best_match;
|
||||
selabel_lookup_best_match_raw;
|
||||
selabel_lookup_raw;
|
||||
selabel_open;
|
||||
selabel_partial_match;
|
||||
selabel_stats;
|
||||
selinux_binary_policy_path;
|
||||
selinux_booleans_path;
|
||||
selinux_booleans_subs_path;
|
||||
selinux_boolean_sub;
|
||||
selinux_check_access;
|
||||
selinux_check_passwd_access;
|
||||
selinux_check_securetty_context;
|
||||
selinux_colors_path;
|
||||
selinux_contexts_path;
|
||||
selinux_current_policy_path;
|
||||
selinux_customizable_types_path;
|
||||
selinux_default_context_path;
|
||||
selinux_default_type_path;
|
||||
selinux_failsafe_context_path;
|
||||
selinux_file_context_cmp;
|
||||
selinux_file_context_homedir_path;
|
||||
selinux_file_context_local_path;
|
||||
selinux_file_context_path;
|
||||
selinux_file_context_subs_dist_path;
|
||||
selinux_file_context_subs_path;
|
||||
selinux_file_context_verify;
|
||||
selinux_flush_class_cache;
|
||||
selinuxfs_exists;
|
||||
selinux_get_callback;
|
||||
selinux_getenforcemode;
|
||||
selinux_getpolicytype;
|
||||
selinux_homedir_context_path;
|
||||
selinux_init_load_policy;
|
||||
selinux_lsetfilecon_default;
|
||||
selinux_lxc_contexts_path;
|
||||
selinux_media_context_path;
|
||||
selinux_mkload_policy;
|
||||
selinux_mnt;
|
||||
selinux_netfilter_context_path;
|
||||
selinux_openrc_contexts_path;
|
||||
selinux_openssh_contexts_path;
|
||||
selinux_path;
|
||||
selinux_policy_root;
|
||||
selinux_raw_context_to_color;
|
||||
selinux_raw_to_trans_context;
|
||||
selinux_removable_context_path;
|
||||
selinux_reset_config;
|
||||
selinux_restorecon;
|
||||
selinux_restorecon_default_handle;
|
||||
selinux_restorecon_set_alt_rootpath;
|
||||
selinux_restorecon_set_exclude_list;
|
||||
selinux_restorecon_set_sehandle;
|
||||
selinux_restorecon_xattr;
|
||||
selinux_securetty_types_path;
|
||||
selinux_sepgsql_context_path;
|
||||
selinux_set_callback;
|
||||
selinux_set_mapping;
|
||||
selinux_set_policy_root;
|
||||
selinux_snapperd_contexts_path;
|
||||
selinux_status_close;
|
||||
selinux_status_deny_unknown;
|
||||
selinux_status_getenforce;
|
||||
selinux_status_open;
|
||||
selinux_status_policyload;
|
||||
selinux_status_updated;
|
||||
selinux_systemd_contexts_path;
|
||||
selinux_translations_path;
|
||||
selinux_trans_to_raw_context;
|
||||
selinux_user_contexts_path;
|
||||
selinux_usersconf_path;
|
||||
selinux_users_path;
|
||||
selinux_virtual_domain_context_path;
|
||||
selinux_virtual_image_context_path;
|
||||
selinux_x_context_path;
|
||||
setcon;
|
||||
setcon_raw;
|
||||
setexeccon;
|
||||
setexeccon_raw;
|
||||
setexecfilecon;
|
||||
setfilecon;
|
||||
setfilecon_raw;
|
||||
setfscreatecon;
|
||||
setfscreatecon_raw;
|
||||
setkeycreatecon;
|
||||
setkeycreatecon_raw;
|
||||
set_matchpathcon_canoncon;
|
||||
set_matchpathcon_flags;
|
||||
set_matchpathcon_invalidcon;
|
||||
set_matchpathcon_printf;
|
||||
set_selinuxmnt;
|
||||
setsockcreatecon;
|
||||
setsockcreatecon_raw;
|
||||
sidget;
|
||||
sidput;
|
||||
string_to_av_perm;
|
||||
string_to_security_class;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
LIBSELINUX_3.4 {
|
||||
global:
|
||||
selinux_restorecon_get_skipped_errors;
|
||||
selinux_restorecon_parallel;
|
||||
} LIBSELINUX_1.0;
|
|
@ -45,7 +45,6 @@ int security_load_policy(void *data, size_t len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
hidden_def(security_load_policy)
|
||||
|
||||
#ifndef ANDROID
|
||||
#undef max
|
||||
|
@ -77,11 +76,11 @@ int selinux_mkload_policy(int preservebools __attribute__((unused)))
|
|||
#ifdef SHARED
|
||||
char *errormsg = NULL;
|
||||
void *libsepolh = NULL;
|
||||
libsepolh = dlopen("libsepol.so.1", RTLD_NOW);
|
||||
libsepolh = dlopen("libsepol.so.2", RTLD_NOW);
|
||||
if (libsepolh) {
|
||||
usesepol = 1;
|
||||
dlerror();
|
||||
#define DLERR() if ((errormsg = dlerror())) goto dlclose;
|
||||
#define DLERR() do { if ((errormsg = dlerror())) goto dlclose; } while (0)
|
||||
vers_max = dlsym(libsepolh, "sepol_policy_kern_vers_max");
|
||||
DLERR();
|
||||
vers_min = dlsym(libsepolh, "sepol_policy_kern_vers_min");
|
||||
|
@ -138,15 +137,15 @@ int selinux_mkload_policy(int preservebools __attribute__((unused)))
|
|||
}
|
||||
if (fd < 0) {
|
||||
fprintf(stderr,
|
||||
"SELinux: Could not open policy file <= %s.%d: %s\n",
|
||||
selinux_binary_policy_path(), maxvers, strerror(errno));
|
||||
"SELinux: Could not open policy file <= %s.%d: %m\n",
|
||||
selinux_binary_policy_path(), maxvers);
|
||||
goto dlclose;
|
||||
}
|
||||
|
||||
if (fstat(fd, &sb) < 0) {
|
||||
fprintf(stderr,
|
||||
"SELinux: Could not stat policy file %s: %s\n",
|
||||
path, strerror(errno));
|
||||
"SELinux: Could not stat policy file %s: %m\n",
|
||||
path);
|
||||
goto close;
|
||||
}
|
||||
|
||||
|
@ -154,8 +153,8 @@ int selinux_mkload_policy(int preservebools __attribute__((unused)))
|
|||
data = map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (map == MAP_FAILED) {
|
||||
fprintf(stderr,
|
||||
"SELinux: Could not map policy file %s: %s\n",
|
||||
path, strerror(errno));
|
||||
"SELinux: Could not map policy file %s: %m\n",
|
||||
path);
|
||||
goto close;
|
||||
}
|
||||
|
||||
|
@ -194,8 +193,8 @@ int selinux_mkload_policy(int preservebools __attribute__((unused)))
|
|||
|
||||
if (rc)
|
||||
fprintf(stderr,
|
||||
"SELinux: Could not load policy file %s: %s\n",
|
||||
path, strerror(errno));
|
||||
"SELinux: Could not load policy file %s: %m\n",
|
||||
path);
|
||||
|
||||
unmap:
|
||||
if (data != map)
|
||||
|
@ -213,7 +212,6 @@ int selinux_mkload_policy(int preservebools __attribute__((unused)))
|
|||
return rc;
|
||||
}
|
||||
|
||||
hidden_def(selinux_mkload_policy)
|
||||
|
||||
/*
|
||||
* Mount point for selinuxfs.
|
||||
|
@ -281,7 +279,8 @@ int selinux_init_load_policy(int *enforce)
|
|||
const char *mntpoint = NULL;
|
||||
/* First make sure /sys is mounted */
|
||||
if (mount("sysfs", "/sys", "sysfs", 0, 0) == 0 || errno == EBUSY) {
|
||||
if (mount(SELINUXFS, SELINUXMNT, SELINUXFS, 0, 0) == 0 || errno == EBUSY) {
|
||||
/* MS_NODEV can't be set because of /sys/fs/selinux/null device, used by Android */
|
||||
if (mount(SELINUXFS, SELINUXMNT, SELINUXFS, MS_NOEXEC | MS_NOSUID, 0) == 0 || errno == EBUSY) {
|
||||
mntpoint = SELINUXMNT;
|
||||
} else {
|
||||
/* check old mountpoint */
|
||||
|
@ -307,7 +306,7 @@ int selinux_init_load_policy(int *enforce)
|
|||
*enforce = 0;
|
||||
} else {
|
||||
/* Only emit this error if selinux was not disabled */
|
||||
fprintf(stderr, "Mount failed for selinuxfs on %s: %s\n", SELINUXMNT, strerror(errno));
|
||||
fprintf(stderr, "Mount failed for selinuxfs on %s: %m\n", SELINUXMNT);
|
||||
}
|
||||
|
||||
if (rc == 0)
|
||||
|
@ -353,7 +352,7 @@ int selinux_init_load_policy(int *enforce)
|
|||
if (orig_enforce != *enforce) {
|
||||
rc = security_setenforce(*enforce);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "SELinux: Unable to switch to %s mode: %s\n", (*enforce ? "enforcing" : "permissive"), strerror(errno));
|
||||
fprintf(stderr, "SELinux: Unable to switch to %s mode: %m\n", (*enforce ? "enforcing" : "permissive"));
|
||||
if (*enforce)
|
||||
goto noload;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ int lsetfilecon_raw(const char *path, const char * context)
|
|||
return rc;
|
||||
}
|
||||
|
||||
hidden_def(lsetfilecon_raw)
|
||||
|
||||
int lsetfilecon(const char *path, const char *context)
|
||||
{
|
||||
|
|
|
@ -144,9 +144,9 @@ unmap_perm(security_class_t tclass, access_vector_t tperm)
|
|||
access_vector_t kperm = 0;
|
||||
|
||||
for (i = 0; i < current_mapping[tclass].num_perms; i++)
|
||||
if (tperm & (1<<i)) {
|
||||
if (tperm & (UINT32_C(1)<<i)) {
|
||||
kperm |= current_mapping[tclass].perms[i];
|
||||
tperm &= ~(1<<i);
|
||||
tperm &= ~(UINT32_C(1)<<i);
|
||||
}
|
||||
return kperm;
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ map_perm(security_class_t tclass, access_vector_t kperm)
|
|||
|
||||
for (i = 0; i < current_mapping[tclass].num_perms; i++)
|
||||
if (kperm & current_mapping[tclass].perms[i]) {
|
||||
tperm |= 1<<i;
|
||||
tperm |= UINT32_C(1)<<i;
|
||||
kperm &= ~current_mapping[tclass].perms[i];
|
||||
}
|
||||
|
||||
|
@ -216,30 +216,30 @@ map_decision(security_class_t tclass, struct av_decision *avd)
|
|||
|
||||
for (i = 0, result = 0; i < n; i++) {
|
||||
if (avd->allowed & mapping->perms[i])
|
||||
result |= 1<<i;
|
||||
result |= UINT32_C(1)<<i;
|
||||
else if (allow_unknown && !mapping->perms[i])
|
||||
result |= 1<<i;
|
||||
result |= UINT32_C(1)<<i;
|
||||
}
|
||||
avd->allowed = result;
|
||||
|
||||
for (i = 0, result = 0; i < n; i++) {
|
||||
if (avd->decided & mapping->perms[i])
|
||||
result |= 1<<i;
|
||||
result |= UINT32_C(1)<<i;
|
||||
else if (allow_unknown && !mapping->perms[i])
|
||||
result |= 1<<i;
|
||||
result |= UINT32_C(1)<<i;
|
||||
}
|
||||
avd->decided = result;
|
||||
|
||||
for (i = 0, result = 0; i < n; i++)
|
||||
if (avd->auditallow & mapping->perms[i])
|
||||
result |= 1<<i;
|
||||
result |= UINT32_C(1)<<i;
|
||||
avd->auditallow = result;
|
||||
|
||||
for (i = 0, result = 0; i < n; i++) {
|
||||
if (avd->auditdeny & mapping->perms[i])
|
||||
result |= 1<<i;
|
||||
result |= UINT32_C(1)<<i;
|
||||
else if (!allow_unknown && !mapping->perms[i])
|
||||
result |= 1<<i;
|
||||
result |= UINT32_C(1)<<i;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -248,7 +248,7 @@ map_decision(security_class_t tclass, struct av_decision *avd)
|
|||
* a bug in the object manager.
|
||||
*/
|
||||
for (; i < (sizeof(result)*8); i++)
|
||||
result |= 1<<i;
|
||||
result |= UINT32_C(1)<<i;
|
||||
avd->auditdeny = result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ int matchmediacon(const char *media, char ** con)
|
|||
return -1;
|
||||
while (!feof_unlocked(infile)) {
|
||||
if (!fgets_unlocked(current_line, sizeof(current_line), infile)) {
|
||||
fclose(infile);
|
||||
return -1;
|
||||
}
|
||||
if (current_line[strlen(current_line) - 1])
|
||||
|
|
|
@ -78,17 +78,30 @@ static pthread_once_t once = PTHREAD_ONCE_INIT;
|
|||
static pthread_key_t destructor_key;
|
||||
static int destructor_key_initialized = 0;
|
||||
|
||||
static void free_array_elts(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < con_array_used; i++)
|
||||
free(con_array[i]);
|
||||
free(con_array);
|
||||
|
||||
con_array_size = con_array_used = 0;
|
||||
con_array = NULL;
|
||||
}
|
||||
|
||||
static int add_array_elt(char *con)
|
||||
{
|
||||
char **tmp;
|
||||
if (con_array_size) {
|
||||
while (con_array_used >= con_array_size) {
|
||||
con_array_size *= 2;
|
||||
con_array = (char **)realloc(con_array, sizeof(char*) *
|
||||
tmp = (char **)realloc(con_array, sizeof(char*) *
|
||||
con_array_size);
|
||||
if (!con_array) {
|
||||
con_array_size = con_array_used = 0;
|
||||
if (!tmp) {
|
||||
free_array_elts();
|
||||
return -1;
|
||||
}
|
||||
con_array = tmp;
|
||||
}
|
||||
} else {
|
||||
con_array_size = 1000;
|
||||
|
@ -105,13 +118,6 @@ static int add_array_elt(char *con)
|
|||
return con_array_used++;
|
||||
}
|
||||
|
||||
static void free_array_elts(void)
|
||||
{
|
||||
con_array_size = con_array_used = 0;
|
||||
free(con_array);
|
||||
con_array = NULL;
|
||||
}
|
||||
|
||||
void set_matchpathcon_invalidcon(int (*f) (const char *p, unsigned l, char *c))
|
||||
{
|
||||
myinvalidcon = f;
|
||||
|
@ -315,14 +321,24 @@ void matchpathcon_filespec_destroy(void)
|
|||
fl_head = NULL;
|
||||
}
|
||||
|
||||
static void matchpathcon_fini_internal(void)
|
||||
{
|
||||
free_array_elts();
|
||||
|
||||
if (hnd) {
|
||||
selabel_close(hnd);
|
||||
hnd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void matchpathcon_thread_destructor(void __attribute__((unused)) *ptr)
|
||||
{
|
||||
matchpathcon_fini();
|
||||
matchpathcon_fini_internal();
|
||||
}
|
||||
|
||||
void __attribute__((destructor)) matchpathcon_lib_destructor(void);
|
||||
|
||||
void hidden __attribute__((destructor)) matchpathcon_lib_destructor(void)
|
||||
void __attribute__((destructor)) matchpathcon_lib_destructor(void)
|
||||
{
|
||||
if (destructor_key_initialized)
|
||||
__selinux_key_delete(destructor_key);
|
||||
|
@ -340,7 +356,7 @@ int matchpathcon_init_prefix(const char *path, const char *subset)
|
|||
mycanoncon = default_canoncon;
|
||||
|
||||
__selinux_once(once, matchpathcon_init_once);
|
||||
__selinux_setspecific(destructor_key, (void *)1);
|
||||
__selinux_setspecific(destructor_key, /* some valid address to please GCC */ &selinux_page_size);
|
||||
|
||||
options[SELABEL_OPT_SUBSET].type = SELABEL_OPT_SUBSET;
|
||||
options[SELABEL_OPT_SUBSET].value = subset;
|
||||
|
@ -351,7 +367,6 @@ int matchpathcon_init_prefix(const char *path, const char *subset)
|
|||
return hnd ? 0 : -1;
|
||||
}
|
||||
|
||||
hidden_def(matchpathcon_init_prefix)
|
||||
|
||||
int matchpathcon_init(const char *path)
|
||||
{
|
||||
|
@ -360,12 +375,7 @@ int matchpathcon_init(const char *path)
|
|||
|
||||
void matchpathcon_fini(void)
|
||||
{
|
||||
free_array_elts();
|
||||
|
||||
if (hnd) {
|
||||
selabel_close(hnd);
|
||||
hnd = NULL;
|
||||
}
|
||||
matchpathcon_fini_internal();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -383,8 +393,8 @@ int realpath_not_final(const char *name, char *resolved_path)
|
|||
|
||||
tmp_path = strdup(name);
|
||||
if (!tmp_path) {
|
||||
myprintf("symlink_realpath(%s) strdup() failed: %s\n",
|
||||
name, strerror(errno));
|
||||
myprintf("symlink_realpath(%s) strdup() failed: %m\n",
|
||||
name);
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
@ -404,8 +414,8 @@ int realpath_not_final(const char *name, char *resolved_path)
|
|||
}
|
||||
|
||||
if (!p) {
|
||||
myprintf("symlink_realpath(%s) realpath() failed: %s\n",
|
||||
name, strerror(errno));
|
||||
myprintf("symlink_realpath(%s) realpath() failed: %m\n",
|
||||
name);
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
@ -428,7 +438,7 @@ out:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int matchpathcon(const char *path, mode_t mode, char ** con)
|
||||
static int matchpathcon_internal(const char *path, mode_t mode, char ** con)
|
||||
{
|
||||
char stackpath[PATH_MAX + 1];
|
||||
char *p = NULL;
|
||||
|
@ -449,9 +459,13 @@ int matchpathcon(const char *path, mode_t mode, char ** con)
|
|||
selabel_lookup(hnd, con, path, mode);
|
||||
}
|
||||
|
||||
int matchpathcon(const char *path, mode_t mode, char ** con) {
|
||||
return matchpathcon_internal(path, mode, con);
|
||||
}
|
||||
|
||||
int matchpathcon_index(const char *name, mode_t mode, char ** con)
|
||||
{
|
||||
int i = matchpathcon(name, mode, con);
|
||||
int i = matchpathcon_internal(name, mode, con);
|
||||
|
||||
if (i < 0)
|
||||
return -1;
|
||||
|
@ -469,15 +483,15 @@ void matchpathcon_checkmatches(char *str __attribute__((unused)))
|
|||
int selinux_file_context_cmp(const char * a,
|
||||
const char * b)
|
||||
{
|
||||
char *rest_a, *rest_b; /* Rest of the context after the user */
|
||||
const char *rest_a, *rest_b; /* Rest of the context after the user */
|
||||
if (!a && !b)
|
||||
return 0;
|
||||
if (!a)
|
||||
return -1;
|
||||
if (!b)
|
||||
return 1;
|
||||
rest_a = strchr((char *)a, ':');
|
||||
rest_b = strchr((char *)b, ':');
|
||||
rest_a = strchr(a, ':');
|
||||
rest_b = strchr(b, ':');
|
||||
if (!rest_a && !rest_b)
|
||||
return 0;
|
||||
if (!rest_a)
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "selinux_internal.h"
|
||||
#include <stdio.h>
|
||||
#include "policy.h"
|
||||
#include "dso.h"
|
||||
#include <limits.h>
|
||||
|
||||
int security_policyvers(void)
|
||||
|
@ -42,4 +41,3 @@ int security_policyvers(void)
|
|||
return vers;
|
||||
}
|
||||
|
||||
hidden_def(security_policyvers)
|
||||
|
|
|
@ -25,21 +25,23 @@ static __thread char destructor_initialized;
|
|||
/* Bionic and glibc >= 2.30 declare gettid() system call wrapper in unistd.h and
|
||||
* has a definition for it */
|
||||
#ifdef __BIONIC__
|
||||
#define OVERRIDE_GETTID 0
|
||||
#define HAVE_GETTID 1
|
||||
#elif !defined(__GLIBC_PREREQ)
|
||||
#define OVERRIDE_GETTID 1
|
||||
#define HAVE_GETTID 0
|
||||
#elif !__GLIBC_PREREQ(2,30)
|
||||
#define OVERRIDE_GETTID 1
|
||||
#define HAVE_GETTID 0
|
||||
#else
|
||||
#define OVERRIDE_GETTID 0
|
||||
#define HAVE_GETTID 1
|
||||
#endif
|
||||
|
||||
#if OVERRIDE_GETTID
|
||||
static pid_t gettid(void)
|
||||
static pid_t selinux_gettid(void)
|
||||
{
|
||||
#if HAVE_GETTID
|
||||
return gettid();
|
||||
#else
|
||||
return syscall(__NR_gettid);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void procattr_thread_destructor(void __attribute__((unused)) *unused)
|
||||
{
|
||||
|
@ -57,7 +59,7 @@ static void procattr_thread_destructor(void __attribute__((unused)) *unused)
|
|||
|
||||
void __attribute__((destructor)) procattr_destructor(void);
|
||||
|
||||
void hidden __attribute__((destructor)) procattr_destructor(void)
|
||||
void __attribute__((destructor)) procattr_destructor(void)
|
||||
{
|
||||
if (destructor_key_initialized)
|
||||
__selinux_key_delete(destructor_key);
|
||||
|
@ -66,7 +68,7 @@ void hidden __attribute__((destructor)) procattr_destructor(void)
|
|||
static inline void init_thread_destructor(void)
|
||||
{
|
||||
if (destructor_initialized == 0) {
|
||||
__selinux_setspecific(destructor_key, (void *)1);
|
||||
__selinux_setspecific(destructor_key, /* some valid address to please GCC */ &selinux_page_size);
|
||||
destructor_initialized = 1;
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +96,7 @@ static int openattr(pid_t pid, const char *attr, int flags)
|
|||
if (fd >= 0 || errno != ENOENT)
|
||||
goto out;
|
||||
free(path);
|
||||
tid = gettid();
|
||||
tid = selinux_gettid();
|
||||
rc = asprintf(&path, "/proc/self/task/%d/attr/%s", tid, attr);
|
||||
} else {
|
||||
errno = EINVAL;
|
||||
|
@ -144,7 +146,7 @@ static int getprocattrcon_raw(char ** context,
|
|||
default:
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
if (prev_context && prev_context != UNSET) {
|
||||
*context = strdup(prev_context);
|
||||
|
@ -238,7 +240,7 @@ static int setprocattrcon_raw(const char * context,
|
|||
default:
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
if (!context && !*prev_context)
|
||||
return 0;
|
||||
|
@ -345,22 +347,3 @@ all_selfattr_def(con, current)
|
|||
all_selfattr_def(sockcreatecon, sockcreate)
|
||||
all_selfattr_def(keycreatecon, keycreate)
|
||||
|
||||
hidden_def(getcon_raw)
|
||||
hidden_def(getcon)
|
||||
hidden_def(getexeccon_raw)
|
||||
hidden_def(getfilecon_raw)
|
||||
hidden_def(getfilecon)
|
||||
hidden_def(getfscreatecon_raw)
|
||||
hidden_def(getkeycreatecon_raw)
|
||||
hidden_def(getpeercon_raw)
|
||||
hidden_def(getpidcon_raw)
|
||||
hidden_def(getprevcon_raw)
|
||||
hidden_def(getprevcon)
|
||||
hidden_def(getsockcreatecon_raw)
|
||||
hidden_def(setcon_raw)
|
||||
hidden_def(setexeccon_raw)
|
||||
hidden_def(setexeccon)
|
||||
hidden_def(setfilecon_raw)
|
||||
hidden_def(setfscreatecon_raw)
|
||||
hidden_def(setkeycreatecon_raw)
|
||||
hidden_def(setsockcreatecon_raw)
|
||||
|
|
|
@ -319,7 +319,7 @@ char const *regex_version(void)
|
|||
}
|
||||
|
||||
int regex_load_mmap(struct mmap_area *mmap_area, struct regex_data **regex,
|
||||
int unused __attribute__((unused)), bool *regex_compiled)
|
||||
int do_load_precompregex __attribute__((unused)), bool *regex_compiled)
|
||||
{
|
||||
int rc;
|
||||
uint32_t entry_len;
|
||||
|
@ -387,7 +387,7 @@ static inline pcre_extra *get_pcre_extra(struct regex_data *regex)
|
|||
}
|
||||
|
||||
int regex_writef(struct regex_data *regex, FILE *fp,
|
||||
int unused __attribute__((unused)))
|
||||
int do_write_precompregex __attribute__((unused)))
|
||||
{
|
||||
int rc;
|
||||
size_t len;
|
||||
|
|
23
src/regex.h
23
src/regex.h
|
@ -10,7 +10,6 @@
|
|||
#include <pcre.h>
|
||||
#endif
|
||||
|
||||
#include "dso.h"
|
||||
|
||||
enum { REGEX_MATCH,
|
||||
REGEX_MATCH_PARTIAL,
|
||||
|
@ -42,10 +41,10 @@ struct mmap_area;
|
|||
* expressions are not portable across architectures that do not have a
|
||||
* matching arch-string.
|
||||
*/
|
||||
char const *regex_arch_string(void) hidden;
|
||||
char const *regex_arch_string(void) ;
|
||||
|
||||
/**
|
||||
* regex_verison returns the version string of the underlying regular
|
||||
* regex_version returns the version string of the underlying regular
|
||||
* regular expressions library. In the case of PCRE it just returns the
|
||||
* result of pcre_version(). In the case of PCRE2, the very first time this
|
||||
* function is called it allocates a buffer large enough to hold the version
|
||||
|
@ -55,12 +54,12 @@ char const *regex_arch_string(void) hidden;
|
|||
*
|
||||
* It may return NULL on error.
|
||||
*/
|
||||
char const *regex_version(void) hidden;
|
||||
char const *regex_version(void) ;
|
||||
/**
|
||||
* This constructor function allocates a buffer for a regex_data structure.
|
||||
* The buffer is being initialized with zeroes.
|
||||
*/
|
||||
struct regex_data *regex_data_create(void) hidden;
|
||||
struct regex_data *regex_data_create(void) ;
|
||||
/**
|
||||
* This complementary destructor function frees the a given regex_data buffer.
|
||||
* It also frees any non NULL member pointers with the appropriate pcreX_X_free
|
||||
|
@ -68,7 +67,7 @@ struct regex_data *regex_data_create(void) hidden;
|
|||
* the pcre_extra data conditionally. Calling this function on a NULL pointer is
|
||||
* save.
|
||||
*/
|
||||
void regex_data_free(struct regex_data *regex) hidden;
|
||||
void regex_data_free(struct regex_data *regex) ;
|
||||
/**
|
||||
* This function compiles the regular expression. Additionally, it prepares
|
||||
* data structures required by the different underlying engines. For PCRE
|
||||
|
@ -88,7 +87,7 @@ void regex_data_free(struct regex_data *regex) hidden;
|
|||
* @retval -1 on error
|
||||
*/
|
||||
int regex_prepare_data(struct regex_data **regex, char const *pattern_string,
|
||||
struct regex_error_data *errordata) hidden;
|
||||
struct regex_error_data *errordata) ;
|
||||
/**
|
||||
* This function loads a serialized precompiled pattern from a contiguous
|
||||
* data region given by map_area.
|
||||
|
@ -109,7 +108,7 @@ int regex_prepare_data(struct regex_data **regex, char const *pattern_string,
|
|||
int regex_load_mmap(struct mmap_area *map_area,
|
||||
struct regex_data **regex,
|
||||
int do_load_precompregex,
|
||||
bool *regex_compiled) hidden;
|
||||
bool *regex_compiled) ;
|
||||
/**
|
||||
* This function stores a precompiled regular expression to a file.
|
||||
* In the case of PCRE, it just dumps the binary representation of the
|
||||
|
@ -122,7 +121,7 @@ int regex_load_mmap(struct mmap_area *map_area,
|
|||
* the output file (ignored by PCRE1 back-end).
|
||||
*/
|
||||
int regex_writef(struct regex_data *regex, FILE *fp,
|
||||
int do_write_precompregex) hidden;
|
||||
int do_write_precompregex) ;
|
||||
/**
|
||||
* This function applies a precompiled pattern to a subject string and
|
||||
* returns whether or not a match was found.
|
||||
|
@ -139,7 +138,7 @@ int regex_writef(struct regex_data *regex, FILE *fp,
|
|||
* regular expression
|
||||
*/
|
||||
int regex_match(struct regex_data *regex, char const *subject,
|
||||
int partial) hidden;
|
||||
int partial) ;
|
||||
/**
|
||||
* This function compares two compiled regular expressions (regex1 and regex2).
|
||||
* It compares the binary representations of the compiled patterns. It is a very
|
||||
|
@ -150,7 +149,7 @@ int regex_match(struct regex_data *regex, char const *subject,
|
|||
* the same
|
||||
* @retval SELABEL_INCOMPARABLE otherwise
|
||||
*/
|
||||
int regex_cmp(struct regex_data *regex1, struct regex_data *regex2) hidden;
|
||||
int regex_cmp(struct regex_data *regex1, struct regex_data *regex2) ;
|
||||
/**
|
||||
* This function takes the error data returned by regex_prepare_data and turns
|
||||
* it in to a human readable error message.
|
||||
|
@ -163,5 +162,5 @@ int regex_cmp(struct regex_data *regex1, struct regex_data *regex2) hidden;
|
|||
* @arg buf_size Total size of the given buffer in bytes.
|
||||
*/
|
||||
void regex_format_error(struct regex_error_data const *error_data, char *buffer,
|
||||
size_t buf_size) hidden;
|
||||
size_t buf_size) ;
|
||||
#endif /* SRC_REGEX_H_ */
|
||||
|
|
|
@ -37,4 +37,3 @@ int security_reject_unknown(void)
|
|||
return reject_unknown;
|
||||
}
|
||||
|
||||
hidden_def(security_reject_unknown);
|
||||
|
|
|
@ -50,4 +50,3 @@ int selinux_check_securetty_context(const char * tty_context)
|
|||
return found;
|
||||
}
|
||||
|
||||
hidden_def(selinux_check_securetty_context)
|
||||
|
|
|
@ -92,6 +92,7 @@ int selinux_getenforcemode(int *enforce)
|
|||
FILE *cfg = fopen(SELINUXCONFIG, "re");
|
||||
if (cfg) {
|
||||
char *buf;
|
||||
char *tag;
|
||||
int len = sizeof(SELINUXTAG) - 1;
|
||||
buf = malloc(selinux_page_size);
|
||||
if (!buf) {
|
||||
|
@ -101,21 +102,24 @@ int selinux_getenforcemode(int *enforce)
|
|||
while (fgets_unlocked(buf, selinux_page_size, cfg)) {
|
||||
if (strncmp(buf, SELINUXTAG, len))
|
||||
continue;
|
||||
tag = buf+len;
|
||||
while (isspace(*tag))
|
||||
tag++;
|
||||
if (!strncasecmp
|
||||
(buf + len, "enforcing", sizeof("enforcing") - 1)) {
|
||||
(tag, "enforcing", sizeof("enforcing") - 1)) {
|
||||
*enforce = 1;
|
||||
ret = 0;
|
||||
break;
|
||||
} else
|
||||
if (!strncasecmp
|
||||
(buf + len, "permissive",
|
||||
(tag, "permissive",
|
||||
sizeof("permissive") - 1)) {
|
||||
*enforce = 0;
|
||||
ret = 0;
|
||||
break;
|
||||
} else
|
||||
if (!strncasecmp
|
||||
(buf + len, "disabled",
|
||||
(tag, "disabled",
|
||||
sizeof("disabled") - 1)) {
|
||||
*enforce = -1;
|
||||
ret = 0;
|
||||
|
@ -128,7 +132,6 @@ int selinux_getenforcemode(int *enforce)
|
|||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(selinux_getenforcemode)
|
||||
|
||||
static char *selinux_policytype;
|
||||
|
||||
|
@ -141,7 +144,6 @@ int selinux_getpolicytype(char **type)
|
|||
return *type ? 0 : -1;
|
||||
}
|
||||
|
||||
hidden_def(selinux_getpolicytype)
|
||||
|
||||
static int setpolicytype(const char *type)
|
||||
{
|
||||
|
@ -178,9 +180,15 @@ static void init_selinux_config(void)
|
|||
|
||||
if (!strncasecmp(buf_p, SELINUXTYPETAG,
|
||||
sizeof(SELINUXTYPETAG) - 1)) {
|
||||
type = strdup(buf_p + sizeof(SELINUXTYPETAG) - 1);
|
||||
if (!type)
|
||||
buf_p += sizeof(SELINUXTYPETAG) - 1;
|
||||
while (isspace(*buf_p))
|
||||
buf_p++;
|
||||
type = strdup(buf_p);
|
||||
if (!type) {
|
||||
free(line_buf);
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
end = type + strlen(type) - 1;
|
||||
while ((end > type) &&
|
||||
(isspace(*end) || iscntrl(*end))) {
|
||||
|
@ -189,6 +197,8 @@ static void init_selinux_config(void)
|
|||
}
|
||||
if (setpolicytype(type) != 0) {
|
||||
free(type);
|
||||
free(line_buf);
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
free(type);
|
||||
|
@ -196,6 +206,8 @@ static void init_selinux_config(void)
|
|||
} else if (!strncmp(buf_p, REQUIRESEUSERS,
|
||||
sizeof(REQUIRESEUSERS) - 1)) {
|
||||
value = buf_p + sizeof(REQUIRESEUSERS) - 1;
|
||||
while (isspace(*value))
|
||||
value++;
|
||||
intptr = &require_seusers;
|
||||
} else {
|
||||
continue;
|
||||
|
@ -249,7 +261,6 @@ void selinux_reset_config(void)
|
|||
init_selinux_config();
|
||||
}
|
||||
|
||||
hidden_def(selinux_reset_config)
|
||||
|
||||
static const char *get_path(int idx)
|
||||
{
|
||||
|
@ -262,7 +273,6 @@ const char *selinux_default_type_path(void)
|
|||
return get_path(DEFAULT_TYPE);
|
||||
}
|
||||
|
||||
hidden_def(selinux_default_type_path)
|
||||
|
||||
const char *selinux_policy_root(void)
|
||||
{
|
||||
|
@ -305,42 +315,36 @@ const char *selinux_path(void)
|
|||
return selinux_rootpath;
|
||||
}
|
||||
|
||||
hidden_def(selinux_path)
|
||||
|
||||
const char *selinux_default_context_path(void)
|
||||
{
|
||||
return get_path(DEFAULT_CONTEXTS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_default_context_path)
|
||||
|
||||
const char *selinux_securetty_types_path(void)
|
||||
{
|
||||
return get_path(SECURETTY_TYPES);
|
||||
}
|
||||
|
||||
hidden_def(selinux_securetty_types_path)
|
||||
|
||||
const char *selinux_failsafe_context_path(void)
|
||||
{
|
||||
return get_path(FAILSAFE_CONTEXT);
|
||||
}
|
||||
|
||||
hidden_def(selinux_failsafe_context_path)
|
||||
|
||||
const char *selinux_removable_context_path(void)
|
||||
{
|
||||
return get_path(REMOVABLE_CONTEXT);
|
||||
}
|
||||
|
||||
hidden_def(selinux_removable_context_path)
|
||||
|
||||
const char *selinux_binary_policy_path(void)
|
||||
{
|
||||
return get_path(BINPOLICY);
|
||||
}
|
||||
|
||||
hidden_def(selinux_binary_policy_path)
|
||||
|
||||
const char *selinux_current_policy_path(void)
|
||||
{
|
||||
|
@ -365,35 +369,30 @@ const char *selinux_current_policy_path(void)
|
|||
return policy_path;
|
||||
}
|
||||
|
||||
hidden_def(selinux_current_policy_path)
|
||||
|
||||
const char *selinux_file_context_path(void)
|
||||
{
|
||||
return get_path(FILE_CONTEXTS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_file_context_path)
|
||||
|
||||
const char *selinux_homedir_context_path(void)
|
||||
{
|
||||
return get_path(HOMEDIR_CONTEXTS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_homedir_context_path)
|
||||
|
||||
const char *selinux_media_context_path(void)
|
||||
{
|
||||
return get_path(MEDIA_CONTEXTS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_media_context_path)
|
||||
|
||||
const char *selinux_customizable_types_path(void)
|
||||
{
|
||||
return get_path(CUSTOMIZABLE_TYPES);
|
||||
}
|
||||
|
||||
hidden_def(selinux_customizable_types_path)
|
||||
|
||||
const char *selinux_contexts_path(void)
|
||||
{
|
||||
|
@ -405,7 +404,6 @@ const char *selinux_user_contexts_path(void)
|
|||
return get_path(USER_CONTEXTS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_user_contexts_path)
|
||||
|
||||
/* Deprecated as local policy booleans no longer supported. */
|
||||
const char *selinux_booleans_path(void)
|
||||
|
@ -413,7 +411,6 @@ const char *selinux_booleans_path(void)
|
|||
return get_path(BOOLEANS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_booleans_path)
|
||||
|
||||
/* Deprecated as no longer supported. */
|
||||
const char *selinux_users_path(void)
|
||||
|
@ -421,127 +418,108 @@ const char *selinux_users_path(void)
|
|||
return get_path(USERS_DIR);
|
||||
}
|
||||
|
||||
hidden_def(selinux_users_path)
|
||||
|
||||
const char *selinux_usersconf_path(void)
|
||||
{
|
||||
return get_path(SEUSERS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_usersconf_path)
|
||||
|
||||
const char *selinux_translations_path(void)
|
||||
{
|
||||
return get_path(TRANSLATIONS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_translations_path)
|
||||
|
||||
const char *selinux_colors_path(void)
|
||||
{
|
||||
return get_path(COLORS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_colors_path)
|
||||
|
||||
const char *selinux_netfilter_context_path(void)
|
||||
{
|
||||
return get_path(NETFILTER_CONTEXTS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_netfilter_context_path)
|
||||
|
||||
const char *selinux_file_context_homedir_path(void)
|
||||
{
|
||||
return get_path(FILE_CONTEXTS_HOMEDIR);
|
||||
}
|
||||
|
||||
hidden_def(selinux_file_context_homedir_path)
|
||||
|
||||
const char *selinux_file_context_local_path(void)
|
||||
{
|
||||
return get_path(FILE_CONTEXTS_LOCAL);
|
||||
}
|
||||
|
||||
hidden_def(selinux_file_context_local_path)
|
||||
|
||||
const char *selinux_x_context_path(void)
|
||||
{
|
||||
return get_path(X_CONTEXTS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_x_context_path)
|
||||
|
||||
const char *selinux_virtual_domain_context_path(void)
|
||||
{
|
||||
return get_path(VIRTUAL_DOMAIN);
|
||||
}
|
||||
|
||||
hidden_def(selinux_virtual_domain_context_path)
|
||||
|
||||
const char *selinux_virtual_image_context_path(void)
|
||||
{
|
||||
return get_path(VIRTUAL_IMAGE);
|
||||
}
|
||||
|
||||
hidden_def(selinux_virtual_image_context_path)
|
||||
|
||||
const char *selinux_lxc_contexts_path(void)
|
||||
{
|
||||
return get_path(LXC_CONTEXTS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_lxc_contexts_path)
|
||||
|
||||
const char *selinux_openrc_contexts_path(void)
|
||||
{
|
||||
return get_path(OPENRC_CONTEXTS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_openrc_contexts_path)
|
||||
|
||||
const char *selinux_openssh_contexts_path(void)
|
||||
{
|
||||
return get_path(OPENSSH_CONTEXTS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_openssh_contexts_path)
|
||||
|
||||
const char *selinux_snapperd_contexts_path(void)
|
||||
{
|
||||
return get_path(SNAPPERD_CONTEXTS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_snapperd_contexts_path)
|
||||
|
||||
const char *selinux_systemd_contexts_path(void)
|
||||
{
|
||||
return get_path(SYSTEMD_CONTEXTS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_systemd_contexts_path)
|
||||
|
||||
const char * selinux_booleans_subs_path(void) {
|
||||
return get_path(BOOLEAN_SUBS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_booleans_subs_path)
|
||||
|
||||
const char * selinux_file_context_subs_path(void) {
|
||||
return get_path(FILE_CONTEXT_SUBS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_file_context_subs_path)
|
||||
|
||||
const char * selinux_file_context_subs_dist_path(void) {
|
||||
return get_path(FILE_CONTEXT_SUBS_DIST);
|
||||
}
|
||||
|
||||
hidden_def(selinux_file_context_subs_dist_path)
|
||||
|
||||
const char *selinux_sepgsql_context_path(void)
|
||||
{
|
||||
return get_path(SEPGSQL_CONTEXTS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_sepgsql_context_path)
|
||||
|
|
|
@ -1,117 +1,9 @@
|
|||
#include <selinux/selinux.h>
|
||||
#include <pthread.h>
|
||||
#include "dso.h"
|
||||
|
||||
hidden_proto(selinux_mkload_policy)
|
||||
hidden_proto(fini_selinuxmnt)
|
||||
hidden_proto(set_selinuxmnt)
|
||||
hidden_proto(selinuxfs_exists)
|
||||
hidden_proto(security_disable)
|
||||
hidden_proto(security_policyvers)
|
||||
hidden_proto(security_load_policy)
|
||||
hidden_proto(security_get_boolean_active)
|
||||
hidden_proto(security_get_boolean_names)
|
||||
hidden_proto(security_set_boolean)
|
||||
hidden_proto(security_commit_booleans)
|
||||
hidden_proto(security_check_context)
|
||||
hidden_proto(security_check_context_raw)
|
||||
hidden_proto(security_canonicalize_context)
|
||||
hidden_proto(security_canonicalize_context_raw)
|
||||
hidden_proto(security_compute_av)
|
||||
hidden_proto(security_compute_av_raw)
|
||||
hidden_proto(security_compute_av_flags)
|
||||
hidden_proto(security_compute_av_flags_raw)
|
||||
hidden_proto(security_compute_user)
|
||||
hidden_proto(security_compute_user_raw)
|
||||
hidden_proto(security_compute_create)
|
||||
hidden_proto(security_compute_create_raw)
|
||||
hidden_proto(security_compute_create_name)
|
||||
hidden_proto(security_compute_create_name_raw)
|
||||
hidden_proto(security_compute_member_raw)
|
||||
hidden_proto(security_compute_relabel_raw)
|
||||
hidden_proto(security_validatetrans)
|
||||
hidden_proto(security_validatetrans_raw)
|
||||
hidden_proto(is_selinux_enabled)
|
||||
hidden_proto(is_selinux_mls_enabled)
|
||||
hidden_proto(freecon)
|
||||
hidden_proto(freeconary)
|
||||
hidden_proto(getprevcon)
|
||||
hidden_proto(getprevcon_raw)
|
||||
hidden_proto(getcon)
|
||||
hidden_proto(getcon_raw)
|
||||
hidden_proto(setcon_raw)
|
||||
hidden_proto(getpeercon_raw)
|
||||
hidden_proto(getpidcon_raw)
|
||||
hidden_proto(getexeccon_raw)
|
||||
hidden_proto(getfilecon)
|
||||
hidden_proto(getfilecon_raw)
|
||||
hidden_proto(lgetfilecon_raw)
|
||||
hidden_proto(fgetfilecon_raw)
|
||||
hidden_proto(setfilecon_raw)
|
||||
hidden_proto(lsetfilecon_raw)
|
||||
hidden_proto(fsetfilecon_raw)
|
||||
hidden_proto(setexeccon)
|
||||
hidden_proto(setexeccon_raw)
|
||||
hidden_proto(getfscreatecon_raw)
|
||||
hidden_proto(getkeycreatecon_raw)
|
||||
hidden_proto(getsockcreatecon_raw)
|
||||
hidden_proto(setfscreatecon_raw)
|
||||
hidden_proto(setkeycreatecon_raw)
|
||||
hidden_proto(setsockcreatecon_raw)
|
||||
hidden_proto(security_getenforce)
|
||||
hidden_proto(security_setenforce)
|
||||
hidden_proto(security_deny_unknown)
|
||||
hidden_proto(security_reject_unknown)
|
||||
hidden_proto(security_get_checkreqprot)
|
||||
hidden_proto(selinux_boolean_sub)
|
||||
hidden_proto(selinux_current_policy_path)
|
||||
hidden_proto(selinux_binary_policy_path)
|
||||
hidden_proto(selinux_booleans_subs_path)
|
||||
hidden_proto(selinux_default_context_path)
|
||||
hidden_proto(selinux_securetty_types_path)
|
||||
hidden_proto(selinux_failsafe_context_path)
|
||||
hidden_proto(selinux_removable_context_path)
|
||||
hidden_proto(selinux_virtual_domain_context_path)
|
||||
hidden_proto(selinux_virtual_image_context_path)
|
||||
hidden_proto(selinux_lxc_contexts_path)
|
||||
hidden_proto(selinux_file_context_path)
|
||||
hidden_proto(selinux_file_context_homedir_path)
|
||||
hidden_proto(selinux_file_context_local_path)
|
||||
hidden_proto(selinux_file_context_subs_dist_path)
|
||||
hidden_proto(selinux_file_context_subs_path)
|
||||
hidden_proto(selinux_netfilter_context_path)
|
||||
hidden_proto(selinux_homedir_context_path)
|
||||
hidden_proto(selinux_user_contexts_path)
|
||||
hidden_proto(selinux_booleans_path)
|
||||
hidden_proto(selinux_customizable_types_path)
|
||||
hidden_proto(selinux_media_context_path)
|
||||
hidden_proto(selinux_x_context_path)
|
||||
hidden_proto(selinux_sepgsql_context_path)
|
||||
hidden_proto(selinux_openrc_contexts_path)
|
||||
hidden_proto(selinux_openssh_contexts_path)
|
||||
hidden_proto(selinux_snapperd_contexts_path)
|
||||
hidden_proto(selinux_systemd_contexts_path)
|
||||
hidden_proto(selinux_path)
|
||||
hidden_proto(selinux_check_passwd_access)
|
||||
hidden_proto(selinux_check_securetty_context)
|
||||
hidden_proto(matchpathcon_init_prefix)
|
||||
hidden_proto(selinux_users_path)
|
||||
hidden_proto(selinux_usersconf_path);
|
||||
hidden_proto(selinux_translations_path);
|
||||
hidden_proto(selinux_colors_path);
|
||||
hidden_proto(selinux_getenforcemode);
|
||||
hidden_proto(selinux_getpolicytype);
|
||||
hidden_proto(selinux_raw_to_trans_context);
|
||||
hidden_proto(selinux_trans_to_raw_context);
|
||||
hidden_proto(selinux_raw_context_to_color);
|
||||
hidden_proto(security_get_initial_context);
|
||||
hidden_proto(security_get_initial_context_raw);
|
||||
hidden_proto(selinux_reset_config);
|
||||
|
||||
hidden void flush_class_cache(void);
|
||||
|
||||
extern int require_seusers hidden;
|
||||
extern int selinux_page_size hidden;
|
||||
extern int require_seusers ;
|
||||
extern int selinux_page_size ;
|
||||
|
||||
/* Make pthread_once optional */
|
||||
#pragma weak pthread_once
|
||||
|
@ -177,8 +69,24 @@ extern int selinux_page_size hidden;
|
|||
pthread_mutex_unlock(LOCK); \
|
||||
} while (0)
|
||||
|
||||
#pragma weak pthread_create
|
||||
#pragma weak pthread_join
|
||||
#pragma weak pthread_cond_init
|
||||
#pragma weak pthread_cond_signal
|
||||
#pragma weak pthread_cond_destroy
|
||||
#pragma weak pthread_cond_wait
|
||||
|
||||
/* check if all functions needed to do parallel operations are available */
|
||||
#define __pthread_supported ( \
|
||||
pthread_create && \
|
||||
pthread_join && \
|
||||
pthread_cond_init && \
|
||||
pthread_cond_destroy && \
|
||||
pthread_cond_signal && \
|
||||
pthread_cond_wait \
|
||||
)
|
||||
|
||||
#define SELINUXDIR "/etc/selinux/"
|
||||
#define SELINUXCONFIG SELINUXDIR "config"
|
||||
|
||||
extern int has_selinux_config hidden;
|
||||
extern int has_selinux_config ;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,7 +20,7 @@ DISABLED = -1
|
|||
PERMISSIVE = 0
|
||||
ENFORCING = 1
|
||||
|
||||
def restorecon(path, recursive=False, verbose=False, force=False):
|
||||
def restorecon(path, recursive=False, verbose=False, force=False, nthreads=1):
|
||||
""" Restore SELinux context on a given path
|
||||
|
||||
Arguments:
|
||||
|
@ -32,6 +32,8 @@ def restorecon(path, recursive=False, verbose=False, force=False):
|
|||
force -- Force reset of context to match file_context for customizable files,
|
||||
and the default file context, changing the user, role, range portion as well
|
||||
as the type (default False)
|
||||
nthreads -- The number of threads to use during relabeling, or 0 to use as many
|
||||
threads as there are online CPU cores (default 1)
|
||||
"""
|
||||
|
||||
restorecon_flags = SELINUX_RESTORECON_IGNORE_DIGEST | SELINUX_RESTORECON_REALPATH
|
||||
|
@ -41,7 +43,7 @@ def restorecon(path, recursive=False, verbose=False, force=False):
|
|||
restorecon_flags |= SELINUX_RESTORECON_VERBOSE
|
||||
if force:
|
||||
restorecon_flags |= SELINUX_RESTORECON_SET_SPECFILE_CTX
|
||||
selinux_restorecon(os.path.expanduser(path), restorecon_flags)
|
||||
selinux_restorecon_parallel(os.path.expanduser(path), restorecon_flags, nthreads)
|
||||
|
||||
def chcon(path, context, recursive=False):
|
||||
""" Set the SELinux context on a given path """
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -37,13 +37,15 @@ struct selinux_status_t
|
|||
* Valid Pointer : opened and mapped correctly
|
||||
*/
|
||||
static struct selinux_status_t *selinux_status = NULL;
|
||||
static int selinux_status_fd;
|
||||
static uint32_t last_seqno;
|
||||
static uint32_t last_policyload;
|
||||
|
||||
static uint32_t fallback_sequence;
|
||||
static int fallback_enforcing;
|
||||
static int fallback_policyload;
|
||||
|
||||
static void *fallback_netlink_thread = NULL;
|
||||
|
||||
/*
|
||||
* read_sequence
|
||||
*
|
||||
|
@ -88,7 +90,9 @@ static inline uint32_t read_sequence(struct selinux_status_t *status)
|
|||
int selinux_status_updated(void)
|
||||
{
|
||||
uint32_t curr_seqno;
|
||||
int result = 0;
|
||||
uint32_t tmp_seqno;
|
||||
uint32_t enforcing;
|
||||
uint32_t policyload;
|
||||
|
||||
if (selinux_status == NULL) {
|
||||
errno = EINVAL;
|
||||
|
@ -114,12 +118,29 @@ int selinux_status_updated(void)
|
|||
if (last_seqno & 0x0001)
|
||||
last_seqno = curr_seqno;
|
||||
|
||||
if (last_seqno != curr_seqno)
|
||||
{
|
||||
last_seqno = curr_seqno;
|
||||
result = 1;
|
||||
if (last_seqno == curr_seqno)
|
||||
return 0;
|
||||
|
||||
/* sequence must not be changed during references */
|
||||
do {
|
||||
enforcing = selinux_status->enforcing;
|
||||
policyload = selinux_status->policyload;
|
||||
tmp_seqno = curr_seqno;
|
||||
curr_seqno = read_sequence(selinux_status);
|
||||
} while (tmp_seqno != curr_seqno);
|
||||
|
||||
if (avc_enforcing != (int) enforcing) {
|
||||
if (avc_process_setenforce(enforcing) < 0)
|
||||
return -1;
|
||||
}
|
||||
return result;
|
||||
if (last_policyload != policyload) {
|
||||
if (avc_process_policyload(policyload) < 0)
|
||||
return -1;
|
||||
last_policyload = policyload;
|
||||
}
|
||||
last_seqno = curr_seqno;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -250,13 +271,20 @@ static int fallback_cb_policyload(int policyload)
|
|||
* Since Linux 2.6.37 or later supports this feature, we may run
|
||||
* fallback routine using a netlink socket on older kernels, if
|
||||
* the supplied `fallback' is not zero.
|
||||
* It returns 0 on success, or -1 on error.
|
||||
* It returns 0 on success, -1 on error or 1 when we are ready to
|
||||
* use these interfaces, but netlink socket was opened as fallback
|
||||
* instead of the kernel status page.
|
||||
*/
|
||||
int selinux_status_open(int fallback)
|
||||
{
|
||||
int fd;
|
||||
char path[PATH_MAX];
|
||||
long pagesize;
|
||||
int fd;
|
||||
char path[PATH_MAX];
|
||||
long pagesize;
|
||||
uint32_t seqno;
|
||||
|
||||
if (selinux_status != NULL) {
|
||||
return (selinux_status == MAP_FAILED) ? 1 : 0;
|
||||
}
|
||||
|
||||
if (!selinux_mnt) {
|
||||
errno = ENOENT;
|
||||
|
@ -273,13 +301,23 @@ int selinux_status_open(int fallback)
|
|||
goto error;
|
||||
|
||||
selinux_status = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, fd, 0);
|
||||
close(fd);
|
||||
if (selinux_status == MAP_FAILED) {
|
||||
close(fd);
|
||||
goto error;
|
||||
}
|
||||
selinux_status_fd = fd;
|
||||
last_seqno = (uint32_t)(-1);
|
||||
|
||||
/* sequence must not be changed during references */
|
||||
do {
|
||||
seqno = read_sequence(selinux_status);
|
||||
|
||||
last_policyload = selinux_status->policyload;
|
||||
|
||||
} while (seqno != read_sequence(selinux_status));
|
||||
|
||||
/* No need to use avc threads if the kernel status page is available */
|
||||
avc_using_threads = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
@ -300,9 +338,14 @@ error:
|
|||
|
||||
/* mark as fallback mode */
|
||||
selinux_status = MAP_FAILED;
|
||||
selinux_status_fd = avc_netlink_acquire_fd();
|
||||
last_seqno = (uint32_t)(-1);
|
||||
|
||||
if (avc_using_threads)
|
||||
{
|
||||
fallback_netlink_thread = avc_create_thread(&avc_netlink_loop);
|
||||
avc_netlink_trouble = 0;
|
||||
}
|
||||
|
||||
fallback_sequence = 0;
|
||||
fallback_enforcing = security_getenforce();
|
||||
fallback_policyload = 0;
|
||||
|
@ -331,6 +374,9 @@ void selinux_status_close(void)
|
|||
/* fallback-mode */
|
||||
if (selinux_status == MAP_FAILED)
|
||||
{
|
||||
if (avc_using_threads)
|
||||
avc_stop_thread(fallback_netlink_thread);
|
||||
|
||||
avc_netlink_release_fd();
|
||||
avc_netlink_close();
|
||||
selinux_status = NULL;
|
||||
|
@ -343,7 +389,5 @@ void selinux_status_close(void)
|
|||
munmap(selinux_status, pagesize);
|
||||
selinux_status = NULL;
|
||||
|
||||
close(selinux_status_fd);
|
||||
selinux_status_fd = -1;
|
||||
last_seqno = (uint32_t)(-1);
|
||||
}
|
||||
|
|
|
@ -34,4 +34,3 @@ int security_setenforce(int value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
hidden_def(security_setenforce)
|
||||
|
|
|
@ -37,7 +37,6 @@ int setexecfilecon(const char *filename, const char *fallback_type)
|
|||
newcon = strdup(context_str(con));
|
||||
if (!newcon)
|
||||
goto out;
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
rc = setexeccon(newcon);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue