Move /selinux to /sys/fs/selinux
Add selinuxexeccon Add realpath to matchpathcon to handle matchpathcon * type queries.
This commit is contained in:
parent
71e7978d45
commit
2c3aaeae1e
@ -1,3 +1,33 @@
|
||||
diff --git a/libselinux/man/man8/selinuxexeccon.8 b/libselinux/man/man8/selinuxexeccon.8
|
||||
new file mode 100644
|
||||
index 0000000..6482d74
|
||||
--- /dev/null
|
||||
+++ b/libselinux/man/man8/selinuxexeccon.8
|
||||
@@ -0,0 +1,24 @@
|
||||
+.TH "selinuxexeccon" "1" "14 May 2011" "dwalsh@redhat.com" "SELinux Command Line documentation"
|
||||
+.SH "NAME"
|
||||
+selinuxexeccon \- report SELinux context used for this executable
|
||||
+
|
||||
+.SH "SYNOPSIS"
|
||||
+.B selinuxexeccon command [ fromcon] o
|
||||
+
|
||||
+.SH "DESCRIPTION"
|
||||
+.B selinuxexeccon
|
||||
+reports the SELinux process context for the specified command from the specified context or the current context.
|
||||
+
|
||||
+.SH EXAMPLE
|
||||
+# selinuxexeccon /usr/bin/passwd
|
||||
+staff_u:staff_r:passwd_t:s0-s0:c0.c1023
|
||||
+
|
||||
+.br
|
||||
+# selinuxexeccon /usr/sbin/sendmail system_u:system_r:httpd_t:s0
|
||||
+system_u:system_r:system_mail_t:s0
|
||||
+
|
||||
+.SH AUTHOR
|
||||
+This manual page was written by Dan Walsh <dwalsh@redhat.com>.
|
||||
+
|
||||
+.SH "SEE ALSO"
|
||||
+secon(8)
|
||||
diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile
|
||||
index bf665ab..ccd08ae 100644
|
||||
--- a/libselinux/src/Makefile
|
||||
@ -174,6 +204,204 @@ index b245364..7c47222 100644
|
||||
va_start(ap, fmt);
|
||||
rc = vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
diff --git a/libselinux/src/enabled.c b/libselinux/src/enabled.c
|
||||
index b3c8c47..018c787 100644
|
||||
--- a/libselinux/src/enabled.c
|
||||
+++ b/libselinux/src/enabled.c
|
||||
@@ -11,10 +11,6 @@
|
||||
|
||||
int is_selinux_enabled(void)
|
||||
{
|
||||
- char *buf=NULL;
|
||||
- FILE *fp;
|
||||
- ssize_t num;
|
||||
- size_t len;
|
||||
int enabled = 0;
|
||||
security_context_t con;
|
||||
|
||||
@@ -32,37 +28,8 @@ int is_selinux_enabled(void)
|
||||
enabled = 0;
|
||||
freecon(con);
|
||||
}
|
||||
- return enabled;
|
||||
}
|
||||
|
||||
- /* Drop back to detecting it the long way. */
|
||||
- fp = fopen("/proc/filesystems", "r");
|
||||
- if (!fp)
|
||||
- return -1;
|
||||
-
|
||||
- __fsetlocking(fp, FSETLOCKING_BYCALLER);
|
||||
- while ((num = getline(&buf, &len, fp)) != -1) {
|
||||
- if (strstr(buf, "selinuxfs")) {
|
||||
- enabled = 1;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (num < 0)
|
||||
- goto out;
|
||||
-
|
||||
- /* Since an selinux file system is available, we consider
|
||||
- * selinux enabled. If getcon_raw fails, selinux is still
|
||||
- * enabled. We only consider it disabled if no policy is loaded. */
|
||||
- if (getcon_raw(&con) == 0) {
|
||||
- if (!strcmp(con, "kernel"))
|
||||
- enabled = 0;
|
||||
- freecon(con);
|
||||
- }
|
||||
-
|
||||
- out:
|
||||
- free(buf);
|
||||
- fclose(fp);
|
||||
return enabled;
|
||||
}
|
||||
|
||||
diff --git a/libselinux/src/init.c b/libselinux/src/init.c
|
||||
index a948920..dd03559 100644
|
||||
--- a/libselinux/src/init.c
|
||||
+++ b/libselinux/src/init.c
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdio_ext.h>
|
||||
#include <dlfcn.h>
|
||||
+#include <sys/statvfs.h>
|
||||
#include <sys/vfs.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
@@ -20,12 +21,41 @@ char *selinux_mnt = NULL;
|
||||
int selinux_page_size = 0;
|
||||
int obj_class_compat = 1;
|
||||
|
||||
+/* Verify the mount point for selinux file system has a selinuxfs.
|
||||
+ If the file system:
|
||||
+ * Exist,
|
||||
+ * Is mounted with an selinux file system,
|
||||
+ * The file system is read/write
|
||||
+ * then set this as the default file system.
|
||||
+*/
|
||||
+static int verify_selinuxmnt(char *mnt)
|
||||
+{
|
||||
+ struct statfs sfbuf;
|
||||
+ int rc;
|
||||
+
|
||||
+ do {
|
||||
+ rc = statfs(mnt, &sfbuf);
|
||||
+ } while (rc < 0 && errno == EINTR);
|
||||
+ if (rc == 0) {
|
||||
+ if ((uint32_t)sfbuf.f_type == (uint32_t)SELINUX_MAGIC) {
|
||||
+ struct statvfs vfsbuf;
|
||||
+ rc = statvfs(mnt, &vfsbuf);
|
||||
+ if (rc == 0) {
|
||||
+ if (!(vfsbuf.f_flag & ST_RDONLY)) {
|
||||
+ set_selinuxmnt(mnt);
|
||||
+ }
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
static void init_selinuxmnt(void)
|
||||
{
|
||||
char *buf=NULL, *p;
|
||||
FILE *fp=NULL;
|
||||
- struct statfs sfbuf;
|
||||
- int rc;
|
||||
size_t len;
|
||||
ssize_t num;
|
||||
int exists = 0;
|
||||
@@ -33,17 +63,9 @@ static void init_selinuxmnt(void)
|
||||
if (selinux_mnt)
|
||||
return;
|
||||
|
||||
- /* We check to see if the preferred mount point for selinux file
|
||||
- * system has a selinuxfs. */
|
||||
- do {
|
||||
- rc = statfs(SELINUXMNT, &sfbuf);
|
||||
- } while (rc < 0 && errno == EINTR);
|
||||
- if (rc == 0) {
|
||||
- if ((uint32_t)sfbuf.f_type == (uint32_t)SELINUX_MAGIC) {
|
||||
- selinux_mnt = strdup(SELINUXMNT);
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
+ if (verify_selinuxmnt(SELINUXMNT) == 0) return;
|
||||
+
|
||||
+ if (verify_selinuxmnt(OLDSELINUXMNT) == 0) return;
|
||||
|
||||
/* Drop back to detecting it the long way. */
|
||||
fp = fopen("/proc/filesystems", "r");
|
||||
@@ -52,7 +74,7 @@ static void init_selinuxmnt(void)
|
||||
|
||||
__fsetlocking(fp, FSETLOCKING_BYCALLER);
|
||||
while ((num = getline(&buf, &len, fp)) != -1) {
|
||||
- if (strstr(buf, "selinuxfs")) {
|
||||
+ if (strstr(buf, SELINUXFS)) {
|
||||
exists = 1;
|
||||
break;
|
||||
}
|
||||
@@ -79,7 +101,7 @@ static void init_selinuxmnt(void)
|
||||
tmp = strchr(p, ' ');
|
||||
if (!tmp)
|
||||
goto out;
|
||||
- if (!strncmp(tmp + 1, "selinuxfs ", 10)) {
|
||||
+ if (!strncmp(tmp + 1, SELINUXFS" ", strlen(SELINUXFS)+1)) {
|
||||
*tmp = '\0';
|
||||
break;
|
||||
}
|
||||
@@ -87,7 +109,7 @@ static void init_selinuxmnt(void)
|
||||
|
||||
/* If we found something, dup it */
|
||||
if (num > 0)
|
||||
- selinux_mnt = strdup(p);
|
||||
+ verify_selinuxmnt(p);
|
||||
|
||||
out:
|
||||
free(buf);
|
||||
diff --git a/libselinux/src/load_policy.c b/libselinux/src/load_policy.c
|
||||
index 83d2143..0961912 100644
|
||||
--- a/libselinux/src/load_policy.c
|
||||
+++ b/libselinux/src/load_policy.c
|
||||
@@ -369,7 +369,17 @@ int selinux_init_load_policy(int *enforce)
|
||||
* Check for the existence of SELinux via selinuxfs, and
|
||||
* mount it if present for use in the calls below.
|
||||
*/
|
||||
- if (mount("selinuxfs", SELINUXMNT, "selinuxfs", 0, 0) < 0 && errno != EBUSY) {
|
||||
+ char *mntpoint = NULL;
|
||||
+ if (mount(SELINUXFS, SELINUXMNT, SELINUXFS, 0, 0) == 0 || errno == EBUSY) {
|
||||
+ mntpoint = SELINUXMNT;
|
||||
+ } else {
|
||||
+ /* check old mountpoint */
|
||||
+ if (mount(SELINUXFS, OLDSELINUXMNT, SELINUXFS, 0, 0) == 0 || errno == EBUSY) {
|
||||
+ mntpoint = OLDSELINUXMNT;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (! mntpoint ) {
|
||||
if (errno == ENODEV) {
|
||||
/*
|
||||
* SELinux was disabled in the kernel, either
|
||||
@@ -385,7 +395,7 @@ int selinux_init_load_policy(int *enforce)
|
||||
|
||||
goto noload;
|
||||
}
|
||||
- set_selinuxmnt(SELINUXMNT);
|
||||
+ set_selinuxmnt(mntpoint);
|
||||
|
||||
/*
|
||||
* Note: The following code depends on having selinuxfs
|
||||
@@ -397,7 +407,7 @@ int selinux_init_load_policy(int *enforce)
|
||||
rc = security_disable();
|
||||
if (rc == 0) {
|
||||
/* Successfully disabled, so umount selinuxfs too. */
|
||||
- umount(SELINUXMNT);
|
||||
+ umount(selinux_mnt);
|
||||
fini_selinuxmnt();
|
||||
}
|
||||
/*
|
||||
diff --git a/libselinux/src/matchpathcon.c b/libselinux/src/matchpathcon.c
|
||||
index 5fd8fe4..da5cab9 100644
|
||||
--- a/libselinux/src/matchpathcon.c
|
||||
@ -195,6 +423,27 @@ index 5fd8fe4..da5cab9 100644
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
diff --git a/libselinux/src/policy.h b/libselinux/src/policy.h
|
||||
index 10e8712..bf270b5 100644
|
||||
--- a/libselinux/src/policy.h
|
||||
+++ b/libselinux/src/policy.h
|
||||
@@ -9,11 +9,15 @@
|
||||
/* Initial length guess for getting contexts. */
|
||||
#define INITCONTEXTLEN 255
|
||||
|
||||
+/* selinux file system type */
|
||||
+#define SELINUXFS "selinuxfs"
|
||||
+
|
||||
/* selinuxfs magic number */
|
||||
#define SELINUX_MAGIC 0xf97cff8c
|
||||
|
||||
/* Preferred selinux mount location */
|
||||
-#define SELINUXMNT "/selinux"
|
||||
+#define SELINUXMNT "/sys/fs/selinux"
|
||||
+#define OLDSELINUXMNT "/selinux"
|
||||
|
||||
/* selinuxfs mount point */
|
||||
extern char *selinux_mnt;
|
||||
diff --git a/libselinux/src/selinux.py b/libselinux/src/selinux.py
|
||||
index fd63a4f..248048a 100644
|
||||
--- a/libselinux/src/selinux.py
|
||||
@ -1375,3 +1624,199 @@ index e0884f6..b131d2e 100644
|
||||
SWIG_Python_SetConstant(d, "SELINUX_AVD_FLAGS_PERMISSIVE",SWIG_From_int((int)(0x0001)));
|
||||
SWIG_Python_SetConstant(d, "SELINUX_CB_LOG",SWIG_From_int((int)(0)));
|
||||
SWIG_Python_SetConstant(d, "SELINUX_CB_AUDIT",SWIG_From_int((int)(1)));
|
||||
diff --git a/libselinux/utils/matchpathcon.c b/libselinux/utils/matchpathcon.c
|
||||
index 4453a88..f1fe506 100644
|
||||
--- a/libselinux/utils/matchpathcon.c
|
||||
+++ b/libselinux/utils/matchpathcon.c
|
||||
@@ -8,6 +8,49 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/errno.h>
|
||||
#include <selinux/selinux.h>
|
||||
+#include <limits.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+
|
||||
+static int symlink_realpath(char *name, char *path)
|
||||
+{
|
||||
+ char *p = NULL, *file_sep;
|
||||
+ char *tmp_path = strdupa(name);
|
||||
+ size_t len = 0;
|
||||
+
|
||||
+ if (!tmp_path) {
|
||||
+ fprintf(stderr, "strdupa on %s failed: %s\n", name,
|
||||
+ strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+ file_sep = strrchr(tmp_path, '/');
|
||||
+ if (file_sep == tmp_path) {
|
||||
+ file_sep++;
|
||||
+ p = strcpy(path, "");
|
||||
+ } else if (file_sep) {
|
||||
+ *file_sep = 0;
|
||||
+ file_sep++;
|
||||
+ p = realpath(tmp_path, path);
|
||||
+ } else {
|
||||
+ file_sep = tmp_path;
|
||||
+ p = realpath("./", path);
|
||||
+ }
|
||||
+ if (p)
|
||||
+ len = strlen(p);
|
||||
+ if (!p || len + strlen(file_sep) + 2 > PATH_MAX) {
|
||||
+ fprintf(stderr, "symlink_realpath(%s) failed %s\n", name,
|
||||
+ strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+ p += len;
|
||||
+ /* ensure trailing slash of directory name */
|
||||
+ if (len == 0 || *(p - 1) != '/') {
|
||||
+ *p = '/';
|
||||
+ p++;
|
||||
+ }
|
||||
+ strcpy(p, file_sep);
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
void usage(const char *progname)
|
||||
{
|
||||
@@ -103,49 +146,66 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
for (i = optind; i < argc; i++) {
|
||||
+ char lnkpath[PATH_MAX + 1];
|
||||
int mode = 0;
|
||||
struct stat buf;
|
||||
+ char *newpath = NULL;
|
||||
+ char *path;
|
||||
int len = strlen(argv[i]);
|
||||
if (len > 1 && argv[i][len - 1 ] == '/') {
|
||||
argv[i][len - 1 ] = '\0';
|
||||
}
|
||||
|
||||
- if (lstat(argv[i], &buf) == 0)
|
||||
+ if (lstat(argv[i], &buf) == 0) {
|
||||
mode = buf.st_mode;
|
||||
+ }
|
||||
+
|
||||
+ path = argv[i];
|
||||
+ if (S_ISLNK(mode)) {
|
||||
+ int rc = symlink_realpath(argv[i], lnkpath);
|
||||
+ if (rc >= 0) {
|
||||
+ path = lnkpath;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if ((newpath = realpath(argv[i], NULL))) {
|
||||
+ path = newpath;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
if (verify) {
|
||||
if (quiet) {
|
||||
- if (selinux_file_context_verify(argv[i], mode))
|
||||
+ if (selinux_file_context_verify(path, mode))
|
||||
continue;
|
||||
else
|
||||
exit(1);
|
||||
}
|
||||
- if (selinux_file_context_verify(argv[i], mode)) {
|
||||
- printf("%s verified.\n", argv[i]);
|
||||
+ if (selinux_file_context_verify(path, mode)) {
|
||||
+ printf("%s verified.\n", path);
|
||||
} else {
|
||||
security_context_t con;
|
||||
int rc;
|
||||
error = 1;
|
||||
if (notrans)
|
||||
- rc = lgetfilecon_raw(argv[i], &con);
|
||||
+ rc = lgetfilecon_raw(path, &con);
|
||||
else
|
||||
- rc = lgetfilecon(argv[i], &con);
|
||||
+ rc = lgetfilecon(path, &con);
|
||||
|
||||
if (rc >= 0) {
|
||||
printf("%s has context %s, should be ",
|
||||
argv[i], con);
|
||||
- printmatchpathcon(argv[i], 0, mode);
|
||||
+ printmatchpathcon(path, 0, mode);
|
||||
freecon(con);
|
||||
} else {
|
||||
printf
|
||||
("actual context unknown: %s, should be ",
|
||||
strerror(errno));
|
||||
- printmatchpathcon(argv[i], 0, mode);
|
||||
+ printmatchpathcon(path, 0, mode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
- error |= printmatchpathcon(argv[i], header, mode);
|
||||
+ error |= printmatchpathcon(path, header, mode);
|
||||
}
|
||||
+ free(newpath); newpath = NULL;
|
||||
}
|
||||
matchpathcon_fini();
|
||||
return error;
|
||||
diff --git a/libselinux/utils/selinuxexeccon.c b/libselinux/utils/selinuxexeccon.c
|
||||
new file mode 100644
|
||||
index 0000000..c55fde9
|
||||
--- /dev/null
|
||||
+++ b/libselinux/utils/selinuxexeccon.c
|
||||
@@ -0,0 +1,60 @@
|
||||
+#include <unistd.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <errno.h>
|
||||
+#include <string.h>
|
||||
+#include <ctype.h>
|
||||
+#include <selinux/flask.h>
|
||||
+#include <selinux/selinux.h>
|
||||
+
|
||||
+void usage(char *name, char *detail, int rc)
|
||||
+{
|
||||
+ fprintf(stderr, "usage: %s command [ fromcon ]\n", name);
|
||||
+ if (detail)
|
||||
+ fprintf(stderr, "%s: %s\n", name, detail);
|
||||
+ exit(rc);
|
||||
+}
|
||||
+
|
||||
+static security_context_t get_selinux_proc_context(const char *command, security_context_t execcon) {
|
||||
+ security_context_t fcon = NULL, newcon = NULL;
|
||||
+
|
||||
+ int ret = getfilecon(command, &fcon);
|
||||
+ if (ret < 0) goto err;
|
||||
+ ret = security_compute_create(execcon, fcon, SECCLASS_PROCESS, &newcon);
|
||||
+ if (ret < 0) goto err;
|
||||
+
|
||||
+err:
|
||||
+ freecon(fcon);
|
||||
+ return newcon;
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char **argv)
|
||||
+{
|
||||
+ int ret = -1;
|
||||
+ security_context_t proccon = NULL, con = NULL;
|
||||
+ if (argc < 2 || argc > 3)
|
||||
+ usage(argv[0], "Invalid number of arguments", -1);
|
||||
+
|
||||
+ if (argc == 2) {
|
||||
+ if (getcon(&con) < 0) {
|
||||
+ perror(argv[0]);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ } else {
|
||||
+ con = strdup(argv[2]);
|
||||
+ }
|
||||
+
|
||||
+ proccon = get_selinux_proc_context(argv[1], con);
|
||||
+ if (proccon) {
|
||||
+ printf("%s\n", proccon);
|
||||
+ ret = 0;
|
||||
+ } else {
|
||||
+ perror(argv[0]);
|
||||
+ }
|
||||
+
|
||||
+ free(proccon);
|
||||
+ free(con);
|
||||
+ return ret;
|
||||
+}
|
||||
|
@ -7,7 +7,7 @@
|
||||
Summary: SELinux library and simple utilities
|
||||
Name: libselinux
|
||||
Version: 2.0.102
|
||||
Release: 4%{?dist}
|
||||
Release: 5%{?dist}
|
||||
License: Public Domain
|
||||
Group: System Environment/Libraries
|
||||
Source: http://www.nsa.gov/research/selinux/%{name}-%{version}.tgz
|
||||
@ -198,6 +198,7 @@ exit 0
|
||||
%{_sbindir}/matchpathcon
|
||||
%{_sbindir}/selinuxconlist
|
||||
%{_sbindir}/selinuxdefcon
|
||||
%{_sbindir}/selinuxexeccon
|
||||
%{_sbindir}/selinuxenabled
|
||||
%{_sbindir}/setenforce
|
||||
%{_sbindir}/togglesebool
|
||||
@ -236,6 +237,11 @@ exit 0
|
||||
%{ruby_sitearch}/selinux.so
|
||||
|
||||
%changelog
|
||||
* Fri Apr 29 2011 Dan Walsh <dwalsh@redhat.com> - 2.0.102-5
|
||||
- Move /selinux to /sys/fs/selinux
|
||||
- Add selinuxexeccon
|
||||
- Add realpath to matchpathcon to handle matchpathcon * type queries.
|
||||
|
||||
* Thu Apr 21 2011 Dan Walsh <dwalsh@redhat.com> - 2.0.102-4
|
||||
- Update for latest libsepol
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user