diff options
author | Jarkko Sakkinen <ext-jarkko.2.sakkinen@nokia.com> | 2010-12-07 06:34:01 -0500 |
---|---|---|
committer | Casey Schaufler <casey@schaufler-ca.com> | 2010-12-07 17:04:02 -0500 |
commit | 5c6d1125f8dbd1bfef39e38fbc2837003be78a59 (patch) | |
tree | 368d34e800bc5478442679323270d776b79501e8 /security/smack/smackfs.c | |
parent | fe27d4b012273640e033be80f143bdc54daa8e16 (diff) |
Smack: Transmute labels on specified directories
In a situation where Smack access rules allow processes
with multiple labels to write to a directory it is easy
to get into a situation where the directory gets cluttered
with files that the owner can't deal with because while
they could be written to the directory a process at the
label of the directory can't write them. This is generally
the desired behavior, but when it isn't it is a real
issue.
This patch introduces a new attribute SMACK64TRANSMUTE that
instructs Smack to create the file with the label of the directory
under certain circumstances.
A new access mode, "t" for transmute, is made available to
Smack access rules, which are expanded from "rwxa" to "rwxat".
If a file is created in a directory marked as transmutable
and if access was granted to perform the operation by a rule
that included the transmute mode, then the file gets the
Smack label of the directory instead of the Smack label of the
creating process.
Note that this is equivalent to creating an empty file at the
label of the directory and then having the other process write
to it. The transmute scheme requires that both the access rule
allows transmutation and that the directory be explicitly marked.
Signed-off-by: Jarkko Sakkinen <ext-jarkko.2.sakkinen@nokia.com>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r-- | security/smack/smackfs.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 01a0be93d8d0..362d5eda948b 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
@@ -109,9 +109,12 @@ const char *smack_cipso_option = SMACK_CIPSO_OPTION; | |||
109 | * SMK_ACCESSLEN: Maximum length for a rule access field | 109 | * SMK_ACCESSLEN: Maximum length for a rule access field |
110 | * SMK_LOADLEN: Smack rule length | 110 | * SMK_LOADLEN: Smack rule length |
111 | */ | 111 | */ |
112 | #define SMK_ACCESS "rwxa" | 112 | #define SMK_OACCESS "rwxa" |
113 | #define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) | 113 | #define SMK_ACCESS "rwxat" |
114 | #define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) | 114 | #define SMK_OACCESSLEN (sizeof(SMK_OACCESS) - 1) |
115 | #define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) | ||
116 | #define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN) | ||
117 | #define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) | ||
115 | 118 | ||
116 | /** | 119 | /** |
117 | * smk_netlabel_audit_set - fill a netlbl_audit struct | 120 | * smk_netlabel_audit_set - fill a netlbl_audit struct |
@@ -175,6 +178,8 @@ static int load_seq_show(struct seq_file *s, void *v) | |||
175 | seq_putc(s, 'x'); | 178 | seq_putc(s, 'x'); |
176 | if (srp->smk_access & MAY_APPEND) | 179 | if (srp->smk_access & MAY_APPEND) |
177 | seq_putc(s, 'a'); | 180 | seq_putc(s, 'a'); |
181 | if (srp->smk_access & MAY_TRANSMUTE) | ||
182 | seq_putc(s, 't'); | ||
178 | if (srp->smk_access == 0) | 183 | if (srp->smk_access == 0) |
179 | seq_putc(s, '-'); | 184 | seq_putc(s, '-'); |
180 | 185 | ||
@@ -273,10 +278,15 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf, | |||
273 | if (!capable(CAP_MAC_ADMIN)) | 278 | if (!capable(CAP_MAC_ADMIN)) |
274 | return -EPERM; | 279 | return -EPERM; |
275 | 280 | ||
276 | if (*ppos != 0 || count != SMK_LOADLEN) | 281 | if (*ppos != 0) |
282 | return -EINVAL; | ||
283 | /* | ||
284 | * Minor hack for backward compatability | ||
285 | */ | ||
286 | if (count < (SMK_OLOADLEN) || count > SMK_LOADLEN) | ||
277 | return -EINVAL; | 287 | return -EINVAL; |
278 | 288 | ||
279 | data = kzalloc(count, GFP_KERNEL); | 289 | data = kzalloc(SMK_LOADLEN, GFP_KERNEL); |
280 | if (data == NULL) | 290 | if (data == NULL) |
281 | return -ENOMEM; | 291 | return -ENOMEM; |
282 | 292 | ||
@@ -285,6 +295,12 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf, | |||
285 | goto out; | 295 | goto out; |
286 | } | 296 | } |
287 | 297 | ||
298 | /* | ||
299 | * More on the minor hack for backward compatability | ||
300 | */ | ||
301 | if (count == (SMK_OLOADLEN)) | ||
302 | data[SMK_OLOADLEN] = '-'; | ||
303 | |||
288 | rule = kzalloc(sizeof(*rule), GFP_KERNEL); | 304 | rule = kzalloc(sizeof(*rule), GFP_KERNEL); |
289 | if (rule == NULL) { | 305 | if (rule == NULL) { |
290 | rc = -ENOMEM; | 306 | rc = -ENOMEM; |
@@ -345,6 +361,17 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf, | |||
345 | goto out_free_rule; | 361 | goto out_free_rule; |
346 | } | 362 | } |
347 | 363 | ||
364 | switch (data[SMK_LABELLEN + SMK_LABELLEN + 4]) { | ||
365 | case '-': | ||
366 | break; | ||
367 | case 't': | ||
368 | case 'T': | ||
369 | rule->smk_access |= MAY_TRANSMUTE; | ||
370 | break; | ||
371 | default: | ||
372 | goto out_free_rule; | ||
373 | } | ||
374 | |||
348 | rc = smk_set_access(rule); | 375 | rc = smk_set_access(rule); |
349 | 376 | ||
350 | if (!rc) | 377 | if (!rc) |