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 | |
| 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')
| -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 | }; |
