aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smackfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r--security/smack/smackfs.c134
1 files changed, 111 insertions, 23 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 160aa08e3cd5..3198cfe1dcc6 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -52,6 +52,7 @@ enum smk_inos {
52 SMK_CIPSO2 = 17, /* load long label -> CIPSO mapping */ 52 SMK_CIPSO2 = 17, /* load long label -> CIPSO mapping */
53 SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */ 53 SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */
54 SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */ 54 SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */
55 SMK_SYSLOG = 20, /* change syslog label) */
55}; 56};
56 57
57/* 58/*
@@ -59,6 +60,7 @@ enum smk_inos {
59 */ 60 */
60static DEFINE_MUTEX(smack_cipso_lock); 61static DEFINE_MUTEX(smack_cipso_lock);
61static DEFINE_MUTEX(smack_ambient_lock); 62static DEFINE_MUTEX(smack_ambient_lock);
63static DEFINE_MUTEX(smack_syslog_lock);
62static DEFINE_MUTEX(smk_netlbladdr_lock); 64static DEFINE_MUTEX(smk_netlbladdr_lock);
63 65
64/* 66/*
@@ -90,7 +92,13 @@ int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT;
90 * everyone. It is expected that the hat (^) label 92 * everyone. It is expected that the hat (^) label
91 * will be used if any label is used. 93 * will be used if any label is used.
92 */ 94 */
93char *smack_onlycap; 95struct smack_known *smack_onlycap;
96
97/*
98 * If this value is set restrict syslog use to the label specified.
99 * It can be reset via smackfs/syslog
100 */
101struct smack_known *smack_syslog_label;
94 102
95/* 103/*
96 * Certain IP addresses may be designated as single label hosts. 104 * Certain IP addresses may be designated as single label hosts.
@@ -301,7 +309,8 @@ static int smk_perm_from_str(const char *string)
301 * @import: if non-zero, import labels 309 * @import: if non-zero, import labels
302 * @len: label length limit 310 * @len: label length limit
303 * 311 *
304 * Returns 0 on success, -1 on failure 312 * Returns 0 on success, -EINVAL on failure and -ENOENT when either subject
313 * or object is missing.
305 */ 314 */
306static int smk_fill_rule(const char *subject, const char *object, 315static int smk_fill_rule(const char *subject, const char *object,
307 const char *access1, const char *access2, 316 const char *access1, const char *access2,
@@ -314,28 +323,28 @@ static int smk_fill_rule(const char *subject, const char *object,
314 if (import) { 323 if (import) {
315 rule->smk_subject = smk_import_entry(subject, len); 324 rule->smk_subject = smk_import_entry(subject, len);
316 if (rule->smk_subject == NULL) 325 if (rule->smk_subject == NULL)
317 return -1; 326 return -EINVAL;
318 327
319 rule->smk_object = smk_import(object, len); 328 rule->smk_object = smk_import(object, len);
320 if (rule->smk_object == NULL) 329 if (rule->smk_object == NULL)
321 return -1; 330 return -EINVAL;
322 } else { 331 } else {
323 cp = smk_parse_smack(subject, len); 332 cp = smk_parse_smack(subject, len);
324 if (cp == NULL) 333 if (cp == NULL)
325 return -1; 334 return -EINVAL;
326 skp = smk_find_entry(cp); 335 skp = smk_find_entry(cp);
327 kfree(cp); 336 kfree(cp);
328 if (skp == NULL) 337 if (skp == NULL)
329 return -1; 338 return -ENOENT;
330 rule->smk_subject = skp; 339 rule->smk_subject = skp;
331 340
332 cp = smk_parse_smack(object, len); 341 cp = smk_parse_smack(object, len);
333 if (cp == NULL) 342 if (cp == NULL)
334 return -1; 343 return -EINVAL;
335 skp = smk_find_entry(cp); 344 skp = smk_find_entry(cp);
336 kfree(cp); 345 kfree(cp);
337 if (skp == NULL) 346 if (skp == NULL)
338 return -1; 347 return -ENOENT;
339 rule->smk_object = skp->smk_known; 348 rule->smk_object = skp->smk_known;
340 } 349 }
341 350
@@ -381,6 +390,7 @@ static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule,
381{ 390{
382 ssize_t cnt = 0; 391 ssize_t cnt = 0;
383 char *tok[4]; 392 char *tok[4];
393 int rc;
384 int i; 394 int i;
385 395
386 /* 396 /*
@@ -405,10 +415,8 @@ static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule,
405 while (i < 4) 415 while (i < 4)
406 tok[i++] = NULL; 416 tok[i++] = NULL;
407 417
408 if (smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0)) 418 rc = smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0);
409 return -1; 419 return rc == 0 ? cnt : rc;
410
411 return cnt;
412} 420}
413 421
414#define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */ 422#define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */
@@ -1603,7 +1611,7 @@ static const struct file_operations smk_ambient_ops = {
1603}; 1611};
1604 1612
1605/** 1613/**
1606 * smk_read_onlycap - read() for /smack/onlycap 1614 * smk_read_onlycap - read() for smackfs/onlycap
1607 * @filp: file pointer, not actually used 1615 * @filp: file pointer, not actually used
1608 * @buf: where to put the result 1616 * @buf: where to put the result
1609 * @cn: maximum to send along 1617 * @cn: maximum to send along
@@ -1622,7 +1630,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
1622 return 0; 1630 return 0;
1623 1631
1624 if (smack_onlycap != NULL) 1632 if (smack_onlycap != NULL)
1625 smack = smack_onlycap; 1633 smack = smack_onlycap->smk_known;
1626 1634
1627 asize = strlen(smack) + 1; 1635 asize = strlen(smack) + 1;
1628 1636
@@ -1633,7 +1641,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
1633} 1641}
1634 1642
1635/** 1643/**
1636 * smk_write_onlycap - write() for /smack/onlycap 1644 * smk_write_onlycap - write() for smackfs/onlycap
1637 * @file: file pointer, not actually used 1645 * @file: file pointer, not actually used
1638 * @buf: where to get the data from 1646 * @buf: where to get the data from
1639 * @count: bytes sent 1647 * @count: bytes sent
@@ -1656,7 +1664,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1656 * explicitly for clarity. The smk_access() implementation 1664 * explicitly for clarity. The smk_access() implementation
1657 * would use smk_access(smack_onlycap, MAY_WRITE) 1665 * would use smk_access(smack_onlycap, MAY_WRITE)
1658 */ 1666 */
1659 if (smack_onlycap != NULL && smack_onlycap != skp->smk_known) 1667 if (smack_onlycap != NULL && smack_onlycap != skp)
1660 return -EPERM; 1668 return -EPERM;
1661 1669
1662 data = kzalloc(count, GFP_KERNEL); 1670 data = kzalloc(count, GFP_KERNEL);
@@ -1676,7 +1684,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1676 if (copy_from_user(data, buf, count) != 0) 1684 if (copy_from_user(data, buf, count) != 0)
1677 rc = -EFAULT; 1685 rc = -EFAULT;
1678 else 1686 else
1679 smack_onlycap = smk_import(data, count); 1687 smack_onlycap = smk_import_entry(data, count);
1680 1688
1681 kfree(data); 1689 kfree(data);
1682 return rc; 1690 return rc;
@@ -1856,11 +1864,12 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
1856 res = smk_parse_long_rule(data, &rule, 0, 3); 1864 res = smk_parse_long_rule(data, &rule, 0, 3);
1857 } 1865 }
1858 1866
1859 if (res < 0) 1867 if (res >= 0)
1868 res = smk_access(rule.smk_subject, rule.smk_object,
1869 rule.smk_access1, NULL);
1870 else if (res != -ENOENT)
1860 return -EINVAL; 1871 return -EINVAL;
1861 1872
1862 res = smk_access(rule.smk_subject, rule.smk_object,
1863 rule.smk_access1, NULL);
1864 data[0] = res == 0 ? '1' : '0'; 1873 data[0] = res == 0 ? '1' : '0';
1865 data[1] = '\0'; 1874 data[1] = '\0';
1866 1875
@@ -2143,7 +2152,7 @@ static ssize_t smk_write_change_rule(struct file *file, const char __user *buf,
2143 /* 2152 /*
2144 * Must have privilege. 2153 * Must have privilege.
2145 */ 2154 */
2146 if (!capable(CAP_MAC_ADMIN)) 2155 if (!smack_privileged(CAP_MAC_ADMIN))
2147 return -EPERM; 2156 return -EPERM;
2148 2157
2149 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, 2158 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
@@ -2158,12 +2167,89 @@ static const struct file_operations smk_change_rule_ops = {
2158}; 2167};
2159 2168
2160/** 2169/**
2161 * smk_fill_super - fill the /smackfs superblock 2170 * smk_read_syslog - read() for smackfs/syslog
2171 * @filp: file pointer, not actually used
2172 * @buf: where to put the result
2173 * @cn: maximum to send along
2174 * @ppos: where to start
2175 *
2176 * Returns number of bytes read or error code, as appropriate
2177 */
2178static ssize_t smk_read_syslog(struct file *filp, char __user *buf,
2179 size_t cn, loff_t *ppos)
2180{
2181 struct smack_known *skp;
2182 ssize_t rc = -EINVAL;
2183 int asize;
2184
2185 if (*ppos != 0)
2186 return 0;
2187
2188 if (smack_syslog_label == NULL)
2189 skp = &smack_known_star;
2190 else
2191 skp = smack_syslog_label;
2192
2193 asize = strlen(skp->smk_known) + 1;
2194
2195 if (cn >= asize)
2196 rc = simple_read_from_buffer(buf, cn, ppos, skp->smk_known,
2197 asize);
2198
2199 return rc;
2200}
2201
2202/**
2203 * smk_write_syslog - write() for smackfs/syslog
2204 * @file: file pointer, not actually used
2205 * @buf: where to get the data from
2206 * @count: bytes sent
2207 * @ppos: where to start
2208 *
2209 * Returns number of bytes written or error code, as appropriate
2210 */
2211static ssize_t smk_write_syslog(struct file *file, const char __user *buf,
2212 size_t count, loff_t *ppos)
2213{
2214 char *data;
2215 struct smack_known *skp;
2216 int rc = count;
2217
2218 if (!smack_privileged(CAP_MAC_ADMIN))
2219 return -EPERM;
2220
2221 data = kzalloc(count, GFP_KERNEL);
2222 if (data == NULL)
2223 return -ENOMEM;
2224
2225 if (copy_from_user(data, buf, count) != 0)
2226 rc = -EFAULT;
2227 else {
2228 skp = smk_import_entry(data, count);
2229 if (skp == NULL)
2230 rc = -EINVAL;
2231 else
2232 smack_syslog_label = smk_import_entry(data, count);
2233 }
2234
2235 kfree(data);
2236 return rc;
2237}
2238
2239static const struct file_operations smk_syslog_ops = {
2240 .read = smk_read_syslog,
2241 .write = smk_write_syslog,
2242 .llseek = default_llseek,
2243};
2244
2245
2246/**
2247 * smk_fill_super - fill the smackfs superblock
2162 * @sb: the empty superblock 2248 * @sb: the empty superblock
2163 * @data: unused 2249 * @data: unused
2164 * @silent: unused 2250 * @silent: unused
2165 * 2251 *
2166 * Fill in the well known entries for /smack 2252 * Fill in the well known entries for the smack filesystem
2167 * 2253 *
2168 * Returns 0 on success, an error code on failure 2254 * Returns 0 on success, an error code on failure
2169 */ 2255 */
@@ -2208,6 +2294,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
2208 S_IRUGO|S_IWUSR}, 2294 S_IRUGO|S_IWUSR},
2209 [SMK_CHANGE_RULE] = { 2295 [SMK_CHANGE_RULE] = {
2210 "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR}, 2296 "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR},
2297 [SMK_SYSLOG] = {
2298 "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR},
2211 /* last one */ 2299 /* last one */
2212 {""} 2300 {""}
2213 }; 2301 };