aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2013-10-11 21:06:39 -0400
committerCasey Schaufler <casey@schaufler-ca.com>2013-10-18 12:39:33 -0400
commitc0ab6e56dcb7ca9903d460247cb464e769ae6e77 (patch)
tree52da39cb2798c0a4276d0d23fa3b4f1dbcd732f2 /security
parent5a5f2acfd04269e2e0958067216b68ff461c285c (diff)
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 Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Diffstat (limited to 'security')
-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 076b8e8a51ab..364cc64fce71 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -177,9 +177,13 @@ struct smk_port_label {
177#define SMACK_CIPSO_MAXCATNUM 184 /* 23 * 8 */ 177#define SMACK_CIPSO_MAXCATNUM 184 /* 23 * 8 */
178 178
179/* 179/*
180 * Flag for transmute access 180 * Flags for untraditional access modes.
181 * It shouldn't be necessary to avoid conflicts with definitions
182 * in fs.h, but do so anyway.
181 */ 183 */
182#define MAY_TRANSMUTE 64 184#define MAY_TRANSMUTE 0x00001000 /* Controls directory labeling */
185#define MAY_LOCK 0x00002000 /* Locks should be writes, but ... */
186
183/* 187/*
184 * Just to make the common cases easier to deal with 188 * Just to make the common cases easier to deal with
185 */ 189 */
@@ -188,9 +192,9 @@ struct smk_port_label {
188#define MAY_NOT 0 192#define MAY_NOT 0
189 193
190/* 194/*
191 * Number of access types used by Smack (rwxat) 195 * Number of access types used by Smack (rwxatl)
192 */ 196 */
193#define SMK_NUM_ACCESS_TYPE 5 197#define SMK_NUM_ACCESS_TYPE 6
194 198
195/* SMACK data */ 199/* SMACK data */
196struct smack_audit_data { 200struct smack_audit_data {
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index b3b59b1e93d6..14293cd9b1e5 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -84,6 +84,8 @@ int log_policy = SMACK_AUDIT_DENIED;
84 * 84 *
85 * Do the object check first because that is more 85 * Do the object check first because that is more
86 * likely to differ. 86 * likely to differ.
87 *
88 * Allowing write access implies allowing locking.
87 */ 89 */
88int smk_access_entry(char *subject_label, char *object_label, 90int smk_access_entry(char *subject_label, char *object_label,
89 struct list_head *rule_list) 91 struct list_head *rule_list)
@@ -99,6 +101,11 @@ int smk_access_entry(char *subject_label, char *object_label,
99 } 101 }
100 } 102 }
101 103
104 /*
105 * MAY_WRITE implies MAY_LOCK.
106 */
107 if ((may & MAY_WRITE) == MAY_WRITE)
108 may |= MAY_LOCK;
102 return may; 109 return may;
103} 110}
104 111
@@ -245,6 +252,7 @@ out_audit:
245static inline void smack_str_from_perm(char *string, int access) 252static inline void smack_str_from_perm(char *string, int access)
246{ 253{
247 int i = 0; 254 int i = 0;
255
248 if (access & MAY_READ) 256 if (access & MAY_READ)
249 string[i++] = 'r'; 257 string[i++] = 'r';
250 if (access & MAY_WRITE) 258 if (access & MAY_WRITE)
@@ -255,6 +263,8 @@ static inline void smack_str_from_perm(char *string, int access)
255 string[i++] = 'a'; 263 string[i++] = 'a';
256 if (access & MAY_TRANSMUTE) 264 if (access & MAY_TRANSMUTE)
257 string[i++] = 't'; 265 string[i++] = 't';
266 if (access & MAY_LOCK)
267 string[i++] = 'l';
258 string[i] = '\0'; 268 string[i] = '\0';
259} 269}
260/** 270/**
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 8825375cc031..88d366e55793 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1146,7 +1146,7 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
1146 * @file: the object 1146 * @file: the object
1147 * @cmd: unused 1147 * @cmd: unused
1148 * 1148 *
1149 * Returns 0 if current has write access, error code otherwise 1149 * Returns 0 if current has lock access, error code otherwise
1150 */ 1150 */
1151static int smack_file_lock(struct file *file, unsigned int cmd) 1151static int smack_file_lock(struct file *file, unsigned int cmd)
1152{ 1152{
@@ -1154,7 +1154,7 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
1154 1154
1155 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); 1155 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1156 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1156 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1157 return smk_curacc(file->f_security, MAY_WRITE, &ad); 1157 return smk_curacc(file->f_security, MAY_LOCK, &ad);
1158} 1158}
1159 1159
1160/** 1160/**
@@ -1178,8 +1178,13 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
1178 1178
1179 switch (cmd) { 1179 switch (cmd) {
1180 case F_GETLK: 1180 case F_GETLK:
1181 break;
1181 case F_SETLK: 1182 case F_SETLK:
1182 case F_SETLKW: 1183 case F_SETLKW:
1184 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1185 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1186 rc = smk_curacc(file->f_security, MAY_LOCK, &ad);
1187 break;
1183 case F_SETOWN: 1188 case F_SETOWN:
1184 case F_SETSIG: 1189 case F_SETSIG:
1185 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); 1190 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 80f4b4a45725..160aa08e3cd5 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -139,7 +139,7 @@ const char *smack_cipso_option = SMACK_CIPSO_OPTION;
139 * SMK_LOADLEN: Smack rule length 139 * SMK_LOADLEN: Smack rule length
140 */ 140 */
141#define SMK_OACCESS "rwxa" 141#define SMK_OACCESS "rwxa"
142#define SMK_ACCESS "rwxat" 142#define SMK_ACCESS "rwxatl"
143#define SMK_OACCESSLEN (sizeof(SMK_OACCESS) - 1) 143#define SMK_OACCESSLEN (sizeof(SMK_OACCESS) - 1)
144#define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) 144#define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1)
145#define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN) 145#define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN)
@@ -282,6 +282,10 @@ static int smk_perm_from_str(const char *string)
282 case 'T': 282 case 'T':
283 perm |= MAY_TRANSMUTE; 283 perm |= MAY_TRANSMUTE;
284 break; 284 break;
285 case 'l':
286 case 'L':
287 perm |= MAY_LOCK;
288 break;
285 default: 289 default:
286 return perm; 290 return perm;
287 } 291 }
@@ -452,7 +456,7 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
452 /* 456 /*
453 * Minor hack for backward compatibility 457 * Minor hack for backward compatibility
454 */ 458 */
455 if (count != SMK_OLOADLEN && count != SMK_LOADLEN) 459 if (count < SMK_OLOADLEN || count > SMK_LOADLEN)
456 return -EINVAL; 460 return -EINVAL;
457 } else { 461 } else {
458 if (count >= PAGE_SIZE) { 462 if (count >= PAGE_SIZE) {
@@ -592,6 +596,8 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
592 seq_putc(s, 'a'); 596 seq_putc(s, 'a');
593 if (srp->smk_access & MAY_TRANSMUTE) 597 if (srp->smk_access & MAY_TRANSMUTE)
594 seq_putc(s, 't'); 598 seq_putc(s, 't');
599 if (srp->smk_access & MAY_LOCK)
600 seq_putc(s, 'l');
595 601
596 seq_putc(s, '\n'); 602 seq_putc(s, '\n');
597} 603}