From: "Serge E. Hallyn" <serue@us.ibm.com>
To: Oren Laadan <orenl@cs.columbia.edu>
Cc: Casey Schaufler <casey@schaufler-ca.com>,
Linux Containers <containers@lists.osdl.org>,
linux-security-module@vger.kernel.org,
SELinux <selinux@tycho.nsa.gov>
Subject: [RFC PATCH 2/2] cr: debug security_checkpoint_header and security_may_restart
Date: Thu, 3 Sep 2009 17:28:53 -0500 [thread overview]
Message-ID: <20090903222853.GA27556@us.ibm.com> (raw)
In-Reply-To: <20090903222824.GB27377@us.ibm.com>
This patch, for debugging only, introduces a silly admin-controlled
'policy version' for smack. By default the version is 1. An
admin (with CAP_MAC_ADMIN) can change it by echoing a new value
into /smack/version.
It then defines security_checkpoint_header() to add this 'policy
version' into the checkpoint header, and defines security_may_restart()
to refuse restart if both:
1. the caller asked for RESTART_KEEP_LSM
and
2. the checkpointed version was different from the current.
This of course is easy enough to test by doing
echo 1 > /smack/version
ckpt > out
mktree < out
succeed
mktree -k < out
succeed
echo 2 > /smack/version
mktree < out
succeed
mktree -k < out
fail
Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
---
security/smack/smack_lsm.c | 46 +++++++++++++++++++++++++++
security/smack/smackfs.c | 75 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 121 insertions(+), 0 deletions(-)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 279fdce..f0d4a08 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -27,6 +27,7 @@
#include <linux/udp.h>
#include <linux/mutex.h>
#include <linux/pipe_fs_i.h>
+#include <linux/checkpoint.h>
#include <net/netlabel.h>
#include <net/cipso_ipv4.h>
#include <linux/audit.h>
@@ -3111,6 +3112,47 @@ static void smack_release_secctx(char *secdata, u32 seclen)
{
}
+#ifdef CONFIG_CHECKPOINT
+extern int smack_version;
+
+static int smack_may_restart(struct ckpt_ctx *ctx)
+{
+ struct ckpt_hdr *h;
+ char *smackv;
+ int v = 0, slen, ret;
+
+ h = ckpt_read_buf_type(ctx, CKPT_LSM_INFO_LEN, CKPT_HDR_LSM_INFO);
+ if (IS_ERR(h))
+ return PTR_ERR(h);
+
+ if (strcmp(ctx->lsm_name, "smack") != 0)
+ return 0;
+
+ smackv = (char *) (h + 1);
+ slen = h->len - sizeof(*h);
+ if (smackv[slen-1] != '\0')
+ smackv[slen-1] = '\0';
+ ret = sscanf(smackv, "%d", &v);
+ ckpt_hdr_put(ctx, h);
+ if (!(ctx->uflags & RESTART_KEEP_LSM))
+ return 0;
+ if (ret != 1 || v != smack_version) {
+ ckpt_debug("Smack version at checkpoint was %d, now is %d\n",
+ v, smack_version);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int smack_checkpoint_header(struct ckpt_ctx *ctx)
+{
+ char smackv[10];
+ sprintf(smackv, "%d", smack_version);
+ return ckpt_write_obj_type(ctx, smackv, strlen(smackv)+1,
+ CKPT_HDR_LSM_INFO);
+}
+#endif
+
struct security_operations smack_ops = {
.name = "smack",
@@ -3245,6 +3287,10 @@ struct security_operations smack_ops = {
.secid_to_secctx = smack_secid_to_secctx,
.secctx_to_secid = smack_secctx_to_secid,
.release_secctx = smack_release_secctx,
+#ifdef CONFIG_CHECKPOINT
+ .may_restart = smack_may_restart,
+ .checkpoint_header = smack_checkpoint_header,
+#endif
};
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index f83a809..7b20ad9 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -42,6 +42,7 @@ enum smk_inos {
SMK_NETLBLADDR = 8, /* single label hosts */
SMK_ONLYCAP = 9, /* the only "capable" label */
SMK_LOGGING = 10, /* logging */
+ SMK_VERSION = 11, /* logging */
};
/*
@@ -51,6 +52,7 @@ static DEFINE_MUTEX(smack_list_lock);
static DEFINE_MUTEX(smack_cipso_lock);
static DEFINE_MUTEX(smack_ambient_lock);
static DEFINE_MUTEX(smk_netlbladdr_lock);
+static DEFINE_MUTEX(smack_version_lock);
/*
* This is the "ambient" label for network traffic.
@@ -60,6 +62,11 @@ static DEFINE_MUTEX(smk_netlbladdr_lock);
char *smack_net_ambient = smack_known_floor.smk_known;
/*
+ * this is the policy version, a simple integer
+ */
+int smack_version = 1;
+
+/*
* This is the level in a CIPSO header that indicates a
* smack label is contained directly in the category set.
* It can be reset via smackfs/direct
@@ -1255,6 +1262,72 @@ static const struct file_operations smk_logging_ops = {
.read = smk_read_logging,
.write = smk_write_logging,
};
+
+#define SMK_VERSIONLEN 12
+/**
+ * smk_read_version - read() for /smack/version
+ * @filp: file pointer, not actually used
+ * @buf: where to put the result
+ * @cn: maximum to send along
+ * @ppos: where to start
+ *
+ * Returns number of bytes read or error code, as appropriate
+ */
+static ssize_t smk_read_version(struct file *filp, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ char temp[SMK_VERSIONLEN];
+
+ if (*ppos != 0)
+ return 0;
+
+ mutex_lock(&smack_version_lock);
+ sprintf(temp, "%d\n", smack_version);
+ mutex_unlock(&smack_version_lock);
+
+ return simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
+}
+
+/**
+ * smk_write_version - write() for /smack/version
+ * @file: file pointer, not actually used
+ * @buf: where to get the data from
+ * @count: bytes sent
+ * @ppos: where to start
+ *
+ * Returns number of bytes written or error code, as appropriate
+ */
+static ssize_t smk_write_version(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ char in[SMK_VERSIONLEN];
+ int tmp, ret;
+
+ if (!capable(CAP_MAC_ADMIN))
+ return -EPERM;
+
+ if (count >= SMK_VERSIONLEN)
+ return -EINVAL;
+
+ if (copy_from_user(in, buf, count) != 0)
+ return -EFAULT;
+
+ in[count-1] = '\0';
+ ret = sscanf(in, "%d", &tmp);
+ if (ret != 1)
+ return -EINVAL;
+ mutex_lock(&smack_version_lock);
+ smack_version = tmp;
+ mutex_unlock(&smack_version_lock);
+
+ return count;
+}
+
+static const struct file_operations smk_version_ops = {
+ .read = smk_read_version,
+ .write = smk_write_version,
+};
+
/**
* smk_fill_super - fill the /smackfs superblock
* @sb: the empty superblock
@@ -1287,6 +1360,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
{"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR},
[SMK_LOGGING] =
{"logging", &smk_logging_ops, S_IRUGO|S_IWUSR},
+ [SMK_VERSION] =
+ {"version", &smk_version_ops, S_IRUGO|S_IWUSR},
/* last one */ {""}
};
--
1.6.1
WARNING: multiple messages have this Message-ID (diff)
From: "Serge E. Hallyn" <serue@us.ibm.com>
To: Oren Laadan <orenl@cs.columbia.edu>
Cc: Casey Schaufler <casey@schaufler-ca.com>,
Linux Containers <containers@lists.osdl.org>,
linux-security-module@vger.kernel.org,
SELinux <selinux@tycho.nsa.gov>
Subject: [RFC PATCH 2/2] cr: debug security_checkpoint_header and security_may_restart
Date: Thu, 3 Sep 2009 17:28:53 -0500 [thread overview]
Message-ID: <20090903222853.GA27556@us.ibm.com> (raw)
In-Reply-To: <20090903222824.GB27377@us.ibm.com>
This patch, for debugging only, introduces a silly admin-controlled
'policy version' for smack. By default the version is 1. An
admin (with CAP_MAC_ADMIN) can change it by echoing a new value
into /smack/version.
It then defines security_checkpoint_header() to add this 'policy
version' into the checkpoint header, and defines security_may_restart()
to refuse restart if both:
1. the caller asked for RESTART_KEEP_LSM
and
2. the checkpointed version was different from the current.
This of course is easy enough to test by doing
echo 1 > /smack/version
ckpt > out
mktree < out
succeed
mktree -k < out
succeed
echo 2 > /smack/version
mktree < out
succeed
mktree -k < out
fail
Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
---
security/smack/smack_lsm.c | 46 +++++++++++++++++++++++++++
security/smack/smackfs.c | 75 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 121 insertions(+), 0 deletions(-)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 279fdce..f0d4a08 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -27,6 +27,7 @@
#include <linux/udp.h>
#include <linux/mutex.h>
#include <linux/pipe_fs_i.h>
+#include <linux/checkpoint.h>
#include <net/netlabel.h>
#include <net/cipso_ipv4.h>
#include <linux/audit.h>
@@ -3111,6 +3112,47 @@ static void smack_release_secctx(char *secdata, u32 seclen)
{
}
+#ifdef CONFIG_CHECKPOINT
+extern int smack_version;
+
+static int smack_may_restart(struct ckpt_ctx *ctx)
+{
+ struct ckpt_hdr *h;
+ char *smackv;
+ int v = 0, slen, ret;
+
+ h = ckpt_read_buf_type(ctx, CKPT_LSM_INFO_LEN, CKPT_HDR_LSM_INFO);
+ if (IS_ERR(h))
+ return PTR_ERR(h);
+
+ if (strcmp(ctx->lsm_name, "smack") != 0)
+ return 0;
+
+ smackv = (char *) (h + 1);
+ slen = h->len - sizeof(*h);
+ if (smackv[slen-1] != '\0')
+ smackv[slen-1] = '\0';
+ ret = sscanf(smackv, "%d", &v);
+ ckpt_hdr_put(ctx, h);
+ if (!(ctx->uflags & RESTART_KEEP_LSM))
+ return 0;
+ if (ret != 1 || v != smack_version) {
+ ckpt_debug("Smack version at checkpoint was %d, now is %d\n",
+ v, smack_version);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int smack_checkpoint_header(struct ckpt_ctx *ctx)
+{
+ char smackv[10];
+ sprintf(smackv, "%d", smack_version);
+ return ckpt_write_obj_type(ctx, smackv, strlen(smackv)+1,
+ CKPT_HDR_LSM_INFO);
+}
+#endif
+
struct security_operations smack_ops = {
.name = "smack",
@@ -3245,6 +3287,10 @@ struct security_operations smack_ops = {
.secid_to_secctx = smack_secid_to_secctx,
.secctx_to_secid = smack_secctx_to_secid,
.release_secctx = smack_release_secctx,
+#ifdef CONFIG_CHECKPOINT
+ .may_restart = smack_may_restart,
+ .checkpoint_header = smack_checkpoint_header,
+#endif
};
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index f83a809..7b20ad9 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -42,6 +42,7 @@ enum smk_inos {
SMK_NETLBLADDR = 8, /* single label hosts */
SMK_ONLYCAP = 9, /* the only "capable" label */
SMK_LOGGING = 10, /* logging */
+ SMK_VERSION = 11, /* logging */
};
/*
@@ -51,6 +52,7 @@ static DEFINE_MUTEX(smack_list_lock);
static DEFINE_MUTEX(smack_cipso_lock);
static DEFINE_MUTEX(smack_ambient_lock);
static DEFINE_MUTEX(smk_netlbladdr_lock);
+static DEFINE_MUTEX(smack_version_lock);
/*
* This is the "ambient" label for network traffic.
@@ -60,6 +62,11 @@ static DEFINE_MUTEX(smk_netlbladdr_lock);
char *smack_net_ambient = smack_known_floor.smk_known;
/*
+ * this is the policy version, a simple integer
+ */
+int smack_version = 1;
+
+/*
* This is the level in a CIPSO header that indicates a
* smack label is contained directly in the category set.
* It can be reset via smackfs/direct
@@ -1255,6 +1262,72 @@ static const struct file_operations smk_logging_ops = {
.read = smk_read_logging,
.write = smk_write_logging,
};
+
+#define SMK_VERSIONLEN 12
+/**
+ * smk_read_version - read() for /smack/version
+ * @filp: file pointer, not actually used
+ * @buf: where to put the result
+ * @cn: maximum to send along
+ * @ppos: where to start
+ *
+ * Returns number of bytes read or error code, as appropriate
+ */
+static ssize_t smk_read_version(struct file *filp, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ char temp[SMK_VERSIONLEN];
+
+ if (*ppos != 0)
+ return 0;
+
+ mutex_lock(&smack_version_lock);
+ sprintf(temp, "%d\n", smack_version);
+ mutex_unlock(&smack_version_lock);
+
+ return simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
+}
+
+/**
+ * smk_write_version - write() for /smack/version
+ * @file: file pointer, not actually used
+ * @buf: where to get the data from
+ * @count: bytes sent
+ * @ppos: where to start
+ *
+ * Returns number of bytes written or error code, as appropriate
+ */
+static ssize_t smk_write_version(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ char in[SMK_VERSIONLEN];
+ int tmp, ret;
+
+ if (!capable(CAP_MAC_ADMIN))
+ return -EPERM;
+
+ if (count >= SMK_VERSIONLEN)
+ return -EINVAL;
+
+ if (copy_from_user(in, buf, count) != 0)
+ return -EFAULT;
+
+ in[count-1] = '\0';
+ ret = sscanf(in, "%d", &tmp);
+ if (ret != 1)
+ return -EINVAL;
+ mutex_lock(&smack_version_lock);
+ smack_version = tmp;
+ mutex_unlock(&smack_version_lock);
+
+ return count;
+}
+
+static const struct file_operations smk_version_ops = {
+ .read = smk_read_version,
+ .write = smk_write_version,
+};
+
/**
* smk_fill_super - fill the /smackfs superblock
* @sb: the empty superblock
@@ -1287,6 +1360,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
{"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR},
[SMK_LOGGING] =
{"logging", &smk_logging_ops, S_IRUGO|S_IWUSR},
+ [SMK_VERSION] =
+ {"version", &smk_version_ops, S_IRUGO|S_IWUSR},
/* last one */ {""}
};
--
1.6.1
--
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.
next prev parent reply other threads:[~2009-09-03 22:28 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-09-03 22:28 [RFC PATCH 1/2] cr: lsm: provide hooks for an LSM to track policy changes Serge E. Hallyn
2009-09-03 22:28 ` Serge E. Hallyn
2009-09-03 22:28 ` Serge E. Hallyn [this message]
2009-09-03 22:28 ` [RFC PATCH 2/2] cr: debug security_checkpoint_header and security_may_restart Serge E. Hallyn
2009-09-04 5:20 ` Casey Schaufler
2009-09-04 5:20 ` Casey Schaufler
2009-09-04 13:46 ` Serge E. Hallyn
2009-09-04 13:46 ` Serge E. Hallyn
2009-09-07 18:31 ` Casey Schaufler
2009-09-07 18:31 ` Casey Schaufler
2009-09-08 4:12 ` Serge E. Hallyn
2009-09-08 4:12 ` Serge E. Hallyn
2009-09-09 4:43 ` Casey Schaufler
2009-09-09 4:43 ` Casey Schaufler
2009-09-09 14:35 ` Serge E. Hallyn
2009-09-09 14:35 ` Serge E. Hallyn
2009-09-09 14:52 ` Casey Schaufler
2009-09-09 14:52 ` Casey Schaufler
2009-09-09 19:46 ` Serge E. Hallyn
2009-09-09 19:46 ` Serge E. Hallyn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090903222853.GA27556@us.ibm.com \
--to=serue@us.ibm.com \
--cc=casey@schaufler-ca.com \
--cc=containers@lists.osdl.org \
--cc=linux-security-module@vger.kernel.org \
--cc=orenl@cs.columbia.edu \
--cc=selinux@tycho.nsa.gov \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.