diff options
author | Casey Schaufler <casey@schaufler-ca.com> | 2013-12-23 14:07:10 -0500 |
---|---|---|
committer | Casey Schaufler <casey@schaufler-ca.com> | 2013-12-23 18:50:55 -0500 |
commit | 00f84f3f2e9d088f06722f4351d67f5f577abe22 (patch) | |
tree | 06ac369a9dac582d9d9710aba38c684f048774ba /security/smack | |
parent | 19760ad03cc639d6f6f8e9beff0f8e6df654b677 (diff) |
Smack: Make the syslog control configurable
The syslog control requires that the calling proccess
have the floor ("_") Smack label. Tizen does not run any
processes except for kernel helpers with the floor label.
This changes allows the admin to configure a specific
label for syslog. The default value is the star ("*")
label, effectively removing the restriction. The value
can be set using smackfs/syslog for anyone who wants
a more restrictive behavior.
Targeted for git://git.gitorious.org/smack-next/kernel.git
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Diffstat (limited to 'security/smack')
-rw-r--r-- | security/smack/smack.h | 5 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 4 | ||||
-rw-r--r-- | security/smack/smackfs.c | 103 |
3 files changed, 99 insertions, 13 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h index 364cc64fce71..d072fd32212d 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
@@ -241,7 +241,8 @@ u32 smack_to_secid(const char *); | |||
241 | extern int smack_cipso_direct; | 241 | extern int smack_cipso_direct; |
242 | extern int smack_cipso_mapped; | 242 | extern int smack_cipso_mapped; |
243 | extern struct smack_known *smack_net_ambient; | 243 | extern struct smack_known *smack_net_ambient; |
244 | extern char *smack_onlycap; | 244 | extern struct smack_known *smack_onlycap; |
245 | extern struct smack_known *smack_syslog_label; | ||
245 | extern const char *smack_cipso_option; | 246 | extern const char *smack_cipso_option; |
246 | 247 | ||
247 | extern struct smack_known smack_known_floor; | 248 | extern struct smack_known smack_known_floor; |
@@ -312,7 +313,7 @@ static inline int smack_privileged(int cap) | |||
312 | 313 | ||
313 | if (!capable(cap)) | 314 | if (!capable(cap)) |
314 | return 0; | 315 | return 0; |
315 | if (smack_onlycap == NULL || smack_onlycap == skp->smk_known) | 316 | if (smack_onlycap == NULL || smack_onlycap == skp) |
316 | return 1; | 317 | return 1; |
317 | return 0; | 318 | return 0; |
318 | } | 319 | } |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 62ebf4f8a6c7..67b7381d0244 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -219,8 +219,6 @@ static int smack_ptrace_traceme(struct task_struct *ptp) | |||
219 | * smack_syslog - Smack approval on syslog | 219 | * smack_syslog - Smack approval on syslog |
220 | * @type: message type | 220 | * @type: message type |
221 | * | 221 | * |
222 | * Require that the task has the floor label | ||
223 | * | ||
224 | * Returns 0 on success, error code otherwise. | 222 | * Returns 0 on success, error code otherwise. |
225 | */ | 223 | */ |
226 | static int smack_syslog(int typefrom_file) | 224 | static int smack_syslog(int typefrom_file) |
@@ -231,7 +229,7 @@ static int smack_syslog(int typefrom_file) | |||
231 | if (smack_privileged(CAP_MAC_OVERRIDE)) | 229 | if (smack_privileged(CAP_MAC_OVERRIDE)) |
232 | return 0; | 230 | return 0; |
233 | 231 | ||
234 | if (skp != &smack_known_floor) | 232 | if (smack_syslog_label != NULL && smack_syslog_label != skp) |
235 | rc = -EACCES; | 233 | rc = -EACCES; |
236 | 234 | ||
237 | return rc; | 235 | return rc; |
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 1c89ade186b6..f5a6bb8e2828 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 | */ |
60 | static DEFINE_MUTEX(smack_cipso_lock); | 61 | static DEFINE_MUTEX(smack_cipso_lock); |
61 | static DEFINE_MUTEX(smack_ambient_lock); | 62 | static DEFINE_MUTEX(smack_ambient_lock); |
63 | static DEFINE_MUTEX(smack_syslog_lock); | ||
62 | static DEFINE_MUTEX(smk_netlbladdr_lock); | 64 | static 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 | */ |
93 | char *smack_onlycap; | 95 | struct 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 | */ | ||
101 | struct 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. |
@@ -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; |
@@ -2159,12 +2167,89 @@ static const struct file_operations smk_change_rule_ops = { | |||
2159 | }; | 2167 | }; |
2160 | 2168 | ||
2161 | /** | 2169 | /** |
2162 | * 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 | */ | ||
2178 | static 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 | */ | ||
2211 | static 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 | |||
2239 | static 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 | ||
2163 | * @sb: the empty superblock | 2248 | * @sb: the empty superblock |
2164 | * @data: unused | 2249 | * @data: unused |
2165 | * @silent: unused | 2250 | * @silent: unused |
2166 | * | 2251 | * |
2167 | * Fill in the well known entries for /smack | 2252 | * Fill in the well known entries for the smack filesystem |
2168 | * | 2253 | * |
2169 | * Returns 0 on success, an error code on failure | 2254 | * Returns 0 on success, an error code on failure |
2170 | */ | 2255 | */ |
@@ -2209,6 +2294,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) | |||
2209 | S_IRUGO|S_IWUSR}, | 2294 | S_IRUGO|S_IWUSR}, |
2210 | [SMK_CHANGE_RULE] = { | 2295 | [SMK_CHANGE_RULE] = { |
2211 | "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}, | ||
2212 | /* last one */ | 2299 | /* last one */ |
2213 | {""} | 2300 | {""} |
2214 | }; | 2301 | }; |