* [RFC][PATCH] New interface for loading policy
@ 2005-09-29 21:20 Stephen Smalley
2005-09-29 21:38 ` Daniel J Walsh
` (2 more replies)
0 siblings, 3 replies; 23+ messages in thread
From: Stephen Smalley @ 2005-09-29 21:20 UTC (permalink / raw)
To: selinux; +Cc: Daniel J Walsh, Ivan Gyurdiev, SELinux-dev
[-- Attachment #1: Type: text/plain, Size: 1689 bytes --]
Hi,
In the past, there have been discussions about the need to migrate more
of the policy loading logic that currently resides in init and
load_policy into a higher level libselinux function than the current
security_load_policy(3) interface. This will allow us to evolve that
logic more easily, without needing to re-patch init each time (as was
done first for the booleans and then for local users) as well as
eliminating code duplication.
Below are sample patches for libselinux and policycoreutils to implement
a new selinux_mkload_policy(3) interface and to rewrite load_policy to
use it. Since load_policy presently requires that you specify the
policy file path as an argument, I retained support for specifying the
path in the interface, without requiring it, with load_policy warning on
the old usage but continuing to accept it. I did however drop the
support for specifying a booleans file other than the default location
entirely, as it was optional and doesn't seem to be used in practice. I
also retained the ability to specify whether booleans should be
preserved across a load or reset to the policy settings in the interface
for use by load_policy (on policy updates, when you don't want to
disturb the active boolean settings).
However, at least the support for specifying the policy path doesn't
seem likely to survive when the policy server is introduced. Hence, I
was wondering if I should just drop it now. In that case, we need to
decide whether load_policy will just warn about the old usage but
proceed to load the active policy (so that current users aren't broken)
or warn and fail in that case.
Comments?
--
Stephen Smalley
National Security Agency
[-- Attachment #2: libselinux-mkload.patch --]
[-- Type: text/x-patch, Size: 4225 bytes --]
Index: libselinux/include/selinux/selinux.h
===================================================================
RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/include/selinux/selinux.h,v
retrieving revision 1.44
diff -u -p -r1.44 selinux.h
--- libselinux/include/selinux/selinux.h 31 Aug 2005 15:56:15 -0000 1.44
+++ libselinux/include/selinux/selinux.h 29 Sep 2005 19:34:14 -0000
@@ -171,6 +171,20 @@ extern int security_compute_user_raw(sec
/* Load a policy configuration. */
extern int security_load_policy(void *data, size_t len);
+/*
+ * Make a policy image and load it.
+ * This function provides a higher level interface for loading policy
+ * than security_load_policy, handling the creation of the policy image
+ * as well as the loading internally.
+ *
+ * 'path' is optional and may be NULL, in which case the
+ * active policy configuration will be used.
+ *
+ * 'preservebools' indicates whether current boolean values should
+ * be preserved (if 1) or reset to the policy settings (if 0).
+ */
+extern int selinux_mkload_policy(const char *path, int preservebools);
+
/* Translate boolean strict to name value pair. */
typedef struct {
char *name;
Index: libselinux/src/Makefile
===================================================================
RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/Makefile,v
retrieving revision 1.27
diff -u -p -r1.27 Makefile
--- libselinux/src/Makefile 18 Jul 2005 13:42:20 -0000 1.27
+++ libselinux/src/Makefile 29 Sep 2005 19:41:07 -0000
@@ -22,7 +22,7 @@ $(LIBA): $(OBJS)
$(RANLIB) $@
$(LIBSO): $(LOBJS)
- $(CC) $(LDFLAGS) -shared -o $@ $^ -ldl -Wl,-soname,$(LIBSO),-z,defs
+ $(CC) $(LDFLAGS) -shared -o $@ $^ -ldl -lsepol -Wl,-soname,$(LIBSO),-z,defs
ln -sf $@ $(TARGET)
%.o: %.c policy.h
Index: libselinux/src/load_policy.c
===================================================================
RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/load_policy.c,v
retrieving revision 1.5
diff -u -p -r1.5 load_policy.c
--- libselinux/src/load_policy.c 18 Dec 2003 17:33:47 -0000 1.5
+++ libselinux/src/load_policy.c 29 Sep 2005 19:49:51 -0000
@@ -1,10 +1,13 @@
#include <unistd.h>
#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <selinux/selinux.h>
+#include <sepol/sepol.h>
#include "policy.h"
#include <limits.h>
@@ -25,3 +28,76 @@ int security_load_policy(void *data, siz
return 0;
}
+int selinux_mkload_policy(const char *polpath, int preservebools)
+{
+ int vers = security_policyvers();
+ char path[PATH_MAX], **names;
+ struct stat sb;
+ size_t size;
+ void *map, *data;
+ int fd, rc = -1, *values, len, i;
+
+ if (vers < 0)
+ return -1;
+
+ if (polpath) {
+ fd = open(polpath, O_RDONLY);
+ } else {
+ snprintf(path, sizeof(path), "%s.%d",
+ selinux_binary_policy_path(), vers);
+ fd = open(path, O_RDONLY);
+ while (fd < 0 && errno == ENOENT && --vers > 0) {
+ /* Check prior versions to see if old policy is available */
+ snprintf(path, sizeof(path), "%s.%d",
+ selinux_binary_policy_path(), vers);
+ fd = open(path, O_RDONLY);
+ }
+ }
+ if (fd < 0)
+ return -1;
+
+ if (fstat(fd, &sb) < 0)
+ goto close;
+
+ size = sb.st_size;
+ data = map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ if (map == MAP_FAILED)
+ goto close;
+
+ rc = sepol_genusers(data, size, selinux_users_path(), &data, &size);
+ if (rc < 0) {
+ /* Fall back to the base image if genusers failed. */
+ data = map;
+ size = sb.st_size;
+ rc = 0;
+ }
+
+ if (!preservebools) {
+ (void) sepol_genbools(data, size, (char*)selinux_booleans_path());
+ } else {
+ rc = security_get_boolean_names(&names, &len);
+ if (!rc) {
+ values = malloc(sizeof(int)*len);
+ if (!values)
+ goto unmap;
+ for (i = 0; i < len; i++)
+ values[i] = security_get_boolean_active(names[i]);
+ (void) sepol_genbools_array(data, size, names, values, len);
+ free(values);
+ for (i = 0; i < len; i++)
+ free(names[i]);
+ free(names);
+ }
+ }
+
+ rc = security_load_policy(data, size);
+
+unmap:
+ if (data != map)
+ free(data);
+ munmap(map, sb.st_size);
+close:
+ close(fd);
+ return rc;
+}
+
[-- Attachment #3: policycoreutils-mkload.patch --]
[-- Type: text/x-patch, Size: 4829 bytes --]
Index: policycoreutils/load_policy/load_policy.c
===================================================================
RCS file: /nfshome/pal/CVS/selinux-usr/policycoreutils/load_policy/load_policy.c,v
retrieving revision 1.18
diff -u -p -r1.18 load_policy.c
--- policycoreutils/load_policy/load_policy.c 11 Jul 2005 19:18:41 -0000 1.18
+++ policycoreutils/load_policy/load_policy.c 29 Sep 2005 20:28:27 -0000
@@ -1,12 +1,7 @@
#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
-#include <string.h>
#include <errno.h>
-#include <sys/mman.h>
#include <getopt.h>
#include <selinux/selinux.h>
#include <sepol/sepol.h>
@@ -23,18 +18,14 @@
void usage(char *progname)
{
- fprintf(stderr, _("usage: %s [-q] [-b] policyfile [booleanfile]\n"), progname);
+ fprintf(stderr, _("usage: %s [-q] [policyfile]\n"), progname);
exit(1);
}
int main(int argc, char **argv)
{
- int fd, ret, opt, quiet=0, setbools = 0, *values;
- int i, len;
- size_t data_size;
- struct stat sb;
- void *map, *data;
- char *polpath, *boolpath = NULL, **names;
+ int ret, opt, quiet=0, setbools = 0, i, nargs;
+ char *polpath = NULL;
#ifdef USE_NLS
setlocale (LC_ALL, "");
@@ -56,100 +47,22 @@ int main(int argc, char **argv)
}
}
- if ((argc-optind) != 1 && (argc-optind) != 2) {
+ nargs = argc - optind;
+ if (nargs > 2)
usage(argv[0]);
+ if (nargs >= 1) {
+ fprintf(stderr, "%s: Warning! Policy file argument (%s) is now optional, will default to active policy if left unspecified. Continuing...\n", argv[0], argv[optind]);
+ polpath = argv[optind++];
}
-
- if ((argc - optind) == 2) {
- /* Implicit enable when they specify a boolean file */
- setbools = 1;
- }
-
- polpath = argv[optind++];
- fd = open(polpath, O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, _("Can't open '%s': %s\n"),
- polpath, strerror(errno));
- exit(2);
- }
-
- if (fstat(fd, &sb) < 0) {
- fprintf(stderr, _("Can't stat '%s': %s\n"),
- polpath, strerror(errno));
- exit(2);
- }
-
- map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
- if (map == MAP_FAILED) {
- fprintf(stderr, _("Can't map '%s': %s\n"),
- polpath, strerror(errno));
- exit(2);
+ if (nargs == 2) {
+ fprintf(stderr, "%s: Warning! Boolean file argument %s is no longer supported. Ignoring...\n", argv[0], argv[optind++]);
}
- ret = sepol_genusers(map, sb.st_size, selinux_users_path(), &data, &data_size);
+ ret = selinux_mkload_policy(polpath, !setbools);
if (ret < 0) {
- /* No users file; non-fatal. */
- if (! quiet)
- fprintf(stderr, _("%s: Error while setting user configuration from %s/{local.users,system.users}: %s\n"), argv[0], selinux_users_path(), strerror(errno));
- data = map;
- data_size = sb.st_size;
- }
-
- if (setbools) {
- /* Set booleans based on a booleans configuration file. */
- boolpath = (optind < argc) ? argv[optind++] : (char*) selinux_booleans_path();
- ret = sepol_genbools(data, data_size, boolpath);
- if (ret < 0) {
- if (errno == ENOENT || errno == EINVAL) {
- /* No booleans file or stale booleans in the file; non-fatal. */
- if (! quiet)
- fprintf(stderr, _("%s: Warning while setting booleans from %s\n"), argv[0], boolpath);
- } else {
- fprintf(stderr, _("%s: Error while setting booleans from %s: %s\n"), argv[0], boolpath, strerror(errno));
- exit(2);
- }
- }
- } else {
- /* Preserve current boolean values. */
- ret = security_get_boolean_names(&names, &len);
- if (ret) {
- /* Possibly ok, as there may be no booleans. */
- if (! quiet)
- fprintf(stderr, _("%s: Warning! unable to get boolean names: %s\n"), argv[0], strerror(errno));
- goto load;
- }
- if (!len)
- goto load;
- values = malloc(sizeof(int)*len);
- if (!values) {
- fprintf(stderr, _("%s: out of memory\n"), argv[0]);
- exit(2);
- }
- for (i = 0; i < len; i++) {
- values[i] = security_get_boolean_active(names[i]);
- if (values[i] < 0) {
- fprintf(stderr, _("%s: Error while getting value for boolean %s: %s\n"), argv[0], names[i], strerror(errno));
- exit(2);
- }
- }
- ret = sepol_genbools_array(data, data_size, names, values, len);
- if (ret < 0) {
- if (errno == EINVAL) {
- /* Stale booleans in the file; non-fatal. */
- if (! quiet)
- fprintf(stderr, _("%s: Warning! Unable to reset all booleans\n"), argv[0]);
- } else {
- fprintf(stderr, _("%s: Error while setting booleans: %s\n"), argv[0], strerror(errno));
- exit(2);
- }
- }
- }
-load:
- ret = security_load_policy(data, data_size);
- if (ret < 0) {
- fprintf(stderr, _("%s: security_load_policy failed\n"), argv[0]);
- exit(3);
+ fprintf(stderr, _("Can't load '%s': %s\n"),
+ polpath ? polpath : "policy", strerror(errno));
+ exit(2);
}
-
exit(0);
}
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [RFC][PATCH] New interface for loading policy 2005-09-29 21:20 [RFC][PATCH] New interface for loading policy Stephen Smalley @ 2005-09-29 21:38 ` Daniel J Walsh 2005-09-30 3:48 ` Ivan Gyurdiev 2005-09-30 14:53 ` Karl MacMillan 2 siblings, 0 replies; 23+ messages in thread From: Daniel J Walsh @ 2005-09-29 21:38 UTC (permalink / raw) To: Stephen Smalley; +Cc: selinux, Ivan Gyurdiev, SELinux-dev Stephen Smalley wrote: >Hi, > >In the past, there have been discussions about the need to migrate more >of the policy loading logic that currently resides in init and >load_policy into a higher level libselinux function than the current >security_load_policy(3) interface. This will allow us to evolve that >logic more easily, without needing to re-patch init each time (as was >done first for the booleans and then for local users) as well as >eliminating code duplication. > >Below are sample patches for libselinux and policycoreutils to implement >a new selinux_mkload_policy(3) interface and to rewrite load_policy to >use it. Since load_policy presently requires that you specify the >policy file path as an argument, I retained support for specifying the >path in the interface, without requiring it, with load_policy warning on >the old usage but continuing to accept it. I did however drop the >support for specifying a booleans file other than the default location >entirely, as it was optional and doesn't seem to be used in practice. I >also retained the ability to specify whether booleans should be >preserved across a load or reset to the policy settings in the interface >for use by load_policy (on policy updates, when you don't want to >disturb the active boolean settings). > >However, at least the support for specifying the policy path doesn't >seem likely to survive when the policy server is introduced. Hence, I >was wondering if I should just drop it now. In that case, we need to >decide whether load_policy will just warn about the old usage but >proceed to load the active policy (so that current users aren't broken) >or warn and fail in that case. > >Comments? > > Eliminate it from the new interface. I don't believe that anyone is using that feature to try out various policies, and the code is currently hacky to figure out where the booleans and users files are anyways. >------------------------------------------------------------------------ > >Index: libselinux/include/selinux/selinux.h >=================================================================== >RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/include/selinux/selinux.h,v >retrieving revision 1.44 >diff -u -p -r1.44 selinux.h >--- libselinux/include/selinux/selinux.h 31 Aug 2005 15:56:15 -0000 1.44 >+++ libselinux/include/selinux/selinux.h 29 Sep 2005 19:34:14 -0000 >@@ -171,6 +171,20 @@ extern int security_compute_user_raw(sec > /* Load a policy configuration. */ > extern int security_load_policy(void *data, size_t len); > >+/* >+ * Make a policy image and load it. >+ * This function provides a higher level interface for loading policy >+ * than security_load_policy, handling the creation of the policy image >+ * as well as the loading internally. >+ * >+ * 'path' is optional and may be NULL, in which case the >+ * active policy configuration will be used. >+ * >+ * 'preservebools' indicates whether current boolean values should >+ * be preserved (if 1) or reset to the policy settings (if 0). >+ */ >+extern int selinux_mkload_policy(const char *path, int preservebools); >+ > /* Translate boolean strict to name value pair. */ > typedef struct { > char *name; >Index: libselinux/src/Makefile >=================================================================== >RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/Makefile,v >retrieving revision 1.27 >diff -u -p -r1.27 Makefile >--- libselinux/src/Makefile 18 Jul 2005 13:42:20 -0000 1.27 >+++ libselinux/src/Makefile 29 Sep 2005 19:41:07 -0000 >@@ -22,7 +22,7 @@ $(LIBA): $(OBJS) > $(RANLIB) $@ > > $(LIBSO): $(LOBJS) >- $(CC) $(LDFLAGS) -shared -o $@ $^ -ldl -Wl,-soname,$(LIBSO),-z,defs >+ $(CC) $(LDFLAGS) -shared -o $@ $^ -ldl -lsepol -Wl,-soname,$(LIBSO),-z,defs > ln -sf $@ $(TARGET) > > %.o: %.c policy.h >Index: libselinux/src/load_policy.c >=================================================================== >RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/load_policy.c,v >retrieving revision 1.5 >diff -u -p -r1.5 load_policy.c >--- libselinux/src/load_policy.c 18 Dec 2003 17:33:47 -0000 1.5 >+++ libselinux/src/load_policy.c 29 Sep 2005 19:49:51 -0000 >@@ -1,10 +1,13 @@ > #include <unistd.h> > #include <sys/types.h> >+#include <sys/stat.h> >+#include <sys/mman.h> > #include <fcntl.h> > #include <stdlib.h> > #include <stdio.h> > #include <errno.h> > #include <selinux/selinux.h> >+#include <sepol/sepol.h> > #include "policy.h" > #include <limits.h> > >@@ -25,3 +28,76 @@ int security_load_policy(void *data, siz > return 0; > } > >+int selinux_mkload_policy(const char *polpath, int preservebools) >+{ >+ int vers = security_policyvers(); >+ char path[PATH_MAX], **names; >+ struct stat sb; >+ size_t size; >+ void *map, *data; >+ int fd, rc = -1, *values, len, i; >+ >+ if (vers < 0) >+ return -1; >+ >+ if (polpath) { >+ fd = open(polpath, O_RDONLY); >+ } else { >+ snprintf(path, sizeof(path), "%s.%d", >+ selinux_binary_policy_path(), vers); >+ fd = open(path, O_RDONLY); >+ while (fd < 0 && errno == ENOENT && --vers > 0) { >+ /* Check prior versions to see if old policy is available */ >+ snprintf(path, sizeof(path), "%s.%d", >+ selinux_binary_policy_path(), vers); >+ fd = open(path, O_RDONLY); >+ } >+ } >+ if (fd < 0) >+ return -1; >+ >+ if (fstat(fd, &sb) < 0) >+ goto close; >+ >+ size = sb.st_size; >+ data = map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); >+ if (map == MAP_FAILED) >+ goto close; >+ >+ rc = sepol_genusers(data, size, selinux_users_path(), &data, &size); >+ if (rc < 0) { >+ /* Fall back to the base image if genusers failed. */ >+ data = map; >+ size = sb.st_size; >+ rc = 0; >+ } >+ >+ if (!preservebools) { >+ (void) sepol_genbools(data, size, (char*)selinux_booleans_path()); >+ } else { >+ rc = security_get_boolean_names(&names, &len); >+ if (!rc) { >+ values = malloc(sizeof(int)*len); >+ if (!values) >+ goto unmap; >+ for (i = 0; i < len; i++) >+ values[i] = security_get_boolean_active(names[i]); >+ (void) sepol_genbools_array(data, size, names, values, len); >+ free(values); >+ for (i = 0; i < len; i++) >+ free(names[i]); >+ free(names); >+ } >+ } >+ >+ rc = security_load_policy(data, size); >+ >+unmap: >+ if (data != map) >+ free(data); >+ munmap(map, sb.st_size); >+close: >+ close(fd); >+ return rc; >+} >+ > > >------------------------------------------------------------------------ > >Index: policycoreutils/load_policy/load_policy.c >=================================================================== >RCS file: /nfshome/pal/CVS/selinux-usr/policycoreutils/load_policy/load_policy.c,v >retrieving revision 1.18 >diff -u -p -r1.18 load_policy.c >--- policycoreutils/load_policy/load_policy.c 11 Jul 2005 19:18:41 -0000 1.18 >+++ policycoreutils/load_policy/load_policy.c 29 Sep 2005 20:28:27 -0000 >@@ -1,12 +1,7 @@ > #include <unistd.h> >-#include <sys/types.h> >-#include <sys/stat.h> >-#include <fcntl.h> > #include <stdlib.h> > #include <stdio.h> >-#include <string.h> > #include <errno.h> >-#include <sys/mman.h> > #include <getopt.h> > #include <selinux/selinux.h> > #include <sepol/sepol.h> >@@ -23,18 +18,14 @@ > > void usage(char *progname) > { >- fprintf(stderr, _("usage: %s [-q] [-b] policyfile [booleanfile]\n"), progname); >+ fprintf(stderr, _("usage: %s [-q] [policyfile]\n"), progname); > exit(1); > } > > int main(int argc, char **argv) > { >- int fd, ret, opt, quiet=0, setbools = 0, *values; >- int i, len; >- size_t data_size; >- struct stat sb; >- void *map, *data; >- char *polpath, *boolpath = NULL, **names; >+ int ret, opt, quiet=0, setbools = 0, i, nargs; >+ char *polpath = NULL; > > #ifdef USE_NLS > setlocale (LC_ALL, ""); >@@ -56,100 +47,22 @@ int main(int argc, char **argv) > } > } > >- if ((argc-optind) != 1 && (argc-optind) != 2) { >+ nargs = argc - optind; >+ if (nargs > 2) > usage(argv[0]); >+ if (nargs >= 1) { >+ fprintf(stderr, "%s: Warning! Policy file argument (%s) is now optional, will default to active policy if left unspecified. Continuing...\n", argv[0], argv[optind]); >+ polpath = argv[optind++]; > } >- >- if ((argc - optind) == 2) { >- /* Implicit enable when they specify a boolean file */ >- setbools = 1; >- } >- >- polpath = argv[optind++]; >- fd = open(polpath, O_RDONLY); >- if (fd < 0) { >- fprintf(stderr, _("Can't open '%s': %s\n"), >- polpath, strerror(errno)); >- exit(2); >- } >- >- if (fstat(fd, &sb) < 0) { >- fprintf(stderr, _("Can't stat '%s': %s\n"), >- polpath, strerror(errno)); >- exit(2); >- } >- >- map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); >- if (map == MAP_FAILED) { >- fprintf(stderr, _("Can't map '%s': %s\n"), >- polpath, strerror(errno)); >- exit(2); >+ if (nargs == 2) { >+ fprintf(stderr, "%s: Warning! Boolean file argument %s is no longer supported. Ignoring...\n", argv[0], argv[optind++]); > } > >- ret = sepol_genusers(map, sb.st_size, selinux_users_path(), &data, &data_size); >+ ret = selinux_mkload_policy(polpath, !setbools); > if (ret < 0) { >- /* No users file; non-fatal. */ >- if (! quiet) >- fprintf(stderr, _("%s: Error while setting user configuration from %s/{local.users,system.users}: %s\n"), argv[0], selinux_users_path(), strerror(errno)); >- data = map; >- data_size = sb.st_size; >- } >- >- if (setbools) { >- /* Set booleans based on a booleans configuration file. */ >- boolpath = (optind < argc) ? argv[optind++] : (char*) selinux_booleans_path(); >- ret = sepol_genbools(data, data_size, boolpath); >- if (ret < 0) { >- if (errno == ENOENT || errno == EINVAL) { >- /* No booleans file or stale booleans in the file; non-fatal. */ >- if (! quiet) >- fprintf(stderr, _("%s: Warning while setting booleans from %s\n"), argv[0], boolpath); >- } else { >- fprintf(stderr, _("%s: Error while setting booleans from %s: %s\n"), argv[0], boolpath, strerror(errno)); >- exit(2); >- } >- } >- } else { >- /* Preserve current boolean values. */ >- ret = security_get_boolean_names(&names, &len); >- if (ret) { >- /* Possibly ok, as there may be no booleans. */ >- if (! quiet) >- fprintf(stderr, _("%s: Warning! unable to get boolean names: %s\n"), argv[0], strerror(errno)); >- goto load; >- } >- if (!len) >- goto load; >- values = malloc(sizeof(int)*len); >- if (!values) { >- fprintf(stderr, _("%s: out of memory\n"), argv[0]); >- exit(2); >- } >- for (i = 0; i < len; i++) { >- values[i] = security_get_boolean_active(names[i]); >- if (values[i] < 0) { >- fprintf(stderr, _("%s: Error while getting value for boolean %s: %s\n"), argv[0], names[i], strerror(errno)); >- exit(2); >- } >- } >- ret = sepol_genbools_array(data, data_size, names, values, len); >- if (ret < 0) { >- if (errno == EINVAL) { >- /* Stale booleans in the file; non-fatal. */ >- if (! quiet) >- fprintf(stderr, _("%s: Warning! Unable to reset all booleans\n"), argv[0]); >- } else { >- fprintf(stderr, _("%s: Error while setting booleans: %s\n"), argv[0], strerror(errno)); >- exit(2); >- } >- } >- } >-load: >- ret = security_load_policy(data, data_size); >- if (ret < 0) { >- fprintf(stderr, _("%s: security_load_policy failed\n"), argv[0]); >- exit(3); >+ fprintf(stderr, _("Can't load '%s': %s\n"), >+ polpath ? polpath : "policy", strerror(errno)); >+ exit(2); > } >- > exit(0); > } > > -- -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC][PATCH] New interface for loading policy 2005-09-29 21:20 [RFC][PATCH] New interface for loading policy Stephen Smalley 2005-09-29 21:38 ` Daniel J Walsh @ 2005-09-30 3:48 ` Ivan Gyurdiev 2005-09-30 12:21 ` Stephen Smalley 2005-09-30 12:51 ` Daniel J Walsh 2005-09-30 14:53 ` Karl MacMillan 2 siblings, 2 replies; 23+ messages in thread From: Ivan Gyurdiev @ 2005-09-30 3:48 UTC (permalink / raw) To: Stephen Smalley; +Cc: selinux, Daniel J Walsh, SELinux-dev >Comments? > > > It doesn't belong in libselinux. I've had an implementation of this for a long time, but I haven't submitted it, because we're changing the plan (right). Boolean and user components will be handled by semanage, using the dbase thing which I'm adding there. Genbools/genusers will be deprecated. Semanage will compile a module, and put users/booleans into that. Then it will re-link modules upon change, and load_policy will ... load the policy. OTOH this may be a good way to get rid of this code from things like init, which needs to happen anyway... P.S. Dan - please take a look at my mail that says that (1) gdm is broken, because it doesn't pay attention to enforcing mode, and (2) MCS is not transparent upon install if you have defined users in local.users (those are rejected post-mcs). Combined those two things prevent you from logging in in *permissive* mode. -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC][PATCH] New interface for loading policy 2005-09-30 3:48 ` Ivan Gyurdiev @ 2005-09-30 12:21 ` Stephen Smalley 2005-09-30 12:35 ` Stephen Smalley ` (2 more replies) 2005-09-30 12:51 ` Daniel J Walsh 1 sibling, 3 replies; 23+ messages in thread From: Stephen Smalley @ 2005-09-30 12:21 UTC (permalink / raw) To: Ivan Gyurdiev; +Cc: selinux, Daniel J Walsh, SELinux-dev On Thu, 2005-09-29 at 23:48 -0400, Ivan Gyurdiev wrote: > It doesn't belong in libselinux. I've had an implementation of this for > a long time, but I haven't submitted it, because we're changing the plan > (right). Boolean and user components will be handled by semanage, using > the dbase thing which I'm adding there. Genbools/genusers will be > deprecated. Semanage will compile a module, and put users/booleans into > that. Then it will re-link modules upon change, and load_policy will ... > load the policy. > > OTOH this may be a good way to get rid of this code from things like > init, which needs to happen anyway... Yes, boolean and user components are expected to be handled by semanage in the future, regenerating the kernel binary policy file on each modification. When that happens, selinux_mkload_policy() can drop out the calls to sepol_genusers and sepol_genbools, but will still encapsulate the logic for finding the right policy version, opening it and mmap'ing it, and loading it. So this change will make it easier to make that transition - we won't need to re-patch sysvinit or load_policy, and will still encapsulate some higher level logic than the current security_load_policy(). BTW, one thing that I'm not clear on is how the preservebools case (the default behavior for load_policy) will be handled in the future. The idea is that if a boolean has been toggled at runtime without altering its saved value (e.g. manually by an admin, or by a cron job that toggles a boolean to enforce different day/night policies, or by an IDS in response to an event), we don't want a subsequent policy reload (e.g. from an update) to reset that boolean value to the saved settings. At present, load_policy (and thus selinux_mkload_policy) grab the active boolean settings from selinuxfs and patch them into the binary policy image via sepol_genbools_array() by default (preservebools=1). My earlier comment about the path needing to go away when the policy server is introduced was a mistake on my part, I think. /sbin/init will still need to directly load a kernel binary policy file into the kernel, as the server won't be running yet, and load_policy will still be run from libsemanage in direct mode (and possibly from the policy server) to load policy files, although it should no longer be directly run by the % post scriptlet in the policy package for updates. Hence, retaining the path as an optional argument isn't necessarily a problem (I think), but we should decide whether we want it. It does offer the flexibility of loading a test policy without first installing it to the standard location, but we don't offer the same flexibility for the other files presently. -- Stephen Smalley National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC][PATCH] New interface for loading policy 2005-09-30 12:21 ` Stephen Smalley @ 2005-09-30 12:35 ` Stephen Smalley 2005-09-30 17:16 ` Stephen Smalley 2005-10-03 13:48 ` Karl MacMillan 2 siblings, 0 replies; 23+ messages in thread From: Stephen Smalley @ 2005-09-30 12:35 UTC (permalink / raw) To: Ivan Gyurdiev; +Cc: selinux, Daniel J Walsh, SELinux-dev On Fri, 2005-09-30 at 08:21 -0400, Stephen Smalley wrote: > Yes, boolean and user components are expected to be handled by semanage > in the future, regenerating the kernel binary policy file on each > modification. When that happens, selinux_mkload_policy() can drop out > the calls to sepol_genusers and sepol_genbools, but will still > encapsulate the logic for finding the right policy version, opening it > and mmap'ing it, and loading it. BTW, the "finding the right policy version" part is what motivated me to go ahead and write this patch now. Someone noted on fedora-list that they couldn't boot 2.6.14-rc2-git6 on FC3, because /sbin/init was only trying to load the current version supported by the kernel (from reading /selinux/policyvers via security_policyvers()) and one version lower if that didn't exist, and there have been two version increments since FC3 was shipped (18->19 for MLS mainstreaming, 19->20 for the avtab optimization), so FC3 only has policy.18. Since we have to fix init and load_policy anyway to continue trying older versions until they finds one that exists (or alternatively they could scandir the directory and just find the closest match to the current version), it seemed sensible to push it all into a libselinux function now so that we don't have to patch them again when the sepol* calls are dropped out. -- Stephen Smalley National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC][PATCH] New interface for loading policy 2005-09-30 12:21 ` Stephen Smalley 2005-09-30 12:35 ` Stephen Smalley @ 2005-09-30 17:16 ` Stephen Smalley 2005-09-30 20:26 ` Daniel J Walsh 2005-10-03 12:56 ` Karl MacMillan 2005-10-03 13:48 ` Karl MacMillan 2 siblings, 2 replies; 23+ messages in thread From: Stephen Smalley @ 2005-09-30 17:16 UTC (permalink / raw) To: Ivan Gyurdiev; +Cc: Karl MacMillan, selinux, Daniel J Walsh, SELinux-dev On Fri, 2005-09-30 at 08:21 -0400, Stephen Smalley wrote: > BTW, one thing that I'm not clear on is how the preservebools case (the > default behavior for load_policy) will be handled in the future. The > idea is that if a boolean has been toggled at runtime without altering > its saved value (e.g. manually by an admin, or by a cron job that > toggles a boolean to enforce different day/night policies, or by an IDS > in response to an event), we don't want a subsequent policy reload (e.g. > from an update) to reset that boolean value to the saved settings. At > present, load_policy (and thus selinux_mkload_policy) grab the active > boolean settings from selinuxfs and patch them into the binary policy > image via sepol_genbools_array() by default (preservebools=1). We seem to have agreed to drop the optional path argument entirely from selinux_mkload_policy(). But we still need to decide whether the preservebools argument is going to make sense going forward. This is for preserving temporary boolean values across a policy reload rather than resetting them to the policy settings and is the default behavior for load_policy (in the absence of the -b option), as noted above. As with the path argument, this argument is not needed for the initial policy load by init, but is only relevant for policy reloads. -- Stephen Smalley National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC][PATCH] New interface for loading policy 2005-09-30 17:16 ` Stephen Smalley @ 2005-09-30 20:26 ` Daniel J Walsh 2005-10-03 12:56 ` Karl MacMillan 1 sibling, 0 replies; 23+ messages in thread From: Daniel J Walsh @ 2005-09-30 20:26 UTC (permalink / raw) To: Stephen Smalley; +Cc: Ivan Gyurdiev, Karl MacMillan, selinux, SELinux-dev Stephen Smalley wrote: > On Fri, 2005-09-30 at 08:21 -0400, Stephen Smalley wrote: > >> BTW, one thing that I'm not clear on is how the preservebools case (the >> default behavior for load_policy) will be handled in the future. The >> idea is that if a boolean has been toggled at runtime without altering >> its saved value (e.g. manually by an admin, or by a cron job that >> toggles a boolean to enforce different day/night policies, or by an IDS >> in response to an event), we don't want a subsequent policy reload (e.g. >> from an update) to reset that boolean value to the saved settings. At >> present, load_policy (and thus selinux_mkload_policy) grab the active >> boolean settings from selinuxfs and patch them into the binary policy >> image via sepol_genbools_array() by default (preservebools=1). >> > > We seem to have agreed to drop the optional path argument entirely from > selinux_mkload_policy(). But we still need to decide whether the > preservebools argument is going to make sense going forward. This is > for preserving temporary boolean values across a policy reload rather > than resetting them to the policy settings and is the default behavior > for load_policy (in the absence of the -b option), as noted above. As > with the path argument, this argument is not needed for the initial > policy load by init, but is only relevant for policy reloads. > > I think you need this behavior for reloads. Or default to always saving the previous state, and forcing me to use setsebool to change particular defaults. Dan -- -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [RFC][PATCH] New interface for loading policy 2005-09-30 17:16 ` Stephen Smalley 2005-09-30 20:26 ` Daniel J Walsh @ 2005-10-03 12:56 ` Karl MacMillan 2005-10-03 14:17 ` Stephen Smalley 1 sibling, 1 reply; 23+ messages in thread From: Karl MacMillan @ 2005-10-03 12:56 UTC (permalink / raw) To: 'Stephen Smalley', 'Ivan Gyurdiev' Cc: selinux, 'Daniel J Walsh', SELinux-dev > -----Original Message----- > From: Stephen Smalley [mailto:sds@tycho.nsa.gov] > Sent: Friday, September 30, 2005 1:16 PM > To: Ivan Gyurdiev > Cc: Karl MacMillan; selinux@tycho.nsa.gov; Daniel J Walsh; SELinux- > dev@tresys.com > Subject: Re: [RFC][PATCH] New interface for loading policy > > On Fri, 2005-09-30 at 08:21 -0400, Stephen Smalley wrote: > > BTW, one thing that I'm not clear on is how the preservebools case (the > > default behavior for load_policy) will be handled in the future. The > > idea is that if a boolean has been toggled at runtime without altering > > its saved value (e.g. manually by an admin, or by a cron job that > > toggles a boolean to enforce different day/night policies, or by an IDS > > in response to an event), we don't want a subsequent policy reload (e.g. > > from an update) to reset that boolean value to the saved settings. At > > present, load_policy (and thus selinux_mkload_policy) grab the active > > boolean settings from selinuxfs and patch them into the binary policy > > image via sepol_genbools_array() by default (preservebools=1). > > We seem to have agreed to drop the optional path argument entirely from > selinux_mkload_policy(). But we still need to decide whether the > preservebools argument is going to make sense going forward. This is > for preserving temporary boolean values across a policy reload rather > than resetting them to the policy settings and is the default behavior > for load_policy (in the absence of the -b option), as noted above. As > with the path argument, this argument is not needed for the initial > policy load by init, but is only relevant for policy reloads. > I think that it needs to remain. In the future all requests for changing bools, either persistently or temporarily, should go through the policy server so that it can a) notify all security servers and b) enforce access control over the changes. It does not, however, make sense to save all states to disk. This means that load_policy needs to take care of saving the state on reload. I think this is significantly "safer" than the users case - the fallback is the defaults in the on-disk policy. Karl ------ Karl MacMillan Tresys Technology http://www.tresys.com > -- > Stephen Smalley > National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [RFC][PATCH] New interface for loading policy 2005-10-03 12:56 ` Karl MacMillan @ 2005-10-03 14:17 ` Stephen Smalley 2005-10-04 12:41 ` Karl MacMillan 0 siblings, 1 reply; 23+ messages in thread From: Stephen Smalley @ 2005-10-03 14:17 UTC (permalink / raw) To: Karl MacMillan Cc: 'Ivan Gyurdiev', selinux, 'Daniel J Walsh', SELinux-dev On Mon, 2005-10-03 at 08:56 -0400, Karl MacMillan wrote: > I think that it needs to remain. In the future all requests for changing > bools, either persistently or temporarily, should go through the policy > server so that it can a) notify all security servers and b) enforce access > control over the changes. It does not, however, make sense to save all > states to disk. This means that load_policy needs to take care of saving the > state on reload. I think this is significantly "safer" than the users case - > the fallback is the defaults in the on-disk policy. True. The only potential concern is that we are trying to preserve the active boolean values of the booleans that were defined in the previous policy in the new policy. If the boolean is no longer defined at all, we just skip it. But if a given boolean name has changed its semantic meaning between the policies, then preserving its value could have interesting effects. -- Stephen Smalley National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [RFC][PATCH] New interface for loading policy 2005-10-03 14:17 ` Stephen Smalley @ 2005-10-04 12:41 ` Karl MacMillan 0 siblings, 0 replies; 23+ messages in thread From: Karl MacMillan @ 2005-10-04 12:41 UTC (permalink / raw) To: 'Stephen Smalley' Cc: 'Ivan Gyurdiev', selinux, 'Daniel J Walsh', SELinux-dev > -----Original Message----- > From: Stephen Smalley [mailto:sds@tycho.nsa.gov] > Sent: Monday, October 03, 2005 10:18 AM > To: Karl MacMillan > Cc: 'Ivan Gyurdiev'; selinux@tycho.nsa.gov; 'Daniel J Walsh'; SELinux- > dev@tresys.com > Subject: RE: [RFC][PATCH] New interface for loading policy > > On Mon, 2005-10-03 at 08:56 -0400, Karl MacMillan wrote: > > I think that it needs to remain. In the future all requests for changing > > bools, either persistently or temporarily, should go through the policy > > server so that it can a) notify all security servers and b) enforce > access > > control over the changes. It does not, however, make sense to save all > > states to disk. This means that load_policy needs to take care of saving > the > > state on reload. I think this is significantly "safer" than the users > case - > > the fallback is the defaults in the on-disk policy. > > True. The only potential concern is that we are trying to preserve the > active boolean values of the booleans that were defined in the previous > policy in the new policy. If the boolean is no longer defined at all, > we just skip it. But if a given boolean name has changed its semantic > meaning between the policies, then preserving its value could have > interesting effects. > This is a general problem that we can't solve, though. What if role names suddenly change meaning - then my local.users file is probably very wrong. These kinds of large policy changes probably require careful upgrading, including things like taking the machine offline, changing customization files (user, Booleans, etc.), and a reboot. So, not really a worry for this case I think. And, of course, load_policy should take an option to not preserve the state. Karl ------ Karl MacMillan Tresys Technology http://www.tresys.com > -- > Stephen Smalley > National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [RFC][PATCH] New interface for loading policy 2005-09-30 12:21 ` Stephen Smalley 2005-09-30 12:35 ` Stephen Smalley 2005-09-30 17:16 ` Stephen Smalley @ 2005-10-03 13:48 ` Karl MacMillan 2005-10-03 14:22 ` Stephen Smalley 2 siblings, 1 reply; 23+ messages in thread From: Karl MacMillan @ 2005-10-03 13:48 UTC (permalink / raw) To: 'Stephen Smalley', 'Ivan Gyurdiev' Cc: selinux, 'Daniel J Walsh', SELinux-dev > -----Original Message----- > From: Stephen Smalley [mailto:sds@tycho.nsa.gov] > Sent: Friday, September 30, 2005 8:22 AM > To: Ivan Gyurdiev > Cc: selinux@tycho.nsa.gov; Daniel J Walsh; SELinux-dev@tresys.com > Subject: Re: [RFC][PATCH] New interface for loading policy > > On Thu, 2005-09-29 at 23:48 -0400, Ivan Gyurdiev wrote: > > It doesn't belong in libselinux. I've had an implementation of this for > > a long time, but I haven't submitted it, because we're changing the plan > > (right). Boolean and user components will be handled by semanage, using > > the dbase thing which I'm adding there. Genbools/genusers will be > > deprecated. Semanage will compile a module, and put users/booleans into > > that. Then it will re-link modules upon change, and load_policy will ... > > load the policy. > > > > OTOH this may be a good way to get rid of this code from things like > > init, which needs to happen anyway... > > Yes, boolean and user components are expected to be handled by semanage > in the future, regenerating the kernel binary policy file on each > modification. When that happens, selinux_mkload_policy() can drop out > the calls to sepol_genusers and sepol_genbools, but will still > encapsulate the logic for finding the right policy version, opening it > and mmap'ing it, and loading it. So this change will make it easier to > make that transition - we won't need to re-patch sysvinit or > load_policy, and will still encapsulate some higher level logic than the > current security_load_policy(). > Agreed. How can libselinux support module and non-module installs then, though? Seems like it needs to determine whether it is handling the adding of users, etc or it has been handled already. If you make it an option passed in as an arg, libsemanage can just call it correctly (either directly or through an option to load_policy). Karl ------ Karl MacMillan Tresys Technology http://www.tresys.com > -- > Stephen Smalley > National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [RFC][PATCH] New interface for loading policy 2005-10-03 13:48 ` Karl MacMillan @ 2005-10-03 14:22 ` Stephen Smalley 2005-10-03 14:37 ` Daniel J Walsh 2005-10-03 14:40 ` Karl MacMillan 0 siblings, 2 replies; 23+ messages in thread From: Stephen Smalley @ 2005-10-03 14:22 UTC (permalink / raw) To: Karl MacMillan Cc: 'Ivan Gyurdiev', selinux, 'Daniel J Walsh', SELinux-dev On Mon, 2005-10-03 at 09:48 -0400, Karl MacMillan wrote: > Agreed. How can libselinux support module and non-module installs then, > though? Seems like it needs to determine whether it is handling the adding > of users, etc or it has been handled already. If you make it an option > passed in as an arg, libsemanage can just call it correctly (either directly > or through an option to load_policy). I assumed that even with a non-module install, libsemanage (or policy server) would handle regeneration of the kernel binary policy file with all local settings (users, saved/persistent booleans) so that libselinux can just load that file unmodified except possibly for preserving the current boolean settings in the preservebools case. So I didn't think we needed to retain the sepol_genusers/sepol_genbools support in the libselinux function at all once we have converted over to the new approach. -- Stephen Smalley National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC][PATCH] New interface for loading policy 2005-10-03 14:22 ` Stephen Smalley @ 2005-10-03 14:37 ` Daniel J Walsh 2005-10-03 14:40 ` Karl MacMillan 1 sibling, 0 replies; 23+ messages in thread From: Daniel J Walsh @ 2005-10-03 14:37 UTC (permalink / raw) To: Stephen Smalley Cc: Karl MacMillan, 'Ivan Gyurdiev', selinux, SELinux-dev Stephen Smalley wrote: > On Mon, 2005-10-03 at 09:48 -0400, Karl MacMillan wrote: > >> Agreed. How can libselinux support module and non-module installs then, >> though? Seems like it needs to determine whether it is handling the adding >> of users, etc or it has been handled already. If you make it an option >> passed in as an arg, libsemanage can just call it correctly (either directly >> or through an option to load_policy). >> > > I assumed that even with a non-module install, libsemanage (or policy > server) would handle regeneration of the kernel binary policy file with > all local settings (users, saved/persistent booleans) so that libselinux > can just load that file unmodified except possibly for preserving the > current boolean settings in the preservebools case. So I didn't think > we needed to retain the sepol_genusers/sepol_genbools support in the > libselinux function at all once we have converted over to the new > approach. > > We do need to handle the transition stage though. -- -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [RFC][PATCH] New interface for loading policy 2005-10-03 14:22 ` Stephen Smalley 2005-10-03 14:37 ` Daniel J Walsh @ 2005-10-03 14:40 ` Karl MacMillan 2005-10-03 15:41 ` Stephen Smalley 1 sibling, 1 reply; 23+ messages in thread From: Karl MacMillan @ 2005-10-03 14:40 UTC (permalink / raw) To: 'Stephen Smalley' Cc: 'Ivan Gyurdiev', selinux, 'Daniel J Walsh', SELinux-dev > -----Original Message----- > From: Stephen Smalley [mailto:sds@tycho.nsa.gov] > Sent: Monday, October 03, 2005 10:22 AM > To: Karl MacMillan > Cc: 'Ivan Gyurdiev'; selinux@tycho.nsa.gov; 'Daniel J Walsh'; SELinux- > dev@tresys.com > Subject: RE: [RFC][PATCH] New interface for loading policy > > On Mon, 2005-10-03 at 09:48 -0400, Karl MacMillan wrote: > > Agreed. How can libselinux support module and non-module installs then, > > though? Seems like it needs to determine whether it is handling the > adding > > of users, etc or it has been handled already. If you make it an option > > passed in as an arg, libsemanage can just call it correctly (either > directly > > or through an option to load_policy). > > I assumed that even with a non-module install, libsemanage (or policy > server) would handle regeneration of the kernel binary policy file with > all local settings (users, saved/persistent booleans) so that libselinux > can just load that file unmodified except possibly for preserving the > current boolean settings in the preservebools case. So I didn't think > we needed to retain the sepol_genusers/sepol_genbools support in the > libselinux function at all once we have converted over to the new > approach. > I guess I meant backwards compatibility - are you suggesting to drop that? Karl ------ Karl MacMillan Tresys Technology http://www.tresys.com > -- > Stephen Smalley > National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [RFC][PATCH] New interface for loading policy 2005-10-03 14:40 ` Karl MacMillan @ 2005-10-03 15:41 ` Stephen Smalley 2005-10-03 19:01 ` Stephen Smalley 0 siblings, 1 reply; 23+ messages in thread From: Stephen Smalley @ 2005-10-03 15:41 UTC (permalink / raw) To: Karl MacMillan Cc: 'Ivan Gyurdiev', selinux, 'Daniel J Walsh', SELinux-dev On Mon, 2005-10-03 at 10:40 -0400, Karl MacMillan wrote: > I guess I meant backwards compatibility - are you suggesting to drop that? Hmm...I suppose not. Although, AFAIK, only Fedora is using the local booleans and users support presently, and they could always coordinate the update of the entire infrastructure. Ok, so it sounds like we want to drop the optional path argument, retain the preservebools flag argument and its functionality, and add a setlocaldefs flag argument to control the use of sepol_genusers/genbools functionality. -- Stephen Smalley National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [RFC][PATCH] New interface for loading policy 2005-10-03 15:41 ` Stephen Smalley @ 2005-10-03 19:01 ` Stephen Smalley 2005-10-05 14:10 ` Stephen Smalley 2005-10-05 21:12 ` Stephen Smalley 0 siblings, 2 replies; 23+ messages in thread From: Stephen Smalley @ 2005-10-03 19:01 UTC (permalink / raw) To: Karl MacMillan Cc: 'Ivan Gyurdiev', selinux, 'Daniel J Walsh', SELinux-dev [-- Attachment #1: Type: text/plain, Size: 1578 bytes --] On Mon, 2005-10-03 at 11:41 -0400, Stephen Smalley wrote: > Ok, so it sounds like we want to drop the optional path argument, retain > the preservebools flag argument and its functionality, and add a > setlocaldefs flag argument to control the use of sepol_genusers/genbools > functionality. Updated patches for libselinux and load_policy below. New interface takes the two flag arguments, as discussed. load_policy defaults to loading local user definitions but preserving current boolean values (setlocaldefs=1, preservebools=1), but allows disabling either or both behaviors via -l and -b: -l Suppress loading of local users. -b Suppress preservation of current booleans. -lb No modification of the binary policy file at all prior to load. /sbin/init would call the interface with (setlocaldefs=1, preservebools=0), equivalent to load_policy -b as before. However, note that this means that the init SELinux patch still has to change when the new infrastructure for regenerating binary policy files upon all policy changes is in place, to instead call the interface with (setlocaldefs=0,preservebools=0), equivalent to load_policy -lb. That seems unfortunate, and could be avoided if we hid the setting of setlocaldefs within libselinux. Possibly libselinux could determine setlocaldefs automatically based on an /etc/selinux/config setting, and we could just change that setting when the new infrastructure is in place? Thereby removing it from the load interface and dropping down to just the preservebools flag there? -- Stephen Smalley National Security Agency [-- Attachment #2: libselinux-mkload2.patch --] [-- Type: text/x-patch, Size: 4839 bytes --] Index: libselinux/include/selinux/selinux.h =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/include/selinux/selinux.h,v retrieving revision 1.45 diff -u -p -r1.45 selinux.h --- libselinux/include/selinux/selinux.h 30 Sep 2005 18:27:17 -0000 1.45 +++ libselinux/include/selinux/selinux.h 3 Oct 2005 17:16:17 -0000 @@ -171,6 +171,27 @@ extern int security_compute_user_raw(sec /* Load a policy configuration. */ extern int security_load_policy(void *data, size_t len); +/* + * Make a policy image and load it. + * This function provides a higher level interface for loading policy + * than security_load_policy, internally determining the right policy + * version, locating and opening the policy file, mapping it into memory, + * manipulating it as needed for current boolean settings and/or local + * definitions, and then calling security_load_policy to load it. + * + * 'setlocaldefs' is a boolean flag indicating whether local policy + * definitions (booleans, users) should be applied to the policy image + * prior to loading (if 1) or not (if 0). The latter case is for when + * the policy file has already been regenerated with all local settings. + * + * 'preservebools' is a boolean flag indicating whether current + * policy boolean values should be preserved into the new policy (if 1) + * or reset to the saved policy settings (if 0). The former case is the + * default for policy reloads, while the latter case is an option for policy + * reloads but is primarily for the initial policy load. + */ +extern int selinux_mkload_policy(int setlocaldefs, int preservebools); + /* Translate boolean strict to name value pair. */ typedef struct { char *name; Index: libselinux/src/Makefile =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/Makefile,v retrieving revision 1.27 diff -u -p -r1.27 Makefile --- libselinux/src/Makefile 18 Jul 2005 13:42:20 -0000 1.27 +++ libselinux/src/Makefile 3 Oct 2005 17:07:18 -0000 @@ -22,7 +22,7 @@ $(LIBA): $(OBJS) $(RANLIB) $@ $(LIBSO): $(LOBJS) - $(CC) $(LDFLAGS) -shared -o $@ $^ -ldl -Wl,-soname,$(LIBSO),-z,defs + $(CC) $(LDFLAGS) -shared -o $@ $^ -ldl -lsepol -Wl,-soname,$(LIBSO),-z,defs ln -sf $@ $(TARGET) %.o: %.c policy.h Index: libselinux/src/load_policy.c =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/load_policy.c,v retrieving revision 1.5 diff -u -p -r1.5 load_policy.c --- libselinux/src/load_policy.c 18 Dec 2003 17:33:47 -0000 1.5 +++ libselinux/src/load_policy.c 3 Oct 2005 17:21:11 -0000 @@ -1,10 +1,13 @@ #include <unistd.h> #include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <selinux/selinux.h> +#include <sepol/sepol.h> #include "policy.h" #include <limits.h> @@ -25,3 +28,78 @@ int security_load_policy(void *data, siz return 0; } +int selinux_mkload_policy(int setlocaldefs, int preservebools) +{ + int vers = security_policyvers(); + char path[PATH_MAX], **names; + struct stat sb; + size_t size; + void *map, *data; + int fd, rc = -1, *values, len, i, prot; + + if (vers < 0) + return -1; + + snprintf(path, sizeof(path), "%s.%d", + selinux_binary_policy_path(), vers); + fd = open(path, O_RDONLY); + while (fd < 0 && errno == ENOENT && --vers > 0) { + /* Check prior versions to see if old policy is available */ + snprintf(path, sizeof(path), "%s.%d", + selinux_binary_policy_path(), vers); + fd = open(path, O_RDONLY); + } + if (fd < 0) + return -1; + + if (fstat(fd, &sb) < 0) + goto close; + + prot = PROT_READ; + if (setlocaldefs || preservebools) + prot |= PROT_WRITE; + + size = sb.st_size; + data = map = mmap(NULL, size, prot, MAP_PRIVATE, fd, 0); + if (map == MAP_FAILED) + goto close; + + if (setlocaldefs) { + rc = sepol_genusers(data, size, selinux_users_path(), &data, &size); + if (rc < 0) { + /* Fall back to the base image if genusers failed. */ + data = map; + size = sb.st_size; + rc = 0; + } + } + + if (preservebools) { + rc = security_get_boolean_names(&names, &len); + if (!rc) { + values = malloc(sizeof(int)*len); + if (!values) + goto unmap; + for (i = 0; i < len; i++) + values[i] = security_get_boolean_active(names[i]); + (void) sepol_genbools_array(data, size, names, values, len); + free(values); + for (i = 0; i < len; i++) + free(names[i]); + free(names); + } + } else if (setlocaldefs) { + (void) sepol_genbools(data, size, (char*)selinux_booleans_path()); + } + + rc = security_load_policy(data, size); + +unmap: + if (data != map) + free(data); + munmap(map, sb.st_size); +close: + close(fd); + return rc; +} + [-- Attachment #3: policycoreutils-mkload2.patch --] [-- Type: text/x-patch, Size: 6660 bytes --] Index: policycoreutils/load_policy/load_policy.8 =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/policycoreutils/load_policy/load_policy.8,v retrieving revision 1.2 diff -u -p -r1.2 load_policy.8 --- policycoreutils/load_policy/load_policy.8 26 Aug 2004 17:05:09 -0000 1.2 +++ policycoreutils/load_policy/load_policy.8 3 Oct 2005 18:15:57 -0000 @@ -1,22 +1,28 @@ .TH LOAD_POLICY "8" "May 2003" "Security Enhanced Linux" NSA .SH NAME -load_policy \- load a newly compiled policy into the kernel +load_policy \- load a new policy into the kernel .SH SYNOPSIS .B load_policy -[-q] [-b] policyfile [booleanfile] +[-blq] .br .SH DESCRIPTION .PP load_policy is the tool used to load/replace the policy in the kernel. -By default, load_policy will maintain the booleans settings from the previous policy. +By default, load_policy will preserve the current policy boolean values +and will set local definitions prior to loading the policy. + +.SH "OPTIONS" +.TP +.B \-b +reset the policy boolean values to the saved policy settings. +.TP +.B \-l +ignore local definitions, use only the policy definitions. .TP -.B -q -quiet mode. Do not report warning messages. -.B -b -replace the booleans settings with the ones from the [booleanfile] or the default on the system /etc/selinux/$SELINUXTYPE/booleans. (SELINUXTYPE is defined in /etc/selinux/config). +.B \-q +suppress warning messages. -.SH FILES .SH SEE ALSO .B booleans (8), Index: policycoreutils/load_policy/load_policy.c =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/policycoreutils/load_policy/load_policy.c,v retrieving revision 1.18 diff -u -p -r1.18 load_policy.c --- policycoreutils/load_policy/load_policy.c 11 Jul 2005 19:18:41 -0000 1.18 +++ policycoreutils/load_policy/load_policy.c 3 Oct 2005 18:09:23 -0000 @@ -1,12 +1,7 @@ #include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> #include <stdlib.h> #include <stdio.h> -#include <string.h> #include <errno.h> -#include <sys/mman.h> #include <getopt.h> #include <selinux/selinux.h> #include <sepol/sepol.h> @@ -23,18 +18,13 @@ void usage(char *progname) { - fprintf(stderr, _("usage: %s [-q] [-b] policyfile [booleanfile]\n"), progname); + fprintf(stderr, _("usage: %s [-blq]\n"), progname); exit(1); } int main(int argc, char **argv) { - int fd, ret, opt, quiet=0, setbools = 0, *values; - int i, len; - size_t data_size; - struct stat sb; - void *map, *data; - char *polpath, *boolpath = NULL, **names; + int ret, opt, quiet=0, preservebools = 1, setlocaldefs = 1, i, nargs; #ifdef USE_NLS setlocale (LC_ALL, ""); @@ -42,10 +32,13 @@ int main(int argc, char **argv) textdomain (PACKAGE); #endif - while ((opt = getopt(argc, argv, "qb")) > 0) { + while ((opt = getopt(argc, argv, "blq")) > 0) { switch (opt) { case 'b': - setbools = 1; + preservebools = 0; + break; + case 'l': + setlocaldefs = 0; break; case 'q': quiet = 1; @@ -56,100 +49,21 @@ int main(int argc, char **argv) } } - if ((argc-optind) != 1 && (argc-optind) != 2) { + nargs = argc - optind; + if (nargs > 2) usage(argv[0]); + if (nargs >= 1) { + fprintf(stderr, "%s: Warning! Policy file argument (%s) is no longer supported, installed policy is always loaded. Continuing...\n", argv[0], argv[optind++]); } - - if ((argc - optind) == 2) { - /* Implicit enable when they specify a boolean file */ - setbools = 1; - } - - polpath = argv[optind++]; - fd = open(polpath, O_RDONLY); - if (fd < 0) { - fprintf(stderr, _("Can't open '%s': %s\n"), - polpath, strerror(errno)); - exit(2); - } - - if (fstat(fd, &sb) < 0) { - fprintf(stderr, _("Can't stat '%s': %s\n"), - polpath, strerror(errno)); - exit(2); - } - - map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (map == MAP_FAILED) { - fprintf(stderr, _("Can't map '%s': %s\n"), - polpath, strerror(errno)); - exit(2); + if (nargs == 2) { + fprintf(stderr, "%s: Warning! Boolean file argument (%s) is no longer supported, installed booleans file is always used. Continuing...\n", argv[0], argv[optind++]); } - ret = sepol_genusers(map, sb.st_size, selinux_users_path(), &data, &data_size); + ret = selinux_mkload_policy(setlocaldefs, preservebools); if (ret < 0) { - /* No users file; non-fatal. */ - if (! quiet) - fprintf(stderr, _("%s: Error while setting user configuration from %s/{local.users,system.users}: %s\n"), argv[0], selinux_users_path(), strerror(errno)); - data = map; - data_size = sb.st_size; - } - - if (setbools) { - /* Set booleans based on a booleans configuration file. */ - boolpath = (optind < argc) ? argv[optind++] : (char*) selinux_booleans_path(); - ret = sepol_genbools(data, data_size, boolpath); - if (ret < 0) { - if (errno == ENOENT || errno == EINVAL) { - /* No booleans file or stale booleans in the file; non-fatal. */ - if (! quiet) - fprintf(stderr, _("%s: Warning while setting booleans from %s\n"), argv[0], boolpath); - } else { - fprintf(stderr, _("%s: Error while setting booleans from %s: %s\n"), argv[0], boolpath, strerror(errno)); - exit(2); - } - } - } else { - /* Preserve current boolean values. */ - ret = security_get_boolean_names(&names, &len); - if (ret) { - /* Possibly ok, as there may be no booleans. */ - if (! quiet) - fprintf(stderr, _("%s: Warning! unable to get boolean names: %s\n"), argv[0], strerror(errno)); - goto load; - } - if (!len) - goto load; - values = malloc(sizeof(int)*len); - if (!values) { - fprintf(stderr, _("%s: out of memory\n"), argv[0]); - exit(2); - } - for (i = 0; i < len; i++) { - values[i] = security_get_boolean_active(names[i]); - if (values[i] < 0) { - fprintf(stderr, _("%s: Error while getting value for boolean %s: %s\n"), argv[0], names[i], strerror(errno)); - exit(2); - } - } - ret = sepol_genbools_array(data, data_size, names, values, len); - if (ret < 0) { - if (errno == EINVAL) { - /* Stale booleans in the file; non-fatal. */ - if (! quiet) - fprintf(stderr, _("%s: Warning! Unable to reset all booleans\n"), argv[0]); - } else { - fprintf(stderr, _("%s: Error while setting booleans: %s\n"), argv[0], strerror(errno)); - exit(2); - } - } - } -load: - ret = security_load_policy(data, data_size); - if (ret < 0) { - fprintf(stderr, _("%s: security_load_policy failed\n"), argv[0]); - exit(3); + fprintf(stderr, _("%s: Can't load policy: %s\n"), + argv[0], strerror(errno)); + exit(2); } - exit(0); } ^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [RFC][PATCH] New interface for loading policy 2005-10-03 19:01 ` Stephen Smalley @ 2005-10-05 14:10 ` Stephen Smalley 2005-10-05 21:12 ` Stephen Smalley 1 sibling, 0 replies; 23+ messages in thread From: Stephen Smalley @ 2005-10-05 14:10 UTC (permalink / raw) To: Karl MacMillan Cc: 'Ivan Gyurdiev', selinux, 'Daniel J Walsh', SELinux-dev On Mon, 2005-10-03 at 15:01 -0400, Stephen Smalley wrote: > Updated patches for libselinux and load_policy below. New interface > takes the two flag arguments, as discussed. load_policy defaults to > loading local user definitions but preserving current boolean values > (setlocaldefs=1, preservebools=1), but allows disabling either or both > behaviors via -l and -b: > -l Suppress loading of local users. > -b Suppress preservation of current booleans. > -lb No modification of the binary policy file at all prior to load. > > /sbin/init would call the interface with (setlocaldefs=1, > preservebools=0), equivalent to load_policy -b as before. However, note > that this means that the init SELinux patch still has to change when the > new infrastructure for regenerating binary policy files upon all policy > changes is in place, to instead call the interface with > (setlocaldefs=0,preservebools=0), equivalent to load_policy -lb. That > seems unfortunate, and could be avoided if we hid the setting of > setlocaldefs within libselinux. Possibly libselinux could determine > setlocaldefs automatically based on an /etc/selinux/config setting, and > we could just change that setting when the new infrastructure is in > place? Thereby removing it from the load interface and dropping down to > just the preservebools flag there? Hi, In addition to the questions above re setlocaldefs, I wanted to raise the issue of how libsemanage determines the binary policy version to use when generating the new kernel policy prior to loading. At present, libsemanage uses the highest version supported by the libsepol against which it was built by default, unless configured to use a different version number in semanage.conf, which I've previously noted is already problematic in practice (e.g. new libsepol often shows up before a kernel that supports the new format does, and user may choose to continue using an older kernel even when a newer kernel becomes available). Since these patches remove the policy path from the interface and always determines the path internally (starting with the latest policy version supported by the kernel and searching downward until it finds a policy file with a version less than or equal to that latest version), libsemanage should instead be generating a kernel binary policy file with the latest version supported by the running kernel, i.e. the one obtained via security_policyvers(). Any objections? -- Stephen Smalley National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [RFC][PATCH] New interface for loading policy 2005-10-03 19:01 ` Stephen Smalley 2005-10-05 14:10 ` Stephen Smalley @ 2005-10-05 21:12 ` Stephen Smalley 2005-10-06 16:39 ` Stephen Smalley 1 sibling, 1 reply; 23+ messages in thread From: Stephen Smalley @ 2005-10-05 21:12 UTC (permalink / raw) To: Karl MacMillan Cc: 'Ivan Gyurdiev', selinux, 'Daniel J Walsh', SELinux-dev [-- Attachment #1: Type: text/plain, Size: 1286 bytes --] On Mon, 2005-10-03 at 15:01 -0400, Stephen Smalley wrote: > /sbin/init would call the interface with (setlocaldefs=1, > preservebools=0), equivalent to load_policy -b as before. However, note > that this means that the init SELinux patch still has to change when the > new infrastructure for regenerating binary policy files upon all policy > changes is in place, to instead call the interface with > (setlocaldefs=0,preservebools=0), equivalent to load_policy -lb. That > seems unfortunate, and could be avoided if we hid the setting of > setlocaldefs within libselinux. Possibly libselinux could determine > setlocaldefs automatically based on an /etc/selinux/config setting, and > we could just change that setting when the new infrastructure is in > place? Thereby removing it from the load interface and dropping down to > just the preservebools flag there? Updated patches below. Back to preservebools as the only argument (and -b as the only option to load_policy), with localdefs determined from /etc/selinux/config (defaulting to enabled if not specified). Thus, when we cut over to the new infrastructure, we don't have to repatch /sbin/init again, but only change /etc/selinux/config to include SETLOCALDEFS=1. Look sane? -- Stephen Smalley National Security Agency [-- Attachment #2: libselinux-mkload.patch --] [-- Type: text/x-patch, Size: 10878 bytes --] Index: libselinux/include/selinux/selinux.h =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/include/selinux/selinux.h,v retrieving revision 1.45 diff -u -p -r1.45 selinux.h --- libselinux/include/selinux/selinux.h 30 Sep 2005 18:27:17 -0000 1.45 +++ libselinux/include/selinux/selinux.h 5 Oct 2005 19:56:14 -0000 @@ -171,6 +171,22 @@ extern int security_compute_user_raw(sec /* Load a policy configuration. */ extern int security_load_policy(void *data, size_t len); +/* + * Make a policy image and load it. + * This function provides a higher level interface for loading policy + * than security_load_policy, internally determining the right policy + * version, locating and opening the policy file, mapping it into memory, + * manipulating it as needed for current boolean settings and/or local + * definitions, and then calling security_load_policy to load it. + * + * 'preservebools' is a boolean flag indicating whether current + * policy boolean values should be preserved into the new policy (if 1) + * or reset to the saved policy settings (if 0). The former case is the + * default for policy reloads, while the latter case is an option for policy + * reloads but is primarily for the initial policy load. + */ +extern int selinux_mkload_policy(int preservebools); + /* Translate boolean strict to name value pair. */ typedef struct { char *name; Index: libselinux/src/Makefile =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/Makefile,v retrieving revision 1.27 diff -u -p -r1.27 Makefile --- libselinux/src/Makefile 18 Jul 2005 13:42:20 -0000 1.27 +++ libselinux/src/Makefile 5 Oct 2005 19:55:32 -0000 @@ -22,7 +22,7 @@ $(LIBA): $(OBJS) $(RANLIB) $@ $(LIBSO): $(LOBJS) - $(CC) $(LDFLAGS) -shared -o $@ $^ -ldl -Wl,-soname,$(LIBSO),-z,defs + $(CC) $(LDFLAGS) -shared -o $@ $^ -ldl -lsepol -Wl,-soname,$(LIBSO),-z,defs ln -sf $@ $(TARGET) %.o: %.c policy.h Index: libselinux/src/booleans.c =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/booleans.c,v retrieving revision 1.19 diff -u -p -r1.19 booleans.c --- libselinux/src/booleans.c 25 Aug 2005 14:11:38 -0000 1.19 +++ libselinux/src/booleans.c 5 Oct 2005 20:20:46 -0000 @@ -91,6 +91,7 @@ bad_freen: bad: goto out; } +hidden_def(security_get_boolean_names) #define STRBUF_SIZE 3 static int get_bool_value(const char *name, char **buf) Index: libselinux/src/load_policy.c =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/load_policy.c,v retrieving revision 1.5 diff -u -p -r1.5 load_policy.c --- libselinux/src/load_policy.c 18 Dec 2003 17:33:47 -0000 1.5 +++ libselinux/src/load_policy.c 5 Oct 2005 20:22:24 -0000 @@ -1,10 +1,13 @@ #include <unistd.h> #include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> -#include <selinux/selinux.h> +#include "selinux_internal.h" +#include <sepol/sepol.h> #include "policy.h" #include <limits.h> @@ -24,4 +27,82 @@ int security_load_policy(void *data, siz return -1; return 0; } +hidden_def(security_load_policy) + +int load_setlocaldefs hidden = 1; + +int selinux_mkload_policy(int preservebools) +{ + int vers = security_policyvers(); + char path[PATH_MAX], **names; + struct stat sb; + size_t size; + void *map, *data; + int fd, rc = -1, *values, len, i, prot; + + if (vers < 0) + return -1; + + snprintf(path, sizeof(path), "%s.%d", + selinux_binary_policy_path(), vers); + fd = open(path, O_RDONLY); + while (fd < 0 && errno == ENOENT && --vers > 0) { + /* Check prior versions to see if old policy is available */ + snprintf(path, sizeof(path), "%s.%d", + selinux_binary_policy_path(), vers); + fd = open(path, O_RDONLY); + } + if (fd < 0) + return -1; + + if (fstat(fd, &sb) < 0) + goto close; + + prot = PROT_READ; + if (load_setlocaldefs || preservebools) + prot |= PROT_WRITE; + + size = sb.st_size; + data = map = mmap(NULL, size, prot, MAP_PRIVATE, fd, 0); + if (map == MAP_FAILED) + goto close; + + if (load_setlocaldefs) { + rc = sepol_genusers(data, size, selinux_users_path(), &data, &size); + if (rc < 0) { + /* Fall back to the base image if genusers failed. */ + data = map; + size = sb.st_size; + rc = 0; + } + } + + if (preservebools) { + rc = security_get_boolean_names(&names, &len); + if (!rc) { + values = malloc(sizeof(int)*len); + if (!values) + goto unmap; + for (i = 0; i < len; i++) + values[i] = security_get_boolean_active(names[i]); + (void) sepol_genbools_array(data, size, names, values, len); + free(values); + for (i = 0; i < len; i++) + free(names[i]); + free(names); + } + } else if (load_setlocaldefs) { + (void) sepol_genbools(data, size, (char*)selinux_booleans_path()); + } + + rc = security_load_policy(data, size); + +unmap: + if (data != map) + free(data); + munmap(map, sb.st_size); +close: + close(fd); + return rc; +} Index: libselinux/src/policyvers.c =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/policyvers.c,v retrieving revision 1.5 diff -u -p -r1.5 policyvers.c --- libselinux/src/policyvers.c 9 Apr 2004 15:20:59 -0000 1.5 +++ libselinux/src/policyvers.c 5 Oct 2005 20:24:04 -0000 @@ -4,9 +4,10 @@ #include <stdlib.h> #include <errno.h> #include <string.h> -#include <selinux/selinux.h> +#include "selinux_internal.h" #include <stdio.h> #include "policy.h" +#include "dso.h" #include <limits.h> #define DEFAULT_POLICY_VERSION 15 @@ -37,3 +38,5 @@ int security_policyvers(void) return vers; } +hidden_def(security_policyvers) + Index: libselinux/src/selinux_config.c =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/selinux_config.c,v retrieving revision 1.17 diff -u -p -r1.17 selinux_config.c --- libselinux/src/selinux_config.c 30 Sep 2005 18:27:18 -0000 1.17 +++ libselinux/src/selinux_config.c 5 Oct 2005 20:54:40 -0000 @@ -15,6 +15,7 @@ #define SELINUXDEFAULT "targeted" #define SELINUXTYPETAG "SELINUXTYPE=" #define SELINUXTAG "SELINUX=" +#define SETLOCALDEFS "SETLOCALDEFS=" /* Indices for file paths arrays. */ #define BINPOLICY 0 @@ -123,45 +124,69 @@ static void init_selinux_policyroot(void static void init_selinux_policyroot(void) { - char *type=SELINUXDEFAULT; - int i=0, len=sizeof(SELINUXTYPETAG)-1, len2; - char buf[4097]; - FILE *cfg; + int i; + size_t rootlen, len; + char *line_buf = NULL, *buf_p; + FILE *fp; + if (selinux_policyroot) return; if (access(SELINUXDIR, F_OK) != 0) { selinux_policyroot = SECURITYDIR; use_compat_file_path = 1; return; } - cfg = fopen(SELINUXCONFIG,"r"); - if (cfg) { - while (fgets_unlocked(buf, 4096, cfg)) { - if (strncmp(buf,SELINUXTYPETAG,len)==0) { - type=buf+len; - break; - } - } - fclose(cfg); + + fp = fopen(SELINUXCONFIG,"r"); + if (fp) { + while (getline(&line_buf, &len, fp) > 0) { + len = strlen(line_buf); /* reset in case of embedded NUL */ + if (line_buf[len - 1] == '\n') + line_buf[len - 1] = 0; + buf_p = line_buf; + while (isspace(*buf_p)) + buf_p++; + if (*buf_p == '#' || *buf_p == 0) + continue; + + if (!strncasecmp(buf_p, SELINUXTYPETAG, + sizeof(SELINUXTYPETAG)-1)) { + char *type, *end; + type = buf_p+sizeof(SELINUXTYPETAG)-1; + end = type + strlen(type)-1; + while ((end > type) && + (isspace(*end) || iscntrl(*end))) { + *end = 0; + end--; + } + rootlen = sizeof(SELINUXDIR) + strlen(type); + selinux_policyroot = malloc(rootlen); + if (!selinux_policyroot) + return; + snprintf(selinux_policyroot, rootlen, "%s%s", + SELINUXDIR, type); + } else if (!strncmp(buf_p, SETLOCALDEFS, + sizeof(SETLOCALDEFS)-1)) { + char *value; + value = buf_p + sizeof(SETLOCALDEFS)-1; + if (isdigit(*value)) + load_setlocaldefs = atoi(value); + else if (strncasecmp(value, "true", sizeof("true")-1)) + load_setlocaldefs = 1; + else if (strncasecmp(value, "false", sizeof("false")-1)) + load_setlocaldefs = 0; + } + } + free(line_buf); + fclose(fp); } - i=strlen(type)-1; - while ((i>=0) && - (isspace(type[i]) || iscntrl(type[i]))) { - type[i]=0; - i--; - } - len=sizeof(SELINUXDIR) + strlen(type); - selinux_policyroot=malloc(len); - if (!selinux_policyroot) - return; - snprintf(selinux_policyroot,len, "%s%s", SELINUXDIR, type); - + for (i = 0; i < NEL; i++) { - len2 = len + strlen(file_path_suffixes_data.str - + file_path_suffixes_idx[i])+1; - file_paths[i] = malloc(len2); + len = rootlen + strlen(file_path_suffixes_data.str + + file_path_suffixes_idx[i])+1; + file_paths[i] = malloc(len); if (!file_paths[i]) return; - snprintf(file_paths[i], len2, "%s%s", selinux_policyroot, + snprintf(file_paths[i], len, "%s%s", selinux_policyroot, file_path_suffixes_data.str + file_path_suffixes_idx[i]); } use_compat_file_path = 0; @@ -220,6 +245,7 @@ hidden_def(selinux_removable_context_pat const char *selinux_binary_policy_path() { return get_path(BINPOLICY); } +hidden_def(selinux_binary_policy_path) const char *selinux_file_context_path() { return get_path(FILE_CONTEXTS); Index: libselinux/src/selinux_internal.h =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/selinux_internal.h,v retrieving revision 1.10 diff -u -p -r1.10 selinux_internal.h --- libselinux/src/selinux_internal.h 30 Sep 2005 18:27:18 -0000 1.10 +++ libselinux/src/selinux_internal.h 5 Oct 2005 20:22:30 -0000 @@ -1,7 +1,10 @@ #include <selinux/selinux.h> #include "dso.h" +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) @@ -38,6 +41,7 @@ hidden_proto(setexeccon_raw) hidden_proto(getfscreatecon_raw) hidden_proto(setfscreatecon_raw) hidden_proto(security_getenforce) +hidden_proto(selinux_binary_policy_path) hidden_proto(selinux_default_context_path) hidden_proto(selinux_failsafe_context_path) hidden_proto(selinux_removable_context_path) @@ -54,3 +58,6 @@ hidden_proto(selinux_usersconf_path); extern int context_translations hidden; extern int hidden trans_to_raw_context(char *trans, char **rawp); extern int hidden raw_to_trans_context(char *raw, char **transp); + +extern int load_setlocaldefs hidden; + [-- Attachment #3: policycoreutils-mkload.patch --] [-- Type: text/x-patch, Size: 6472 bytes --] Index: policycoreutils/load_policy/load_policy.8 =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/policycoreutils/load_policy/load_policy.8,v retrieving revision 1.2 diff -u -p -r1.2 load_policy.8 --- policycoreutils/load_policy/load_policy.8 26 Aug 2004 17:05:09 -0000 1.2 +++ policycoreutils/load_policy/load_policy.8 5 Oct 2005 21:02:17 -0000 @@ -1,22 +1,25 @@ .TH LOAD_POLICY "8" "May 2003" "Security Enhanced Linux" NSA .SH NAME -load_policy \- load a newly compiled policy into the kernel +load_policy \- load a new policy into the kernel .SH SYNOPSIS .B load_policy -[-q] [-b] policyfile [booleanfile] +[-blq] .br .SH DESCRIPTION .PP load_policy is the tool used to load/replace the policy in the kernel. -By default, load_policy will maintain the booleans settings from the previous policy. +By default, load_policy will preserve the current policy boolean values +when loading the policy. + +.SH "OPTIONS" +.TP +.B \-b +reset the policy boolean values to the saved policy settings. .TP -.B -q -quiet mode. Do not report warning messages. -.B -b -replace the booleans settings with the ones from the [booleanfile] or the default on the system /etc/selinux/$SELINUXTYPE/booleans. (SELINUXTYPE is defined in /etc/selinux/config). +.B \-q +suppress warning messages. -.SH FILES .SH SEE ALSO .B booleans (8), Index: policycoreutils/load_policy/load_policy.c =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/policycoreutils/load_policy/load_policy.c,v retrieving revision 1.18 diff -u -p -r1.18 load_policy.c --- policycoreutils/load_policy/load_policy.c 11 Jul 2005 19:18:41 -0000 1.18 +++ policycoreutils/load_policy/load_policy.c 5 Oct 2005 21:01:36 -0000 @@ -1,12 +1,7 @@ #include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> #include <stdlib.h> #include <stdio.h> -#include <string.h> #include <errno.h> -#include <sys/mman.h> #include <getopt.h> #include <selinux/selinux.h> #include <sepol/sepol.h> @@ -23,18 +18,13 @@ void usage(char *progname) { - fprintf(stderr, _("usage: %s [-q] [-b] policyfile [booleanfile]\n"), progname); + fprintf(stderr, _("usage: %s [-bq]\n"), progname); exit(1); } int main(int argc, char **argv) { - int fd, ret, opt, quiet=0, setbools = 0, *values; - int i, len; - size_t data_size; - struct stat sb; - void *map, *data; - char *polpath, *boolpath = NULL, **names; + int ret, opt, quiet=0, preservebools = 1, i, nargs; #ifdef USE_NLS setlocale (LC_ALL, ""); @@ -42,10 +32,10 @@ int main(int argc, char **argv) textdomain (PACKAGE); #endif - while ((opt = getopt(argc, argv, "qb")) > 0) { + while ((opt = getopt(argc, argv, "bq")) > 0) { switch (opt) { case 'b': - setbools = 1; + preservebools = 0; break; case 'q': quiet = 1; @@ -56,100 +46,21 @@ int main(int argc, char **argv) } } - if ((argc-optind) != 1 && (argc-optind) != 2) { + nargs = argc - optind; + if (nargs > 2) usage(argv[0]); + if (nargs >= 1) { + fprintf(stderr, "%s: Warning! Policy file argument (%s) is no longer supported, installed policy is always loaded. Continuing...\n", argv[0], argv[optind++]); } - - if ((argc - optind) == 2) { - /* Implicit enable when they specify a boolean file */ - setbools = 1; - } - - polpath = argv[optind++]; - fd = open(polpath, O_RDONLY); - if (fd < 0) { - fprintf(stderr, _("Can't open '%s': %s\n"), - polpath, strerror(errno)); - exit(2); - } - - if (fstat(fd, &sb) < 0) { - fprintf(stderr, _("Can't stat '%s': %s\n"), - polpath, strerror(errno)); - exit(2); - } - - map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (map == MAP_FAILED) { - fprintf(stderr, _("Can't map '%s': %s\n"), - polpath, strerror(errno)); - exit(2); + if (nargs == 2) { + fprintf(stderr, "%s: Warning! Boolean file argument (%s) is no longer supported, installed booleans file is always used. Continuing...\n", argv[0], argv[optind++]); } - ret = sepol_genusers(map, sb.st_size, selinux_users_path(), &data, &data_size); + ret = selinux_mkload_policy(preservebools); if (ret < 0) { - /* No users file; non-fatal. */ - if (! quiet) - fprintf(stderr, _("%s: Error while setting user configuration from %s/{local.users,system.users}: %s\n"), argv[0], selinux_users_path(), strerror(errno)); - data = map; - data_size = sb.st_size; - } - - if (setbools) { - /* Set booleans based on a booleans configuration file. */ - boolpath = (optind < argc) ? argv[optind++] : (char*) selinux_booleans_path(); - ret = sepol_genbools(data, data_size, boolpath); - if (ret < 0) { - if (errno == ENOENT || errno == EINVAL) { - /* No booleans file or stale booleans in the file; non-fatal. */ - if (! quiet) - fprintf(stderr, _("%s: Warning while setting booleans from %s\n"), argv[0], boolpath); - } else { - fprintf(stderr, _("%s: Error while setting booleans from %s: %s\n"), argv[0], boolpath, strerror(errno)); - exit(2); - } - } - } else { - /* Preserve current boolean values. */ - ret = security_get_boolean_names(&names, &len); - if (ret) { - /* Possibly ok, as there may be no booleans. */ - if (! quiet) - fprintf(stderr, _("%s: Warning! unable to get boolean names: %s\n"), argv[0], strerror(errno)); - goto load; - } - if (!len) - goto load; - values = malloc(sizeof(int)*len); - if (!values) { - fprintf(stderr, _("%s: out of memory\n"), argv[0]); - exit(2); - } - for (i = 0; i < len; i++) { - values[i] = security_get_boolean_active(names[i]); - if (values[i] < 0) { - fprintf(stderr, _("%s: Error while getting value for boolean %s: %s\n"), argv[0], names[i], strerror(errno)); - exit(2); - } - } - ret = sepol_genbools_array(data, data_size, names, values, len); - if (ret < 0) { - if (errno == EINVAL) { - /* Stale booleans in the file; non-fatal. */ - if (! quiet) - fprintf(stderr, _("%s: Warning! Unable to reset all booleans\n"), argv[0]); - } else { - fprintf(stderr, _("%s: Error while setting booleans: %s\n"), argv[0], strerror(errno)); - exit(2); - } - } - } -load: - ret = security_load_policy(data, data_size); - if (ret < 0) { - fprintf(stderr, _("%s: security_load_policy failed\n"), argv[0]); - exit(3); + fprintf(stderr, _("%s: Can't load policy: %s\n"), + argv[0], strerror(errno)); + exit(2); } - exit(0); } ^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [RFC][PATCH] New interface for loading policy 2005-10-05 21:12 ` Stephen Smalley @ 2005-10-06 16:39 ` Stephen Smalley 0 siblings, 0 replies; 23+ messages in thread From: Stephen Smalley @ 2005-10-06 16:39 UTC (permalink / raw) To: Karl MacMillan Cc: 'Ivan Gyurdiev', selinux, 'Daniel J Walsh', SELinux-dev [-- Attachment #1: Type: text/plain, Size: 1419 bytes --] On Wed, 2005-10-05 at 17:12 -0400, Stephen Smalley wrote: > Updated patches below. Back to preservebools as the only argument (and > -b as the only option to load_policy), with localdefs determined > from /etc/selinux/config (defaulting to enabled if not specified). > Thus, when we cut over to the new infrastructure, we don't have to > repatch /sbin/init again, but only change /etc/selinux/config to include > SETLOCALDEFS=1. Look sane? I merged the selinux_mkload_policy function into libselinux 1.27.5. However, when I went back and looked at the sysvinit-selinux.patch, it occurred to me that we should also migrate the remaining logic in the load_policy() function in that patch into a higher level libselinux function built on top of selinux_mkload_policy. While this logic is specific to the initial policy load, it does contain SELinux-specific logic that may change in the future (selinuxfs mount point or even the existence of selinuxfs as a separate fs, interpretation of selinux kernel command line arguments, handling of /etc/selinux/config). Moving it into libselinux also gave me the opportunity to do some cleanup of the logic. The new function is called selinux_init_load_policy(); patch is attached and merged into libselinux 1.27.6. Also attached is the interdiff for the sysvinit-selinux.patch (also obsoletes sysvinit-2.85-selgenusers.patch). -- Stephen Smalley National Security Agency [-- Attachment #2: libselinux-1.27.6.patch --] [-- Type: text/x-patch, Size: 10369 bytes --] Index: libselinux/ChangeLog =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/ChangeLog,v retrieving revision 1.147 retrieving revision 1.148 diff -u -p -r1.147 -r1.148 --- libselinux/ChangeLog 6 Oct 2005 11:40:41 -0000 1.147 +++ libselinux/ChangeLog 6 Oct 2005 16:00:26 -0000 1.148 @@ -1,3 +1,8 @@ +1.27.6 2005-10-06 + * Added selinux_init_load_policy() function as an even higher level + interface for the initial policy load by /sbin/init. This obsoletes + the load_policy() function in the sysvinit-selinux.patch. + 1.27.5 2005-10-06 * Added selinux_mkload_policy() function as a higher level interface for loading policy than the security_load_policy() interface. Index: libselinux/VERSION =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/VERSION,v retrieving revision 1.65 retrieving revision 1.66 diff -u -p -r1.65 -r1.66 --- libselinux/VERSION 6 Oct 2005 11:40:41 -0000 1.65 +++ libselinux/VERSION 6 Oct 2005 16:00:27 -0000 1.66 @@ -1 +1 @@ -1.27.5 +1.27.6 Index: libselinux/include/selinux/selinux.h =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/include/selinux/selinux.h,v retrieving revision 1.46 retrieving revision 1.47 diff -u -p -r1.46 -r1.47 --- libselinux/include/selinux/selinux.h 6 Oct 2005 11:40:41 -0000 1.46 +++ libselinux/include/selinux/selinux.h 6 Oct 2005 16:00:27 -0000 1.47 @@ -187,6 +187,24 @@ extern int security_load_policy(void *da */ extern int selinux_mkload_policy(int preservebools); + +/* + * Perform the initial policy load. + * This function determines the desired enforcing mode, sets the + * the *enforce argument accordingly for the caller to use, sets the + * SELinux kernel enforcing status to match it, and loads the policy. + * It also internally handles the initial selinuxfs mount required to + * perform these actions. + * + * The function returns 0 if everything including the policy load succeeds. + * In this case, init is expected to re-exec itself in order to transition + * to the proper security context. + * Otherwise, the function returns -1, and init must check *enforce to + * determine how to proceed. If enforcing (*enforce > 0), then init should + * halt the system. Otherwise, init may proceed normally without a re-exec. + */ +extern int selinux_init_load_policy(int *enforce); + /* Translate boolean strict to name value pair. */ typedef struct { char *name; Index: libselinux/src/disable.c =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/disable.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -r1.1 -r1.2 --- libselinux/src/disable.c 20 Apr 2004 15:43:15 -0000 1.1 +++ libselinux/src/disable.c 6 Oct 2005 16:00:27 -0000 1.2 @@ -4,7 +4,7 @@ #include <stdlib.h> #include <errno.h> #include <string.h> -#include <selinux/selinux.h> +#include "selinux_internal.h" #include "policy.h" #include <stdio.h> #include <limits.h> @@ -29,3 +29,5 @@ int security_disable(void) return 0; } +hidden_def(security_disable) + Index: libselinux/src/init.c =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/init.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -p -r1.15 -r1.16 --- libselinux/src/init.c 14 Sep 2005 19:51:33 -0000 1.15 +++ libselinux/src/init.c 6 Oct 2005 16:00:27 -0000 1.16 @@ -1,7 +1,6 @@ #include <unistd.h> #include <fcntl.h> #include <string.h> -#include <selinux/selinux.h> #include <stdlib.h> #include <errno.h> #include <ctype.h> @@ -11,6 +10,7 @@ #include "dso.h" #include "policy.h" +#include "selinux_internal.h" char *selinux_mnt = NULL; @@ -73,6 +73,7 @@ void set_selinuxmnt(char *mnt) { selinux_mnt = strdup(mnt); } +hidden_def(set_selinuxmnt) int context_translations hidden; void *translation_lib_handle hidden; Index: libselinux/src/load_policy.c =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/load_policy.c,v retrieving revision 1.6 retrieving revision 1.8 diff -u -p -r1.6 -r1.8 --- libselinux/src/load_policy.c 6 Oct 2005 11:40:41 -0000 1.6 +++ libselinux/src/load_policy.c 6 Oct 2005 16:18:13 -0000 1.8 @@ -2,9 +2,12 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> +#include <sys/mount.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> +#include <ctype.h> +#include <string.h> #include <errno.h> #include "selinux_internal.h" #include <sepol/sepol.h> @@ -105,4 +108,119 @@ close: close(fd); return rc; } +hidden_def(selinux_mkload_policy) +/* + * Mount point for selinuxfs. + * This definition is private to the function below. + * Everything else uses the location determined during + * libselinux startup via /proc/mounts (see init_selinuxmnt). + * We only need the hardcoded definition for the initial mount + * required for the initial policy load. + */ +#define SELINUXMNT "/selinux/" + +int selinux_init_load_policy(int *enforce) +{ + int rc = 0, orig_enforce = 0, seconfig = -2, secmdline = -1; + FILE *cfg; + char buf[4096]; + + /* + * Get desired mode (disabled, permissive, enforcing) from + * /etc/selinux/config. + */ + selinux_getenforcemode(&seconfig); + + /* Check for an override of the mode via the kernel command line. */ + rc = mount("none", "/proc", "proc", 0, 0); + cfg = fopen("/proc/cmdline", "r"); + if (cfg) { + char *tmp; + if (fgets(buf, 4096, cfg) && + (tmp = strstr(buf,"enforcing="))) { + if (tmp == buf || isspace(*(tmp-1))) { + secmdline = atoi(tmp+sizeof("enforcing=")-1); + } + } + fclose(cfg); + } +#define MNT_DETACH 2 + if (rc == 0) + umount2("/proc", MNT_DETACH); + + /* + * Determine the final desired mode. + * Command line argument takes precedence, then config file. + */ + if (secmdline >= 0) + *enforce = secmdline; + else if (seconfig >= 0) + *enforce = seconfig; + else + *enforce = 0; /* unspecified or disabled */ + + /* + * Check for the existence of SELinux via selinuxfs, and + * mount it if present for use in the calls below. + */ + if (mount("none", SELINUXMNT, "selinuxfs", 0, 0) < 0) { + if (errno == ENODEV) { + /* + * SELinux was disabled in the kernel, either + * omitted entirely or disabled at boot via selinux=0. + * This takes precedence over any config or + * commandline enforcing setting. + */ + *enforce = 0; + } + goto noload; + } + set_selinuxmnt(SELINUXMNT); + + /* + * Note: The following code depends on having selinuxfs + * already mounted and selinuxmnt set above. + */ + + if (seconfig == -1) { + /* Runtime disable of SELinux. */ + rc = security_disable(); + if (rc == 0) { + /* Successfully disabled, so umount selinuxfs too. */ + umount(SELINUXMNT); + } + /* + * If we failed to disable, SELinux will still be + * effectively permissive, because no policy is loaded. + * No need to call security_setenforce(0) here. + */ + goto noload; + } + + /* + * If necessary, change the kernel enforcing status to match + * the desired mode. + */ + orig_enforce = rc = security_getenforce(); + if (rc < 0) + goto noload; + if (orig_enforce != *enforce) { + rc = security_setenforce(*enforce); + if (rc < 0) + goto noload; + } + + /* Load the policy. */ + return selinux_mkload_policy(0); + +noload: + /* + * Only return 0 on a successful completion of policy load. + * In any other case, we want to return an error so that init + * knows not to proceed with the re-exec for the domain transition. + * Depending on the *enforce setting, init will halt (> 0) or proceed + * normally (otherwise). + */ + return -1; +} Index: libselinux/src/selinux_config.c =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/selinux_config.c,v retrieving revision 1.18 retrieving revision 1.19 diff -u -p -r1.18 -r1.19 --- libselinux/src/selinux_config.c 6 Oct 2005 11:40:41 -0000 1.18 +++ libselinux/src/selinux_config.c 6 Oct 2005 16:00:27 -0000 1.19 @@ -117,6 +117,7 @@ int selinux_getenforcemode(int *enforce) } return ret; } +hidden_def(selinux_getenforcemode) static char *selinux_policyroot = NULL; Index: libselinux/src/selinux_internal.h =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/selinux_internal.h,v retrieving revision 1.11 retrieving revision 1.12 diff -u -p -r1.11 -r1.12 --- libselinux/src/selinux_internal.h 6 Oct 2005 11:40:41 -0000 1.11 +++ libselinux/src/selinux_internal.h 6 Oct 2005 16:00:27 -0000 1.12 @@ -1,6 +1,9 @@ #include <selinux/selinux.h> #include "dso.h" +hidden_proto(selinux_mkload_policy) +hidden_proto(set_selinuxmnt) +hidden_proto(security_disable) hidden_proto(security_policyvers) hidden_proto(security_load_policy) hidden_proto(security_get_boolean_active) @@ -41,6 +44,7 @@ hidden_proto(setexeccon_raw) hidden_proto(getfscreatecon_raw) hidden_proto(setfscreatecon_raw) hidden_proto(security_getenforce) +hidden_proto(security_setenforce) hidden_proto(selinux_binary_policy_path) hidden_proto(selinux_default_context_path) hidden_proto(selinux_failsafe_context_path) @@ -54,6 +58,7 @@ hidden_proto(selinux_check_passwd_access hidden_proto(matchpathcon_init) hidden_proto(selinux_users_path) hidden_proto(selinux_usersconf_path); +hidden_proto(selinux_getenforcemode); extern int context_translations hidden; extern int hidden trans_to_raw_context(char *trans, char **rawp); Index: libselinux/src/setenforce.c =================================================================== RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/setenforce.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -p -r1.4 -r1.5 --- libselinux/src/setenforce.c 18 Dec 2003 17:33:47 -0000 1.4 +++ libselinux/src/setenforce.c 6 Oct 2005 16:00:27 -0000 1.5 @@ -4,7 +4,7 @@ #include <stdlib.h> #include <errno.h> #include <string.h> -#include <selinux/selinux.h> +#include "selinux_internal.h" #include "policy.h" #include <stdio.h> #include <limits.h> @@ -28,3 +28,4 @@ int security_setenforce(int value) return 0; } +hidden_def(security_setenforce) [-- Attachment #3: sysvinit-selinux.interdiff --] [-- Type: text/x-patch, Size: 4779 bytes --] diff -u sysvinit-2.85/src/init.c sysvinit-2.85/src/init.c --- sysvinit-2.85/src/init.c 2004-08-12 06:25:30.166271148 -0400 +++ sysvinit-2.85/src/init.c 2005-10-06 11:17:41.000000000 -0400 @@ -48,10 +48,7 @@ #include <stdarg.h> #include <sys/syslog.h> #include <sys/time.h> -#include <sys/mman.h> #include <selinux/selinux.h> -#include <sepol/sepol.h> -#include <sys/mount.h> #ifdef __i386__ @@ -108,7 +105,6 @@ int dfl_level = 0; /* Default runlevel */ sig_atomic_t got_cont = 0; /* Set if we received the SIGCONT signal */ sig_atomic_t got_signals; /* Set if we received a signal. */ -int enforcing = -1; /* SELinux enforcing mode */ int emerg_shell = 0; /* Start emergency shell? */ int wrote_wtmp_reboot = 1; /* Set when we wrote the reboot record */ int wrote_utmp_reboot = 1; /* Set when we wrote the reboot record */ @@ -193,146 +189,6 @@ {NULL,0} }; -/* Mount point for selinuxfs. */ -#define SELINUXMNT "/selinux/" - -static int load_policy(int *enforce) -{ - int fd=-1,ret=-1; - int rc=0, orig_enforce; - struct stat sb; - void *map; - char policy_file[PATH_MAX]; - int policy_version=0; - FILE *cfg; - char buf[4096]; - int seconfig = -2; - - selinux_getenforcemode(&seconfig); - - mount("none", "/proc", "proc", 0, 0); - cfg = fopen("/proc/cmdline","r"); - if (cfg) { - char *tmp; - if (fgets(buf,4096,cfg) && (tmp = strstr(buf,"enforcing="))) { - if (tmp == buf || isspace(*(tmp-1))) { - enforcing=atoi(tmp+10); - } - } - fclose(cfg); - } -#define MNT_DETACH 2 - umount2("/proc",MNT_DETACH); - - if (enforcing >=0) - *enforce = enforcing; - else if (seconfig == 1) - *enforce = 1; - - if (mount("none", SELINUXMNT, "selinuxfs", 0, 0) < 0) { - if (errno == ENODEV) { - log(L_VB, "SELinux not supported by kernel: %s\n",SELINUXMNT,strerror(errno)); - *enforce = 0; - } else { - log(L_VB, "Failed to mount %s: %s\n",SELINUXMNT,strerror(errno)); - } - return ret; - } - - set_selinuxmnt(SELINUXMNT); /* set manually since we mounted it */ - - policy_version=security_policyvers(); - if (policy_version < 0) { - log(L_VB, "Can't get policy version: %s\n", strerror(errno)); - goto UMOUNT; - } - - orig_enforce = rc = security_getenforce(); - if (rc < 0) { - log(L_VB, "Can't get SELinux enforcement flag: %s\n", strerror(errno)); - goto UMOUNT; - } - if (enforcing >= 0) { - *enforce = enforcing; - } else if (seconfig == -1) { - *enforce = 0; - rc = security_disable(); - if (rc == 0) umount(SELINUXMNT); - if (rc < 0) { - rc = security_setenforce(0); - if (rc < 0) { - log(L_VB, "Can't disable SELinux: %s\n", strerror(errno)); - goto UMOUNT; - } - } - ret = 0; - goto UMOUNT; - } else if (seconfig >= 0) { - *enforce = seconfig; - if (orig_enforce != *enforce) { - rc = security_setenforce(seconfig); - if (rc < 0) { - log(L_VB, "Can't set SELinux enforcement flag: %s\n", strerror(errno)); - goto UMOUNT; - } - } - } - - snprintf(policy_file,sizeof(policy_file),"%s.%d",selinux_binary_policy_path(),policy_version); - fd = open(policy_file, O_RDONLY); - if (fd < 0) { - /* Check previous version to see if old policy is available - */ - snprintf(policy_file,sizeof(policy_file),"%s.%d",selinux_binary_policy_path(),policy_version-1); - fd = open(policy_file, O_RDONLY); - if (fd < 0) { - log(L_VB, "Can't open '%s.%d': %s\n", - selinux_binary_policy_path(),policy_version,strerror(errno)); - goto UMOUNT; - } - } - - if (fstat(fd, &sb) < 0) { - log(L_VB, "Can't stat '%s': %s\n", - policy_file, strerror(errno)); - goto UMOUNT; - } - - map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (map == MAP_FAILED) { - log(L_VB, "Can't map '%s': %s\n", - policy_file, strerror(errno)); - goto UMOUNT; - } - - - /* Set booleans based on a booleans configuration file. */ - ret = sepol_genbools(map, sb.st_size, selinux_booleans_path()); - if (ret < 0) { - if (errno == ENOENT || errno == EINVAL) { - /* No booleans file or stale booleans in the file; non-fatal. */ - log(L_VB,"Warning! Error while setting booleans: %s\n" - , strerror(errno)); - } else { - log(L_VB,"Error while setting booleans: %s\n", - strerror(errno)); - goto UMOUNT; - } - } - log(L_VB, "Loading security policy\n"); - ret=security_load_policy(map, sb.st_size); - if (ret < 0) { - log(L_VB, "security_load_policy failed\n"); - } - -UMOUNT: - /*umount(SELINUXMNT); */ - if ( fd >= 0) { - close(fd); - } - return(ret); -} - /* * Sleep a number of seconds. * @@ -2725,7 +2581,7 @@ if (getenv("SELINUX_INIT") == NULL) { putenv("SELINUX_INIT=YES"); - if (load_policy(&enforce) == 0 ) { + if (selinux_init_load_policy(&enforce) == 0 ) { execv(myname, argv); } else { if (enforce > 0) { ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [RFC][PATCH] New interface for loading policy 2005-09-30 3:48 ` Ivan Gyurdiev 2005-09-30 12:21 ` Stephen Smalley @ 2005-09-30 12:51 ` Daniel J Walsh 1 sibling, 0 replies; 23+ messages in thread From: Daniel J Walsh @ 2005-09-30 12:51 UTC (permalink / raw) To: Ivan Gyurdiev; +Cc: Stephen Smalley, selinux, SELinux-dev Ivan Gyurdiev wrote: > >> Comments? >> >> >> > It doesn't belong in libselinux. I've had an implementation of this > for a long time, but I haven't submitted it, because we're changing > the plan (right). Boolean and user components will be handled by > semanage, using the dbase thing which I'm adding there. > Genbools/genusers will be deprecated. Semanage will compile a module, > and put users/booleans into that. Then it will re-link modules upon > change, and load_policy will ... load the policy. > > OTOH this may be a good way to get rid of this code from things like > init, which needs to happen anyway... > I agree this is a step toward the final solution. But needs to happen now. > P.S. Dan - please take a look at my mail that says that (1) gdm is > broken, because it doesn't pay attention to enforcing mode, This is fixed in rawhide. gdm-2.8.0.4-3 > and (2) MCS is not transparent upon install if you have defined users > in local.users (those are rejected post-mcs). Combined those two > things prevent you from logging in in *permissive* mode. > I will need to look into this. -- -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [RFC][PATCH] New interface for loading policy 2005-09-29 21:20 [RFC][PATCH] New interface for loading policy Stephen Smalley 2005-09-29 21:38 ` Daniel J Walsh 2005-09-30 3:48 ` Ivan Gyurdiev @ 2005-09-30 14:53 ` Karl MacMillan 2005-09-30 14:59 ` Stephen Smalley 2 siblings, 1 reply; 23+ messages in thread From: Karl MacMillan @ 2005-09-30 14:53 UTC (permalink / raw) To: 'Stephen Smalley', selinux Cc: 'Daniel J Walsh', 'Ivan Gyurdiev', SELinux-dev > -----Original Message----- > From: Stephen Smalley [mailto:sds@tycho.nsa.gov] > Sent: Thursday, September 29, 2005 5:20 PM > To: selinux@tycho.nsa.gov > Cc: Daniel J Walsh; Ivan Gyurdiev; SELinux-dev@tresys.com > Subject: [RFC][PATCH] New interface for loading policy > > Hi, > > In the past, there have been discussions about the need to migrate more > of the policy loading logic that currently resides in init and > load_policy into a higher level libselinux function than the current > security_load_policy(3) interface. This will allow us to evolve that > logic more easily, without needing to re-patch init each time (as was > done first for the booleans and then for local users) as well as > eliminating code duplication. > This will be an interface in addition to the current interface, correct? > Below are sample patches for libselinux and policycoreutils to implement > a new selinux_mkload_policy(3) interface and to rewrite load_policy to > use it. Since load_policy presently requires that you specify the > policy file path as an argument, I retained support for specifying the > path in the interface, without requiring it, with load_policy warning on > the old usage but continuing to accept it. I did however drop the > support for specifying a booleans file other than the default location > entirely, as it was optional and doesn't seem to be used in practice. I > also retained the ability to specify whether booleans should be > preserved across a load or reset to the policy settings in the interface > for use by load_policy (on policy updates, when you don't want to > disturb the active boolean settings). > > However, at least the support for specifying the policy path doesn't > seem likely to survive when the policy server is introduced. Hence, I > was wondering if I should just drop it now. In that case, we need to > decide whether load_policy will just warn about the old usage but > proceed to load the active policy (so that current users aren't broken) > or warn and fail in that case. > It depends on whether the policy server will use this interface or the existing security_load_policy internally to load policy. If it will use selinux_mkload_policy then it will need to be able to specify the path I think. This is especially important if the policy server will be generating different policies for the kernel and one or more userspace security servers. Karl ------ Karl MacMillan Tresys Technology http://www.tresys.com > Comments? > > -- > Stephen Smalley > National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [RFC][PATCH] New interface for loading policy 2005-09-30 14:53 ` Karl MacMillan @ 2005-09-30 14:59 ` Stephen Smalley 2005-09-30 16:28 ` Karl MacMillan 0 siblings, 1 reply; 23+ messages in thread From: Stephen Smalley @ 2005-09-30 14:59 UTC (permalink / raw) To: Karl MacMillan Cc: selinux, 'Daniel J Walsh', 'Ivan Gyurdiev', SELinux-dev On Fri, 2005-09-30 at 10:53 -0400, Karl MacMillan wrote: > This will be an interface in addition to the current interface, correct? Yes, security_load_policy(3) will still be available. Just not used directly any more by init or load_policy, but potentially could be used by others if they want the low level interface. > It depends on whether the policy server will use this interface or the > existing security_load_policy internally to load policy. If it will use > selinux_mkload_policy then it will need to be able to specify the path I > think. This is especially important if the policy server will be generating > different policies for the kernel and one or more userspace security > servers. Hmm...at present, libsemanage installs the binary policy to the standard location and then invokes load_policy in direct mode, right? Is there a reason the policy server would operate differently? selinux_mkload_policy is purely for the kernel policy; it will be used by init for the initial policy load. -- Stephen Smalley National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
* RE: [RFC][PATCH] New interface for loading policy 2005-09-30 14:59 ` Stephen Smalley @ 2005-09-30 16:28 ` Karl MacMillan 0 siblings, 0 replies; 23+ messages in thread From: Karl MacMillan @ 2005-09-30 16:28 UTC (permalink / raw) To: 'Stephen Smalley' Cc: selinux, 'Daniel J Walsh', 'Ivan Gyurdiev', SELinux-dev > -----Original Message----- > From: Stephen Smalley [mailto:sds@tycho.nsa.gov] > Sent: Friday, September 30, 2005 10:59 AM > To: Karl MacMillan > Cc: selinux@tycho.nsa.gov; 'Daniel J Walsh'; 'Ivan Gyurdiev'; SELinux- > dev@tresys.com > Subject: RE: [RFC][PATCH] New interface for loading policy > > On Fri, 2005-09-30 at 10:53 -0400, Karl MacMillan wrote: > > This will be an interface in addition to the current interface, correct? > > Yes, security_load_policy(3) will still be available. Just not used > directly any more by init or load_policy, but potentially could be used > by others if they want the low level interface. > > > It depends on whether the policy server will use this interface or the > > existing security_load_policy internally to load policy. If it will use > > selinux_mkload_policy then it will need to be able to specify the path I > > think. This is especially important if the policy server will be > generating > > different policies for the kernel and one or more userspace security > > servers. > > Hmm...at present, libsemanage installs the binary policy to the standard > location and then invokes load_policy in direct mode, right? Correct. > Is there a > reason the policy server would operate differently? > selinux_mkload_policy is purely for the kernel policy; it will be used > by init for the initial policy load. > As long as the interface is only for the kernel policy then libselinux should always know the correct file. The only thing I was thinking of is if the policy gets split for kernel and uss, but you are right, init will have to be able to rely on always finding the correct policy to load into the kernel, so making certain that libselinux can always find that policy is the right thing to do. Karl ------ Karl MacMillan Tresys Technology http://www.tresys.com > -- > Stephen Smalley > National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message. ^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2005-10-06 16:39 UTC | newest] Thread overview: 23+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-09-29 21:20 [RFC][PATCH] New interface for loading policy Stephen Smalley 2005-09-29 21:38 ` Daniel J Walsh 2005-09-30 3:48 ` Ivan Gyurdiev 2005-09-30 12:21 ` Stephen Smalley 2005-09-30 12:35 ` Stephen Smalley 2005-09-30 17:16 ` Stephen Smalley 2005-09-30 20:26 ` Daniel J Walsh 2005-10-03 12:56 ` Karl MacMillan 2005-10-03 14:17 ` Stephen Smalley 2005-10-04 12:41 ` Karl MacMillan 2005-10-03 13:48 ` Karl MacMillan 2005-10-03 14:22 ` Stephen Smalley 2005-10-03 14:37 ` Daniel J Walsh 2005-10-03 14:40 ` Karl MacMillan 2005-10-03 15:41 ` Stephen Smalley 2005-10-03 19:01 ` Stephen Smalley 2005-10-05 14:10 ` Stephen Smalley 2005-10-05 21:12 ` Stephen Smalley 2005-10-06 16:39 ` Stephen Smalley 2005-09-30 12:51 ` Daniel J Walsh 2005-09-30 14:53 ` Karl MacMillan 2005-09-30 14:59 ` Stephen Smalley 2005-09-30 16:28 ` Karl MacMillan
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.