diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/av_permissions.h libselinux-2.0.47/include/selinux/av_permissions.h --- nsalibselinux/include/selinux/av_permissions.h 2007-11-15 15:52:46.000000000 -0500 +++ libselinux-2.0.47/include/selinux/av_permissions.h 2008-01-11 10:55:14.000000000 -0500 @@ -900,6 +900,8 @@ #define PACKET__SEND 0x00000001UL #define PACKET__RECV 0x00000002UL #define PACKET__RELABELTO 0x00000004UL +#define PACKET__FLOW_IN 0x00000008UL +#define PACKET__FLOW_OUT 0x00000010UL #define KEY__VIEW 0x00000001UL #define KEY__READ 0x00000002UL #define KEY__WRITE 0x00000004UL diff --exclude-from=exclude -N -u -r nsalibselinux/src/audit2why.c libselinux-2.0.47/src/audit2why.c --- nsalibselinux/src/audit2why.c 1969-12-31 19:00:00.000000000 -0500 +++ libselinux-2.0.47/src/audit2why.c 2008-01-22 16:23:59.000000000 -0500 @@ -0,0 +1,460 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define UNKNOWN -1 +#define BADSCON -2 +#define BADTCON -3 +#define BADTCLASS -4 +#define BADPERM -5 +#define BADCOMPUTE -6 +#define NOPOLICY -7 +#define ALLOW 0 +#define DONTAUDIT 1 +#define TERULE 2 +#define BOOLEAN 3 +#define CONSTRAINT 4 +#define RBAC 5 + +struct boolean_t { + char *name; + int active; +}; + +static struct boolean_t **boollist = NULL; +static int boolcnt = 0; + +struct avc_t { + sepol_handle_t *handle; + policydb_t policydb; + sepol_security_id_t ssid; + sepol_security_id_t tsid; + sepol_security_class_t tclass; + sepol_access_vector_t av; +}; + +static struct avc_t *avc = NULL; + +static sidtab_t sidtab; + +static int load_booleans(const sepol_bool_t * boolean, + void *arg __attribute__ ((__unused__))) +{ + boollist[boolcnt] = + (struct boolean_t *)malloc(sizeof(struct boolean_t)); + boollist[boolcnt]->name = strdup(sepol_bool_get_name(boolean)); + boollist[boolcnt]->active = sepol_bool_get_value(boolean); + boolcnt++; + return 0; +} + +static int check_booleans(struct avc_t *avc, struct boolean_t ***bools) +{ + char errormsg[PATH_MAX]; + struct sepol_av_decision avd; + unsigned int reason; + int rc; + int i; + sepol_bool_key_t *key = NULL; + sepol_bool_t *boolean = NULL; + int fcnt = 0; + int *foundlist = calloc(boolcnt, sizeof(int)); + if (!foundlist) { + PyErr_SetString( PyExc_MemoryError, "Out of memory\n"); + return fcnt; + } + for (i = 0; i < boolcnt; i++) { + char *name = boollist[i]->name; + int active = boollist[i]->active; + rc = sepol_bool_key_create(avc->handle, name, &key); + if (rc < 0) { + PyErr_SetString( PyExc_RuntimeError, + "Could not create boolean key.\n"); + break; + } + rc = sepol_bool_query(avc->handle, + (sepol_policydb_t *) & avc->policydb, + key, &boolean); + + if (rc < 0) { + snprintf(errormsg, sizeof(errormsg), + "Could not find boolean %s.\n", name); + PyErr_SetString( PyExc_RuntimeError, errormsg); + break; + } + + sepol_bool_set_value(boolean, !active); + + rc = sepol_bool_set(avc->handle, + (sepol_policydb_t *) & avc->policydb, + key, boolean); + if (rc < 0) { + snprintf(errormsg, sizeof(errormsg), + "Could not set boolean data %s.\n", name); + PyErr_SetString( PyExc_RuntimeError, errormsg); + break; + } + + /* Reproduce the computation. */ + rc = sepol_compute_av_reason(avc->ssid, avc->tsid, avc->tclass, + avc->av, &avd, &reason); + if (rc < 0) { + snprintf(errormsg, sizeof(errormsg), + "Error during access vector computation, skipping..."); + PyErr_SetString( PyExc_RuntimeError, errormsg); + + sepol_bool_free(boolean); + break; + } else { + if (!reason) { + foundlist[fcnt] = i; + fcnt++; + } + sepol_bool_set_value((sepol_bool_t *) boolean, active); + rc = sepol_bool_set(avc->handle, + (sepol_policydb_t *) & avc-> + policydb, key, + (sepol_bool_t *) boolean); + if (rc < 0) { + snprintf(errormsg, sizeof(errormsg), + "Could not set boolean data %s.\n", + name); + + PyErr_SetString( PyExc_RuntimeError, errormsg); + break; + } + } + sepol_bool_free(boolean); + sepol_bool_key_free(key); + key = NULL; + boolean = NULL; + } + if (key) + sepol_bool_key_free(key); + + if (boolean) + sepol_bool_free(boolean); + + if (fcnt > 0) { + *bools = (struct boolean_t **) + calloc(sizeof(struct boolean_t), fcnt + 1); + struct boolean_t *b = (struct boolean_t *) *bools; + for (i = 0; i < fcnt; i++) { + int ctr = foundlist[i]; + b[i].name = strdup(boollist[ctr]->name); + b[i].active = !boollist[ctr]->active; + } + } + free(foundlist); + return fcnt; +} + +static PyObject *finish(PyObject *self __attribute__((unused)), PyObject *args) { + PyObject *result = 0; + + if (PyArg_ParseTuple(args,(char *)":finish")) { + int i = 0; + for (i = 0; i < boolcnt; i++) { + free(boollist[i]->name); + free(boollist[i]); + } + free(boollist); + sepol_sidtab_shutdown(&sidtab); + sepol_sidtab_destroy(&sidtab); + policydb_destroy(&avc->policydb); + sepol_handle_destroy(avc->handle); + free(avc); + avc = NULL; + boollist = NULL; + boolcnt = 0; + + /* Boilerplate to return "None" */ + Py_RETURN_NONE; + } + return result; +} + + +static int __policy_init(const char *init_path) +{ + FILE *fp; + int vers = 0; + char path[PATH_MAX]; + char errormsg[PATH_MAX]; + struct policy_file pf; + int rc; + unsigned int cnt; + + if (init_path) { + strncpy(path, init_path, PATH_MAX); + fp = fopen(path, "r"); + if (!fp) { + snprintf(errormsg, sizeof(errormsg), + "unable to open %s: %s\n", + path, strerror(errno)); + PyErr_SetString( PyExc_ValueError, errormsg); + return 0; // trigger exception + } + } else { + vers = security_policyvers(); + if (vers < 0) { + snprintf(errormsg, sizeof(errormsg), + "Could not get policy version: %s\n", + strerror(errno)); + PyErr_SetString( PyExc_ValueError, errormsg); + return 1; + } + snprintf(path, PATH_MAX, "%s.%d", + selinux_binary_policy_path(), vers); + fp = fopen(path, "r"); + while (!fp && errno == ENOENT && --vers) { + snprintf(path, PATH_MAX, "%s.%d", + selinux_binary_policy_path(), vers); + fp = fopen(path, "r"); + } + if (!fp) { + snprintf(errormsg, sizeof(errormsg), + "unable to open %s.%d: %s\n", + selinux_binary_policy_path(), + security_policyvers(), strerror(errno)); + PyErr_SetString( PyExc_ValueError, errormsg); + return 1; + } + } + + avc = calloc(sizeof(struct avc_t), 1); + if (!avc) { + PyErr_SetString( PyExc_MemoryError, "Out of memory\n"); + return 1; + } + + /* Set up a policydb directly so that we can mutate it later + for booleans and user settings. Otherwise we would just use + sepol_set_policydb_from_file() here. */ + pf.fp = fp; + pf.type = PF_USE_STDIO; + if (policydb_init(&avc->policydb)) { + snprintf(errormsg, sizeof(errormsg), + "policydb_init failed: %s\n", strerror(errno)); + PyErr_SetString( PyExc_RuntimeError, errormsg); + fclose(fp); + return 1; + } + if (policydb_read(&avc->policydb, &pf, 0)) { + snprintf(errormsg, sizeof(errormsg), + "invalid binary policy %s\n", path); + PyErr_SetString( PyExc_ValueError, errormsg); + fclose(fp); + return 1; + } + fclose(fp); + sepol_set_policydb(&avc->policydb); + if (!init_path) { + /* If they didn't specify a full path of a binary policy file, + then also try loading any boolean settings and user + definitions from the active locations. Otherwise, + they can use genpolbools and genpolusers to build a + binary policy file that includes any desired settings + and then apply audit2why -p to the resulting file. + Errors are non-fatal as such settings are optional. */ + sepol_debug(0); + (void)sepol_genbools_policydb(&avc->policydb, + selinux_booleans_path()); + (void)sepol_genusers_policydb(&avc->policydb, + selinux_users_path()); + } + avc->handle = sepol_handle_create(); + + rc = sepol_bool_count(avc->handle, + (sepol_policydb_t *) & avc->policydb, &cnt); + if (rc < 0) { + PyErr_SetString( PyExc_RuntimeError, "unable to get bool count\n"); + return 1; + } + + boollist = calloc(cnt, sizeof(struct boolean_t)); + if (!boollist) { + PyErr_SetString( PyExc_MemoryError, "Out of memory\n"); + return 1; + } + + sepol_bool_iterate(avc->handle, + (const sepol_policydb_t *)&avc->policydb, + load_booleans, (void *)NULL); + + /* Initialize the sidtab for subsequent use by sepol_context_to_sid + and sepol_compute_av_reason. */ + rc = sepol_sidtab_init(&sidtab); + if (rc < 0) { + PyErr_SetString( PyExc_RuntimeError, "unable to init sidtab\n"); + free(boollist); + return 1; + } + sepol_set_sidtab(&sidtab); + return 0; +} + +static PyObject *init(PyObject *self __attribute__((unused)), PyObject *args) { + int result; + char *init_path=NULL; + if (PyArg_ParseTuple(args,(char *)"|s:policy_init",&init_path)) + result = __policy_init(init_path); + return Py_BuildValue("i", result); +} + +#define RETURN(X) \ + PyTuple_SetItem(result, 0, Py_BuildValue("i", X)); \ + return result; + +static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args) { + security_context_t scon; + security_context_t tcon; + char *tclassstr; + PyObject *listObj; + PyObject *strObj; + int numlines; + struct boolean_t **bools; + unsigned int reason; + sepol_security_id_t ssid, tsid; + sepol_security_class_t tclass; + sepol_access_vector_t perm, av; + struct sepol_av_decision avd; + int rc; + int i=0; + PyObject *result = PyTuple_New(2); + if (!result) return NULL; + Py_INCREF(Py_None); + PyTuple_SetItem(result, 1, Py_None); + + if (!PyArg_ParseTuple(args,(char *)"sssO!:audit2why",&scon,&tcon,&tclassstr,&PyList_Type, &listObj)) + return NULL; + + /* get the number of lines passed to us */ + numlines = PyList_Size(listObj); + + /* should raise an error here. */ + if (numlines < 0) return NULL; /* Not a list */ + + if (!avc) { + RETURN(NOPOLICY) + } + + rc = sepol_context_to_sid(scon, strlen(scon) + 1, &ssid); + if (rc < 0) { + RETURN(BADSCON) + } + rc = sepol_context_to_sid(tcon, strlen(tcon) + 1, &tsid); + if (rc < 0) { + RETURN(BADTCON) + } + tclass = string_to_security_class(tclassstr); + if (!tclass) { + RETURN(BADTCLASS) + } + /* Convert the permission list to an AV. */ + av = 0; + + /* iterate over items of the list, grabbing strings, and parsing + for numbers */ + for (i=0; issid = ssid; + avc->tsid = tsid; + avc->tclass = tclass; + avc->av = av; + if (check_booleans(avc, &bools) == 0) { + if (av & ~avd.auditdeny) { + RETURN(DONTAUDIT) + } else { + RETURN(TERULE) + } + } else { + PyTuple_SetItem(result, 0, Py_BuildValue("i", BOOLEAN)); + struct boolean_t *b=(struct boolean_t *) bools; + int len=0; + while (b->name) { + len++; b++; + } + b = (struct boolean_t *) bools; + PyObject *boollist = PyTuple_New(len); + len=0; + while(b->name) { + PyObject *bool = Py_BuildValue("(si)", b->name, b->active); + PyTuple_SetItem(boollist, len++, bool); + b++; + } + free(bools); + PyTuple_SetItem(result, 1, boollist); + return result; + } + } + + if (reason & SEPOL_COMPUTEAV_CONS) { + RETURN(CONSTRAINT); + } + + if (reason & SEPOL_COMPUTEAV_RBAC) { + RETURN(RBAC) + } + RETURN(BADCOMPUTE) +} + +static PyMethodDef audit2whyMethods[] = { + {"init", init, METH_VARARGS, + "Initialize policy database."}, + {"analyze", analyze, METH_VARARGS, + "Analyze AVC."}, + {"finish", finish, METH_VARARGS, + "Finish using policy, free memory."}, + {NULL, NULL, 0, NULL} /* Sentinel */ +}; + +PyMODINIT_FUNC +initaudit2why(void) +{ + PyObject *m = Py_InitModule("audit2why", audit2whyMethods); + PyModule_AddIntConstant(m,"UNKNOWN", UNKNOWN); + PyModule_AddIntConstant(m,"BADSCON", BADSCON); + PyModule_AddIntConstant(m,"BADTCON", BADTCON); + PyModule_AddIntConstant(m,"BADTCLASS", BADTCLASS); + PyModule_AddIntConstant(m,"BADPERM", BADPERM); + PyModule_AddIntConstant(m,"BADCOMPUTE", BADCOMPUTE); + PyModule_AddIntConstant(m,"NOPOLICY", NOPOLICY); + PyModule_AddIntConstant(m,"ALLOW", ALLOW); + PyModule_AddIntConstant(m,"DONTAUDIT", DONTAUDIT); + PyModule_AddIntConstant(m,"TERULE", TERULE); + PyModule_AddIntConstant(m,"BOOLEAN", BOOLEAN); + PyModule_AddIntConstant(m,"CONSTRAINT", CONSTRAINT); + PyModule_AddIntConstant(m,"RBAC", RBAC); +} diff --exclude-from=exclude -N -u -r nsalibselinux/src/Makefile libselinux-2.0.47/src/Makefile --- nsalibselinux/src/Makefile 2008-01-11 10:52:37.000000000 -0500 +++ libselinux-2.0.47/src/Makefile 2008-01-23 14:19:11.000000000 -0500 @@ -18,6 +18,7 @@ SWIGSO=_selinux.so SWIGFILES=$(SWIGSO) selinux.py LIBSO=$(TARGET).$(LIBVERSION) +AUDIT2WHYSO=audit2why.so ifeq ($(DISABLE_AVC),y) UNUSED_SRCS+=avc.c avc_internal.c avc_sidtab.c mapping.c stringrep.c checkAccess.c @@ -28,7 +29,7 @@ ifeq ($(DISABLE_RPM),y) UNUSED_SRCS+=rpm.c endif -SRCS= $(filter-out $(UNUSED_SRCS), $(filter-out $(SWIGCOUT),$(wildcard *.c))) +SRCS= $(filter-out $(UNUSED_SRCS), $(filter-out audit2why.c $(SWIGCOUT),$(wildcard *.c))) OBJS= $(patsubst %.c,%.o,$(SRCS)) LOBJS= $(patsubst %.c,%.lo,$(SRCS)) @@ -47,7 +48,7 @@ all: $(LIBA) $(LIBSO) -pywrap: all $(SWIGSO) +pywrap: all $(SWIGSO) $(AUDIT2WHYSO) $(LIBA): $(OBJS) $(AR) rcs $@ $^ @@ -63,6 +64,12 @@ $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -ldl -L$(LIBDIR) -Wl,-soname,$(LIBSO),-z,defs,-z,relro ln -sf $@ $(TARGET) +audit2why.lo: audit2why.c + $(CC) $(CFLAGS) -I$(PYINC) -fPIC -DSHARED -c -o $@ $< + +$(AUDIT2WHYSO): audit2why.lo + $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -L. -lselinux ${LIBDIR}/libsepol.a -L$(LIBDIR) -Wl,-soname,$@ + %.o: %.c policy.h $(CC) $(CFLAGS) $(TLSFLAGS) -c -o $@ $< @@ -83,14 +90,16 @@ cd $(LIBDIR) && ln -sf ../../`basename $(SHLIBDIR)`/$(LIBSO) $(TARGET) install-pywrap: pywrap - test -d $(PYTHONLIBDIR)/site-packages || install -m 755 -d $(PYTHONLIBDIR)/site-packages - install -m 755 $(SWIGFILES) $(PYTHONLIBDIR)/site-packages + test -d $(PYTHONLIBDIR)/site-packages/selinux || install -m 755 -d $(PYTHONLIBDIR)/site-packages/selinux + install -m 755 $(SWIGSO) $(PYTHONLIBDIR)/site-packages/selinux + install -m 755 $(AUDIT2WHYSO) $(PYTHONLIBDIR)/site-packages/selinux + install -m 644 selinux.py $(PYTHONLIBDIR)/site-packages/selinux/__init__.py relabel: /sbin/restorecon $(SHLIBDIR)/$(LIBSO) clean: - -rm -f $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(TARGET) + -rm -f $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(TARGET) $(AUDIT2WHYSO) *.o *.lo *~ distclean: clean rm -f $(SWIGCOUT) $(SWIGFILES) diff --exclude-from=exclude -N -u -r nsalibselinux/src/matchpathcon.c libselinux-2.0.47/src/matchpathcon.c --- nsalibselinux/src/matchpathcon.c 2007-09-28 09:48:58.000000000 -0400 +++ libselinux-2.0.47/src/matchpathcon.c 2008-01-11 10:55:14.000000000 -0500 @@ -2,6 +2,7 @@ #include #include #include +#include #include "selinux_internal.h" #include "label_internal.h" #include "callbacks.h" @@ -57,7 +58,7 @@ { va_list ap; va_start(ap, fmt); - vfprintf(stderr, fmt, ap); + vsyslog(LOG_ERR, fmt, ap); va_end(ap); } diff --exclude-from=exclude -N -u -r nsalibselinux/src/selinuxswig.i libselinux-2.0.47/src/selinuxswig.i --- nsalibselinux/src/selinuxswig.i 2008-01-23 14:36:29.000000000 -0500 +++ libselinux-2.0.47/src/selinuxswig.i 2008-01-11 10:55:14.000000000 -0500 @@ -14,6 +14,7 @@ %typedef unsigned mode_t; %typedef unsigned pid_t; +%typedef char * security_context_t; %typemap(in, numinputs=0) (char ***names, int *len) (char **temp1, int temp2) { $1 = &temp1;