summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElena Reshetova <elena.reshetova@intel.com>2013-11-11 10:50:50 +0200
committerElena Reshetova <elena.reshetova@intel.com>2013-11-11 15:24:05 +0200
commitc52077b864906af4854d7cb509f10339fde085b7 (patch)
tree63e9e8535871673ecde86ee2eefc966f97bc1f24
parentcb212a7ac8d37ae6f97270c6171d88a8ce53e188 (diff)
downloadkernel-mfld-blackbay-c52077b864906af4854d7cb509f10339fde085b7.tar.gz
kernel-mfld-blackbay-c52077b864906af4854d7cb509f10339fde085b7.tar.bz2
kernel-mfld-blackbay-c52077b864906af4854d7cb509f10339fde085b7.zip
Subject: [PATCH] Smack: Implement lock security mode
Linux file locking does not follow the same rules as other mechanisms. Even though it is a write operation a process can set a read lock on files which it has open only for read access. Two programs with read access to a file can use read locks to communicate. This is not acceptable in a Mandatory Access Control environment. Smack treats setting a read lock as the write operation that it is. Unfortunately, many programs assume that setting a read lock is a read operation. These programs are unhappy in the Smack environment. This patch introduces a new access mode (lock) to address this problem. A process with lock access to a file can set a read lock. A process with write access to a file can set a read lock or a write lock. This prevents a situation where processes are granted write access just so they can set read locks. Targeted for git://git.gitorious.org/smack-next/kernel.git Change-Id: I22ca438a655ff9f72055ae6278a88acd71904822 Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
-rw-r--r--security/smack/smack.h12
-rw-r--r--security/smack/smack_access.c10
-rw-r--r--security/smack/smack_lsm.c9
-rw-r--r--security/smack/smackfs.c10
4 files changed, 33 insertions, 8 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h
index a34c350eaf2..787bd1c1ddc 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -166,9 +166,13 @@ struct smack_known {
#define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */
/*
- * Flag for transmute access
+ * Flags for untraditional access modes.
+ * It shouldn't be necessary to avoid conflicts with definitions
+ * in fs.h, but do so anyway.
*/
-#define MAY_TRANSMUTE 64
+#define MAY_TRANSMUTE 0x00001000 /* Controls directory labeling */
+#define MAY_LOCK 0x00002000 /* Locks should be writes, but ... */
+
/*
* Just to make the common cases easier to deal with
*/
@@ -177,9 +181,9 @@ struct smack_known {
#define MAY_NOT 0
/*
- * Number of access types used by Smack (rwxat)
+ * Number of access types used by Smack (rwxatl)
*/
-#define SMK_NUM_ACCESS_TYPE 5
+#define SMK_NUM_ACCESS_TYPE 6
/*
* Smack audit data; is empty if CONFIG_AUDIT not set
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index bd8338f9b8c..a2f2f8f0bd0 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -84,6 +84,8 @@ int log_policy = SMACK_AUDIT_DENIED;
*
* Do the object check first because that is more
* likely to differ.
+ *
+ * Allowing write access implies allowing locking.
*/
int smk_access_entry(char *subject_label, char *object_label,
struct list_head *rule_list)
@@ -99,6 +101,11 @@ int smk_access_entry(char *subject_label, char *object_label,
}
}
+ /*
+ * MAY_WRITE implies MAY_LOCK.
+ */
+ if ((may & MAY_WRITE) == MAY_WRITE)
+ may |= MAY_LOCK;
return may;
}
@@ -244,6 +251,7 @@ out_audit:
static inline void smack_str_from_perm(char *string, int access)
{
int i = 0;
+
if (access & MAY_READ)
string[i++] = 'r';
if (access & MAY_WRITE)
@@ -254,6 +262,8 @@ static inline void smack_str_from_perm(char *string, int access)
string[i++] = 'a';
if (access & MAY_TRANSMUTE)
string[i++] = 't';
+ if (access & MAY_LOCK)
+ string[i++] = 'l';
string[i] = '\0';
}
/**
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 4a3e0c1cb23..6cee84b5239 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1132,7 +1132,7 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
* @file: the object
* @cmd: unused
*
- * Returns 0 if current has write access, error code otherwise
+ * Returns 0 if current has lock access, error code otherwise
*/
static int smack_file_lock(struct file *file, unsigned int cmd)
{
@@ -1140,7 +1140,7 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
smk_ad_setfield_u_fs_path(&ad, file->f_path);
- return smk_curacc(file->f_security, MAY_WRITE, &ad);
+ return smk_curacc(file->f_security, MAY_LOCK, &ad);
}
/**
@@ -1164,8 +1164,13 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
switch (cmd) {
case F_GETLK:
+ break;
case F_SETLK:
case F_SETLKW:
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_setfield_u_fs_path(&ad, file->f_path);
+ rc = smk_curacc(file->f_security, MAY_LOCK, &ad);
+ break;
case F_SETOWN:
case F_SETSIG:
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index e9563c376ed..752c140055b 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -139,7 +139,7 @@ const char *smack_cipso_option = SMACK_CIPSO_OPTION;
* SMK_LOADLEN: Smack rule length
*/
#define SMK_OACCESS "rwxa"
-#define SMK_ACCESS "rwxat"
+#define SMK_ACCESS "rwxatl"
#define SMK_OACCESSLEN (sizeof(SMK_OACCESS) - 1)
#define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1)
#define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN)
@@ -280,6 +280,10 @@ static int smk_perm_from_str(const char *string)
case 'T':
perm |= MAY_TRANSMUTE;
break;
+ case 'l':
+ case 'L':
+ perm |= MAY_LOCK;
+ break;
default:
return perm;
}
@@ -463,7 +467,7 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
/*
* Minor hack for backward compatibility
*/
- if (count != SMK_OLOADLEN && count != SMK_LOADLEN)
+ if (count < SMK_OLOADLEN || count > SMK_LOADLEN)
return -EINVAL;
datalen = SMK_LOADLEN;
} else
@@ -599,6 +603,8 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
seq_putc(s, 'a');
if (srp->smk_access & MAY_TRANSMUTE)
seq_putc(s, 't');
+ if (srp->smk_access & MAY_LOCK)
+ seq_putc(s, 'l');
seq_putc(s, '\n');
}