diff options
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r-- | security/smack/smackfs.c | 76 |
1 files changed, 75 insertions, 1 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 3198cfe1dcc6..32b248820840 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
@@ -53,6 +53,7 @@ enum smk_inos { | |||
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 | SMK_SYSLOG = 20, /* change syslog label) */ |
56 | SMK_PTRACE = 21, /* set ptrace rule */ | ||
56 | }; | 57 | }; |
57 | 58 | ||
58 | /* | 59 | /* |
@@ -101,6 +102,15 @@ struct smack_known *smack_onlycap; | |||
101 | struct smack_known *smack_syslog_label; | 102 | struct smack_known *smack_syslog_label; |
102 | 103 | ||
103 | /* | 104 | /* |
105 | * Ptrace current rule | ||
106 | * SMACK_PTRACE_DEFAULT regular smack ptrace rules (/proc based) | ||
107 | * SMACK_PTRACE_EXACT labels must match, but can be overriden with | ||
108 | * CAP_SYS_PTRACE | ||
109 | * SMACK_PTRACE_DRACONIAN lables must match, CAP_SYS_PTRACE has no effect | ||
110 | */ | ||
111 | int smack_ptrace_rule = SMACK_PTRACE_DEFAULT; | ||
112 | |||
113 | /* | ||
104 | * Certain IP addresses may be designated as single label hosts. | 114 | * Certain IP addresses may be designated as single label hosts. |
105 | * Packets are sent there unlabeled, but only from tasks that | 115 | * Packets are sent there unlabeled, but only from tasks that |
106 | * can write to the specified label. | 116 | * can write to the specified label. |
@@ -1183,7 +1193,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, | |||
1183 | 1193 | ||
1184 | data[count] = '\0'; | 1194 | data[count] = '\0'; |
1185 | 1195 | ||
1186 | rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%d %s", | 1196 | rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%u %s", |
1187 | &host[0], &host[1], &host[2], &host[3], &m, smack); | 1197 | &host[0], &host[1], &host[2], &host[3], &m, smack); |
1188 | if (rc != 6) { | 1198 | if (rc != 6) { |
1189 | rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s", | 1199 | rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s", |
@@ -2244,6 +2254,68 @@ static const struct file_operations smk_syslog_ops = { | |||
2244 | 2254 | ||
2245 | 2255 | ||
2246 | /** | 2256 | /** |
2257 | * smk_read_ptrace - read() for /smack/ptrace | ||
2258 | * @filp: file pointer, not actually used | ||
2259 | * @buf: where to put the result | ||
2260 | * @count: maximum to send along | ||
2261 | * @ppos: where to start | ||
2262 | * | ||
2263 | * Returns number of bytes read or error code, as appropriate | ||
2264 | */ | ||
2265 | static ssize_t smk_read_ptrace(struct file *filp, char __user *buf, | ||
2266 | size_t count, loff_t *ppos) | ||
2267 | { | ||
2268 | char temp[32]; | ||
2269 | ssize_t rc; | ||
2270 | |||
2271 | if (*ppos != 0) | ||
2272 | return 0; | ||
2273 | |||
2274 | sprintf(temp, "%d\n", smack_ptrace_rule); | ||
2275 | rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); | ||
2276 | return rc; | ||
2277 | } | ||
2278 | |||
2279 | /** | ||
2280 | * smk_write_ptrace - write() for /smack/ptrace | ||
2281 | * @file: file pointer | ||
2282 | * @buf: data from user space | ||
2283 | * @count: bytes sent | ||
2284 | * @ppos: where to start - must be 0 | ||
2285 | */ | ||
2286 | static ssize_t smk_write_ptrace(struct file *file, const char __user *buf, | ||
2287 | size_t count, loff_t *ppos) | ||
2288 | { | ||
2289 | char temp[32]; | ||
2290 | int i; | ||
2291 | |||
2292 | if (!smack_privileged(CAP_MAC_ADMIN)) | ||
2293 | return -EPERM; | ||
2294 | |||
2295 | if (*ppos != 0 || count >= sizeof(temp) || count == 0) | ||
2296 | return -EINVAL; | ||
2297 | |||
2298 | if (copy_from_user(temp, buf, count) != 0) | ||
2299 | return -EFAULT; | ||
2300 | |||
2301 | temp[count] = '\0'; | ||
2302 | |||
2303 | if (sscanf(temp, "%d", &i) != 1) | ||
2304 | return -EINVAL; | ||
2305 | if (i < SMACK_PTRACE_DEFAULT || i > SMACK_PTRACE_MAX) | ||
2306 | return -EINVAL; | ||
2307 | smack_ptrace_rule = i; | ||
2308 | |||
2309 | return count; | ||
2310 | } | ||
2311 | |||
2312 | static const struct file_operations smk_ptrace_ops = { | ||
2313 | .write = smk_write_ptrace, | ||
2314 | .read = smk_read_ptrace, | ||
2315 | .llseek = default_llseek, | ||
2316 | }; | ||
2317 | |||
2318 | /** | ||
2247 | * smk_fill_super - fill the smackfs superblock | 2319 | * smk_fill_super - fill the smackfs superblock |
2248 | * @sb: the empty superblock | 2320 | * @sb: the empty superblock |
2249 | * @data: unused | 2321 | * @data: unused |
@@ -2296,6 +2368,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) | |||
2296 | "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR}, | 2368 | "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR}, |
2297 | [SMK_SYSLOG] = { | 2369 | [SMK_SYSLOG] = { |
2298 | "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR}, | 2370 | "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR}, |
2371 | [SMK_PTRACE] = { | ||
2372 | "ptrace", &smk_ptrace_ops, S_IRUGO|S_IWUSR}, | ||
2299 | /* last one */ | 2373 | /* last one */ |
2300 | {""} | 2374 | {""} |
2301 | }; | 2375 | }; |