예제 #1
0
/*
 * Looks up a name in the selection or property mappings
 */
static int
SELinuxAtomToSIDLookup(Atom atom, SELinuxObjectRec * obj, int map, int polymap)
{
    const char *name = NameForAtom(atom);
    security_context_t ctx;
    int rc = Success;

    obj->poly = 1;

    /* Look in the mappings of names to contexts */
    if (selabel_lookup_raw(label_hnd, &ctx, name, map) == 0) {
        obj->poly = 0;
    }
    else if (errno != ENOENT) {
        ErrorF("SELinux: a property label lookup failed!\n");
        return BadValue;
    }
    else if (selabel_lookup_raw(label_hnd, &ctx, name, polymap) < 0) {
        ErrorF("SELinux: a property label lookup failed!\n");
        return BadValue;
    }

    /* Get a SID for context */
    if (avc_context_to_sid_raw(ctx, &obj->sid) < 0) {
        ErrorF("SELinux: a context_to_SID_raw call failed!\n");
        rc = BadAlloc;
    }

    freecon(ctx);
    return rc;
}
예제 #2
0
파일: label.c 프로젝트: terralinux/systemd
int label_mkdir(
        const char *path,
        mode_t mode) {

        /* Creates a directory and labels it according to the SELinux policy */

#ifdef HAVE_SELINUX
        int r;
        security_context_t fcon = NULL;

        if (use_selinux() && label_hnd) {

                if (path_is_absolute(path))
                        r = selabel_lookup_raw(label_hnd, &fcon, path, mode);
                else {
                        char *newpath = NULL;

                        if (!(newpath = path_make_absolute_cwd(path)))
                                return -ENOMEM;

                        r = selabel_lookup_raw(label_hnd, &fcon, newpath, mode);
                        free(newpath);
                }

                if (r == 0)
                        r = setfscreatecon(fcon);

                if (r < 0 && errno != ENOENT) {
                        log_error("Failed to set security context %s for %s: %m", fcon, path);
                        r = -errno;

                        if (security_getenforce() == 1)
                                goto finish;
                }
        }

        if ((r = mkdir(path, mode)) < 0)
                r = -errno;

finish:
        if (use_selinux() && label_hnd) {
                setfscreatecon(NULL);
                freecon(fcon);
        }

        return r;
#else
        return mkdir(path, mode);
#endif
}
예제 #3
0
파일: selinux.c 프로젝트: guillemj/dpkg
void
dpkg_selabel_set_context(const char *matchpath, const char *path, mode_t mode)
{
#ifdef WITH_LIBSELINUX
	security_context_t scontext = NULL;
	int ret;

	/* If SELinux is not enabled just do nothing. */
	if (sehandle == NULL)
		return;

	/*
	 * We use the _raw function variants here so that no translation
	 * happens from computer to human readable forms, to avoid issues
	 * when mcstransd has disappeared during the unpack process.
	 */

	/* Do nothing if we can't figure out what the context is, or if it has
	 * no context; in which case the default context shall be applied. */
	ret = selabel_lookup_raw(sehandle, &scontext, matchpath, mode & S_IFMT);
	if (ret == -1 || (ret == 0 && scontext == NULL))
		return;

	ret = lsetfilecon_raw(path, scontext);
	if (ret < 0 && errno != ENOTSUP)
		ohshite(_("cannot set security context for file object '%s'"),
		        path);

	freecon(scontext);
#endif /* WITH_LIBSELINUX */
}
예제 #4
0
int mac_selinux_create_file_prepare(const char *path, mode_t mode) {

#ifdef HAVE_SELINUX
        _cleanup_freecon_ char *filecon = NULL;
        int r;

        assert(path);

        if (!label_hnd)
                return 0;

        if (path_is_absolute(path))
                r = selabel_lookup_raw(label_hnd, &filecon, path, mode);
        else {
                _cleanup_free_ char *newpath = NULL;

                r = path_make_absolute_cwd(path, &newpath);
                if (r < 0)
                        return r;

                r = selabel_lookup_raw(label_hnd, &filecon, newpath, mode);
        }

        if (r < 0) {
                /* No context specified by the policy? Proceed without setting it. */
                if (errno == ENOENT)
                        return 0;

                log_enforcing("Failed to determine SELinux security context for %s: %m", path);
        } else {
                if (setfscreatecon_raw(filecon) >= 0)
                        return 0; /* Success! */

                log_enforcing("Failed to set SELinux security context %s for %s: %m", filecon, path);
        }

        if (security_getenforce() > 0)
                return -errno;

#endif
        return 0;
}
예제 #5
0
int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {

#ifdef HAVE_SELINUX
        struct stat st;
        int r;

        assert(path);

        /* if mac_selinux_init() wasn't called before we are a NOOP */
        if (!label_hnd)
                return 0;

        r = lstat(path, &st);
        if (r >= 0) {
                _cleanup_freecon_ char* fcon = NULL;

                r = selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode);

                /* If there's no label to set, then exit without warning */
                if (r < 0 && errno == ENOENT)
                        return 0;

                if (r >= 0) {
                        r = lsetfilecon_raw(path, fcon);

                        /* If the FS doesn't support labels, then exit without warning */
                        if (r < 0 && errno == EOPNOTSUPP)
                                return 0;
                }
        }

        if (r < 0) {
                /* Ignore ENOENT in some cases */
                if (ignore_enoent && errno == ENOENT)
                        return 0;

                if (ignore_erofs && errno == EROFS)
                        return 0;

                log_enforcing("Unable to fix SELinux security context of %s: %m", path);
                if (security_getenforce() == 1)
                        return -errno;
        }
#endif

        return 0;
}
예제 #6
0
int
SELinuxExtensionToSID(const char *name, security_id_t * sid_rtn)
{
    security_context_t ctx;

    /* Look in the mappings of extension names to contexts */
    if (selabel_lookup_raw(label_hnd, &ctx, name, SELABEL_X_EXT) < 0) {
        ErrorF("SELinux: a property label lookup failed!\n");
        return BadValue;
    }
    /* Get a SID for context */
    if (avc_context_to_sid_raw(ctx, sid_rtn) < 0) {
        ErrorF("SELinux: a context_to_SID_raw call failed!\n");
        freecon(ctx);
        return BadAlloc;
    }
    freecon(ctx);
    return Success;
}
예제 #7
0
파일: rc-selinux.c 프로젝트: OpenRC/openrc
int selinux_util_label(const char *path)
{
    int retval = 0;
    int enforce;
    struct stat st;
    security_context_t con;

    enforce = security_getenforce();
    if (retval < 0)
        return retval;

    if (!hnd)
        return (enforce) ? -1 : 0;

    retval = lstat(path, &st);
    if (retval < 0) {
        if (errno == ENOENT)
            return 0;
        return (enforce) ? -1 : 0;
    }

    /* lookup the context */
    retval = selabel_lookup_raw(hnd, &con, path, st.st_mode);
    if (retval < 0) {
        if (errno == ENOENT)
            return 0;
        return (enforce) ? -1 : 0;
    }

    /* apply the context */
    retval = lsetfilecon(path, con);
    freecon(con);
    if (retval < 0) {
        if (errno == ENOENT)
            return 0;
        if (errno == ENOTSUP)
            return 0;
        return (enforce) ? -1 : 0;
    }

    return 0;
}
예제 #8
0
파일: label.c 프로젝트: terralinux/systemd
int label_fix(const char *path, bool ignore_enoent) {
        int r = 0;

#ifdef HAVE_SELINUX
        struct stat st;
        security_context_t fcon;

        if (!use_selinux() || !label_hnd)
                return 0;

        r = lstat(path, &st);
        if (r == 0) {
                r = selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode);

                /* If there's no label to set, then exit without warning */
                if (r < 0 && errno == ENOENT)
                        return 0;

                if (r == 0) {
                        r = setfilecon(path, fcon);
                        freecon(fcon);

                        /* If the FS doesn't support labels, then exit without warning */
                        if (r < 0 && errno == ENOTSUP)
                                return 0;
                }
        }

        if (r < 0) {
                /* Ignore ENOENT in some cases */
                if (ignore_enoent && errno == ENOENT)
                        return 0;

                log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
                         "Unable to fix label of %s: %m", path);
                r = security_getenforce() == 1 ? -errno : 0;
        }
#endif

        return r;
}
예제 #9
0
/*
 * Looks up the SID corresponding to the given event type
 */
int
SELinuxEventToSID(unsigned type, security_id_t sid_of_window,
                  SELinuxObjectRec * sid_return)
{
    const char *name = LookupEventName(type);
    security_id_t sid;
    security_context_t ctx;

    type &= 127;

    sid = SELinuxArrayGet(&arr_events, type);
    if (!sid) {
        /* Look in the mappings of event names to contexts */
        if (selabel_lookup_raw(label_hnd, &ctx, name, SELABEL_X_EVENT) < 0) {
            ErrorF("SELinux: an event label lookup failed!\n");
            return BadValue;
        }
        /* Get a SID for context */
        if (avc_context_to_sid_raw(ctx, &sid) < 0) {
            ErrorF("SELinux: a context_to_SID_raw call failed!\n");
            freecon(ctx);
            return BadAlloc;
        }
        freecon(ctx);
        /* Cache the SID value */
        if (!SELinuxArraySet(&arr_events, type, sid))
            return BadAlloc;
    }

    /* Perform a transition to obtain the final SID */
    if (avc_compute_create(sid_of_window, sid, SECCLASS_X_EVENT,
                           &sid_return->sid) < 0) {
        ErrorF("SELinux: a compute_create call failed!\n");
        return BadValue;
    }

    return Success;
}
예제 #10
0
파일: label.c 프로젝트: terralinux/systemd
int label_symlinkfile_set(const char *path) {
        int r = 0;

#ifdef HAVE_SELINUX
        security_context_t filecon = NULL;

        if (!use_selinux() || !label_hnd)
                return 0;

        if ((r = selabel_lookup_raw(label_hnd, &filecon, path, S_IFLNK)) == 0) {
                if ((r = setfscreatecon(filecon)) < 0) {
                        log_error("Failed to set SELinux file context on %s: %m", path);
                        r = -errno;
                }

                freecon(filecon);
        }

        if (r < 0 && security_getenforce() == 0)
                r = 0;
#endif

        return r;
}
예제 #11
0
/*
 * exec_object_restorecon
 *
 * This routine is a helper called by sepgsql_restorecon; it set up
 * initial security labels of database objects within the supplied
 * catalog OID.
 */
static void
exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
{
	Relation		rel;
	SysScanDesc		sscan;
	HeapTuple		tuple;
	char		   *database_name = get_database_name(MyDatabaseId);
	char		   *namespace_name;
	Oid				namespace_id;
	char		   *relation_name;

	/*
	 * Open the target catalog. We don't want to allow writable
	 * accesses by other session during initial labeling.
	 */
	rel = heap_open(catalogId, AccessShareLock);

	sscan = systable_beginscan(rel, InvalidOid, false,
							   SnapshotNow, 0, NULL);
	while (HeapTupleIsValid(tuple = systable_getnext(sscan)))
	{
		Form_pg_namespace	nspForm;
		Form_pg_class		relForm;
		Form_pg_attribute	attForm;
		Form_pg_proc		proForm;
		char			   *objname;
		int					objtype = 1234;
		ObjectAddress		object;
		security_context_t	context;

		/*
		 * The way to determine object name depends on object classes.
		 * So, any branches set up `objtype', `objname' and `object' here.
		 */
		switch (catalogId)
		{
			case NamespaceRelationId:
				nspForm = (Form_pg_namespace) GETSTRUCT(tuple);

				objtype = SELABEL_DB_SCHEMA;

				objname = quote_object_name(database_name,
											NameStr(nspForm->nspname),
											NULL, NULL);

				object.classId = NamespaceRelationId;
				object.objectId = HeapTupleGetOid(tuple);
				object.objectSubId = 0;
				break;

			case RelationRelationId:
				relForm = (Form_pg_class) GETSTRUCT(tuple);

				if (relForm->relkind == RELKIND_RELATION)
					objtype = SELABEL_DB_TABLE;
				else if (relForm->relkind == RELKIND_SEQUENCE)
					objtype = SELABEL_DB_SEQUENCE;
				else if (relForm->relkind == RELKIND_VIEW)
					objtype = SELABEL_DB_VIEW;
				else
					continue;	/* no need to assign security label */

				namespace_name = get_namespace_name(relForm->relnamespace);
				objname = quote_object_name(database_name,
											namespace_name,
											NameStr(relForm->relname),
											NULL);
				pfree(namespace_name);

				object.classId = RelationRelationId;
				object.objectId = HeapTupleGetOid(tuple);
				object.objectSubId = 0;
				break;

			case AttributeRelationId:
				attForm = (Form_pg_attribute) GETSTRUCT(tuple);

				if (get_rel_relkind(attForm->attrelid) != RELKIND_RELATION)
					continue;	/* no need to assign security label */

				objtype = SELABEL_DB_COLUMN;

				namespace_id = get_rel_namespace(attForm->attrelid);
				namespace_name = get_namespace_name(namespace_id);
				relation_name = get_rel_name(attForm->attrelid);
				objname = quote_object_name(database_name,
											namespace_name,
											relation_name,
											NameStr(attForm->attname));
				pfree(namespace_name);
				pfree(relation_name);

				object.classId = RelationRelationId;
				object.objectId = attForm->attrelid;
				object.objectSubId = attForm->attnum;
				break;

			case ProcedureRelationId:
				proForm = (Form_pg_proc) GETSTRUCT(tuple);

				objtype = SELABEL_DB_PROCEDURE;

				namespace_name = get_namespace_name(proForm->pronamespace);
				objname = quote_object_name(database_name,
											namespace_name,
											NameStr(proForm->proname),
											NULL);
				pfree(namespace_name);

				object.classId = ProcedureRelationId;
				object.objectId = HeapTupleGetOid(tuple);
				object.objectSubId = 0;
				break;

			default:
				elog(ERROR, "unexpected catalog id: %u", catalogId);
				objname = NULL;		/* for compiler quiet */
				break;
		}

		if (selabel_lookup_raw(sehnd, &context, objname, objtype) == 0)
		{
			PG_TRY();
			{
				/*
				 * Check SELinux permission to relabel the fetched object,
				 * then do the actual relabeling.
				 */
				sepgsql_object_relabel(&object, context);

				SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, context);
			}
			PG_CATCH();
			{
				freecon(context);
				PG_RE_THROW();
			}
			PG_END_TRY();
			freecon(context);
		}
		else if (errno == ENOENT)
			ereport(WARNING,
					(errmsg("SELinux: no initial label assigned for %s (type=%d), skipping",
							objname, objtype)));
		else
			ereport(ERROR,
					(errcode(ERRCODE_INTERNAL_ERROR),
					 errmsg("SELinux: could not determine initial security label for %s (type=%d): %m", objname, objtype)));

		pfree(objname);
	}
	systable_endscan(sscan);

	heap_close(rel, NoLock);
}
예제 #12
0
int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {

        /* Binds a socket and label its file system object according to the SELinux policy */

#ifdef HAVE_SELINUX
        _cleanup_freecon_ char *fcon = NULL;
        const struct sockaddr_un *un;
        bool context_changed = false;
        char *path;
        int r;

        assert(fd >= 0);
        assert(addr);
        assert(addrlen >= sizeof(sa_family_t));

        if (!label_hnd)
                goto skipped;

        /* Filter out non-local sockets */
        if (addr->sa_family != AF_UNIX)
                goto skipped;

        /* Filter out anonymous sockets */
        if (addrlen < offsetof(struct sockaddr_un, sun_path) + 1)
                goto skipped;

        /* Filter out abstract namespace sockets */
        un = (const struct sockaddr_un*) addr;
        if (un->sun_path[0] == 0)
                goto skipped;

        path = strndupa(un->sun_path, addrlen - offsetof(struct sockaddr_un, sun_path));

        if (path_is_absolute(path))
                r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK);
        else {
                _cleanup_free_ char *newpath = NULL;

                r = path_make_absolute_cwd(path, &newpath);
                if (r < 0)
                        return r;

                r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFSOCK);
        }

        if (r < 0) {
                /* No context specified by the policy? Proceed without setting it */
                if (errno == ENOENT)
                        goto skipped;

                log_enforcing("Failed to determine SELinux security context for %s: %m", path);
                if (security_getenforce() > 0)
                        return -errno;

        } else {
                if (setfscreatecon_raw(fcon) < 0) {
                        log_enforcing("Failed to set SELinux security context %s for %s: %m", fcon, path);
                        if (security_getenforce() > 0)
                                return -errno;
                } else
                        context_changed = true;
        }

        r = bind(fd, addr, addrlen) < 0 ? -errno : 0;

        if (context_changed)
                setfscreatecon_raw(NULL);

        return r;

skipped:
#endif
        if (bind(fd, addr, addrlen) < 0)
                return -errno;

        return 0;
}