libsmack_la_LDFLAGS = \
-version-info 1:0:0 \
-Wl,--version-script=$(top_srcdir)/libsmack/libsmack.sym
-libsmack_la_SOURCES = libsmack.c
+libsmack_la_SOURCES = libsmack.c init.c
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libsmack.pc
--- /dev/null
+/*
+ * This file is part of libsmack. Derived from libselinux/src/dso.h.
+ *
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * Authors:
+ * Passion Zhao <passion.zhao@intel.com>
+ */
+
+#ifndef _SMACK_DSO_H
+#define _SMACK_DSO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef SHARED
+# define hidden __attribute__ ((visibility ("hidden")))
+# define hidden_proto(fct) __hidden_proto (fct, fct##_internal)
+# define __hidden_proto(fct, internal) \
+ extern __typeof (fct) internal; \
+ extern __typeof (fct) fct __asm (#internal) hidden;
+# if defined(__alpha__) || defined(__mips__)
+# define hidden_def(fct) \
+ asm (".globl " #fct "\n" #fct " = " #fct "_internal");
+# else
+# define hidden_def(fct) \
+ asm (".globl " #fct "\n.set " #fct ", " #fct "_internal");
+#endif
+#else
+# define hidden
+# define hidden_proto(fct)
+# define hidden_def(fct)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+/*
+ * This file is part of libsmack. Derived from libselinux/src/init.c.
+ *
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * Authors:
+ * Passion Zhao <passion.zhao@intel.com>
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <dlfcn.h>
+#include <sys/statvfs.h>
+#include <sys/vfs.h>
+#include <stdint.h>
+#include <limits.h>
+
+#include "dso.h"
+
+/*
+ * * smackfs magic number
+ * */
+#define SMACK_MAGIC 0x43415d53 /* "SMAC" */
+
+/* smack file system type */
+#define SMACKFS "smackfs"
+
+#define SMACKFSMNT "/sys/fs/smackfs/"
+#define OLDSMACKFSMNT "/smack"
+
+static char *smack_mnt = NULL;
+
+void set_smackmnt(const char *mnt)
+{
+ smack_mnt = strdup(mnt);
+}
+
+hidden_def(set_smackmnt)
+
+
+/* Verify the mount point for smack file system has a smackfs.
+ * If the file system:
+ * Exist,
+ * Is mounted with an smack file system,
+ * The file system is read/write
+ * then set this as the default file system.
+ */
+static int verify_smackmnt(const char *mnt)
+{
+ struct statfs sfbuf;
+ int rc;
+
+ do {
+ rc = statfs(mnt, &sfbuf);
+ } while (rc < 0 && errno == EINTR);
+
+ if (rc == 0) {
+ if ((uint32_t)sfbuf.f_type == (uint32_t)SMACK_MAGIC) {
+ struct statvfs vfsbuf;
+ rc = statvfs(mnt, &vfsbuf);
+ if (rc == 0) {
+ if (!(vfsbuf.f_flag & ST_RDONLY)) {
+ set_smackmnt(mnt);
+ }
+ return 0;
+ }
+ }
+ }
+
+ return -1;
+}
+
+int smackfs_exists(void)
+{
+ int exists = 0;
+ FILE *fp = NULL;
+ char *buf = NULL;
+ size_t len;
+ ssize_t num;
+
+ fp = fopen("/proc/filesystems", "r");
+ if (!fp)
+ return 1; /* Fail as if it exists */
+
+ __fsetlocking(fp, FSETLOCKING_BYCALLER);
+
+ num = getline(&buf, &len, fp);
+ while (num != -1) {
+ if (strstr(buf, SMACKFS)) {
+ exists = 1;
+ break;
+ }
+ num = getline(&buf, &len, fp);
+ }
+
+ free(buf);
+ fclose(fp);
+ return exists;
+}
+
+hidden_def(smackfs_exists)
+
+static void init_smackmnt(void)
+{
+ char *buf=NULL, *p;
+ FILE *fp=NULL;
+ size_t len;
+ ssize_t num;
+
+ if (smack_mnt)
+ return;
+
+ if (verify_smackmnt(SMACKFSMNT) == 0)
+ return;
+
+ if (verify_smackmnt(OLDSMACKFSMNT) == 0)
+ return;
+
+ /* Drop back to detecting it the long way. */
+ if (!smackfs_exists())
+ goto out;
+
+ /* At this point, the usual spot doesn't have an smackfs so
+ * we look around for it */
+ fp = fopen("/proc/mounts", "r");
+ if (!fp)
+ goto out;
+
+ __fsetlocking(fp, FSETLOCKING_BYCALLER);
+ while ((num = getline(&buf, &len, fp)) != -1) {
+ char *tmp;
+ p = strchr(buf, ' ');
+ if (!p)
+ goto out;
+ p++;
+
+ tmp = strchr(p, ' ');
+ if (!tmp)
+ goto out;
+
+ if (!strncmp(tmp + 1, SMACKFS" ", strlen(SMACKFS)+1)) {
+ *tmp = '\0';
+ break;
+ }
+ }
+
+ /* If we found something, dup it */
+ if (num > 0)
+ verify_smackmnt(p);
+
+ out:
+ free(buf);
+ if (fp)
+ fclose(fp);
+ return;
+}
+
+const char *smack_smackfs_path(void)
+{
+ return smack_mnt;
+}
+
+void fini_smackmnt(void)
+{
+ free(smack_mnt);
+ smack_mnt = NULL;
+}
+
+hidden_def(fini_smackmnt)
+
+static void init_lib(void) __attribute__ ((constructor));
+static void init_lib(void)
+{
+ init_smackmnt();
+}
+
+static void fini_lib(void) __attribute__ ((destructor));
+static void fini_lib(void)
+{
+ fini_smackmnt();
+}
* Authors:
* Jarkko Sakkinen <jarkko.sakkinen@intel.com>
* Brian McGillion <brian.mcgillion@intel.com>
+ * Passion Zhao <passion.zhao@intel.com>
*/
#include "sys/smack.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#include <limits.h>
#define LABEL_LEN 255
#define ACC_LEN 5
#define KERNEL_LONG_FORMAT "%s %s %s"
#define KERNEL_SHORT_FORMAT "%-23s %-23s %5s"
#define READ_BUF_SIZE LOAD_LEN + 1
-#define SMACKFS_MNT "/smack"
#define SELF_LABEL_FILE "/proc/self/attr/current"
+const char *smack_mnt;
+
struct smack_rule {
char subject[LABEL_LEN + 1];
char object[LABEL_LEN + 1];
int ret;
int fd;
int access2 = 1;
+ char path[PATH_MAX];
- access_code = access_type_to_int(access_type);
- int_to_access_type_k(access_code, access_type_k);
-
- fd = open(SMACKFS_MNT "/access2", O_RDWR);
+ smack_mnt = smack_smackfs_path();
+ if (!smack_mnt) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ snprintf(path, sizeof path, "%s/access2", smack_mnt);
+ fd = open(path, O_RDWR);
if (fd < 0) {
if (errno != ENOENT)
return -1;
- fd = open(SMACKFS_MNT "/access", O_RDWR);
+
+ snprintf(path, sizeof path, "%s/access", smack_mnt);
+ fd = open(path, O_RDWR);
if (fd < 0)
return -1;
access2 = 0;
}
+ access_code = access_type_to_int(access_type);
+ int_to_access_type_k(access_code, access_type_k);
+
if (access2)
ret = snprintf(buf, LOAD_LEN + 1, KERNEL_LONG_FORMAT,
subject, object, access_type_k);
char buf[CIPSO_MAX_SIZE];
int fd;
int i;
+ char path[PATH_MAX];
- fd = open(SMACKFS_MNT "/cipso2", O_WRONLY);
+ smack_mnt = smack_smackfs_path();
+ if (!smack_mnt) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ snprintf(path, sizeof path, "%s/cipso2", smack_mnt);
+ fd = open(path, O_WRONLY);
if (fd < 0)
return -1;
if (ret < 0 && errno != ERANGE)
return -1;
- result = calloc(length + 1, 1);
+ result = calloc(length + 1, 1);
if (result == NULL)
return -1;
int ret;
int fd;
int load2 = 1;
+ char path[PATH_MAX];
- fd = open(SMACKFS_MNT "/load2", O_WRONLY);
+ smack_mnt = smack_smackfs_path();
+ if (!smack_mnt) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ snprintf(path, sizeof path, "%s/load2", smack_mnt);
+ fd = open(path, O_WRONLY);
if (fd < 0) {
if (errno != ENOENT)
return -1;
/* fallback */
- fd = open(SMACKFS_MNT "/load", O_WRONLY);
+ snprintf(path, sizeof path, "%s/load", smack_mnt);
+ fd = open(path, O_WRONLY);
if (fd < 0)
return -1;
load2 = 0;
smack_cipso_free;
smack_cipso_new;
smack_cipso_apply;
+ smack_smackfs_path;
smack_new_label_from_self;
smack_new_label_from_socket;
local:
int smack_cipso_apply(struct smack_cipso *cipso);
/*!
+ * Get the smackfs directory.
+ */
+const char *smack_smackfs_path(void);
+
+/*!
* Get the label that is associated with the callers process.
* Caller is responsible of freeing the returned label.
*
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
-#define SMACKFS_MAGIC 0x43415d53
+#define SMACK_MAGIC 0x43415d53
static int apply_rules_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf);
static int apply_cipso_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf);
{
struct statfs sfs;
int ret;
+ const char * smack_mnt;
+
+ smack_mnt = smack_smackfs_path();
+ if (!smack_mnt) {
+ errno = EFAULT;
+ return -1;
+ }
do {
- ret = statfs(SMACKFS_MNT, &sfs);
+ ret = statfs(smack_mnt, &sfs);
} while (ret < 0 && errno == EINTR);
if (ret)
return -1;
- if (sfs.f_type == SMACKFS_MAGIC)
+ if (sfs.f_type == SMACK_MAGIC)
return 1;
return 0;
{
int fd;
int ret;
+ const char * smack_mnt;
+ char path[PATH_MAX];
+
+ smack_mnt = smack_smackfs_path();
+ if (!smack_mnt) {
+ errno = EFAULT;
+ return -1;
+ }
if (is_smackfs_mounted() != 1)
return -1;
- fd = open(SMACKFS_MNT "/load2", O_RDONLY);
+ snprintf(path, sizeof path, "%s/load2", smack_mnt);
+ fd = open(path, O_RDONLY);
if (fd < 0)
return -1;
#define COMMON_H
#define LABEL_LEN 255
-#define SMACKFS_MNT "/smack"
#define ACCESSES_D_PATH "/etc/smack/accesses.d"
#define CIPSO_D_PATH "/etc/smack/cipso.d"