diff options
author | James Morris <jmorris@namei.org> | 2006-06-09 03:33:33 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-06-18 00:30:05 -0400 |
commit | 4e5ab4cb85683cf77b507ba0c4d48871e1562305 (patch) | |
tree | aef7ba8b6050fcaccbaf0d05f8e5ba860a143eaf /security/selinux/selinuxfs.c | |
parent | 100468e9c05c10fb6872751c1af523b996d6afa9 (diff) |
[SECMARK]: Add new packet controls to SELinux
Add new per-packet access controls to SELinux, replacing the old
packet controls.
Packets are labeled with the iptables SECMARK and CONNSECMARK targets,
then security policy for the packets is enforced with these controls.
To allow for a smooth transition to the new controls, the old code is
still present, but not active by default. To restore previous
behavior, the old controls may be activated at runtime by writing a
'1' to /selinux/compat_net, and also via the kernel boot parameter
selinux_compat_net. Switching between the network control models
requires the security load_policy permission. The old controls will
probably eventually be removed and any continued use is discouraged.
With this patch, the new secmark controls for SElinux are disabled by
default, so existing behavior is entirely preserved, and the user is
not affected at all.
It also provides a config option to enable the secmark controls by
default (which can always be overridden at boot and runtime). It is
also noted in the kconfig help that the user will need updated
userspace if enabling secmark controls for SELinux and that they'll
probably need the SECMARK and CONNMARK targets, and conntrack protocol
helpers, although such decisions are beyond the scope of kernel
configuration.
Signed-off-by: James Morris <jmorris@namei.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'security/selinux/selinuxfs.c')
-rw-r--r-- | security/selinux/selinuxfs.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index a4efc966f065..2e73d3279f2d 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -38,6 +38,14 @@ | |||
38 | 38 | ||
39 | unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; | 39 | unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; |
40 | 40 | ||
41 | #ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT | ||
42 | #define SELINUX_COMPAT_NET_VALUE 0 | ||
43 | #else | ||
44 | #define SELINUX_COMPAT_NET_VALUE 1 | ||
45 | #endif | ||
46 | |||
47 | int selinux_compat_net = SELINUX_COMPAT_NET_VALUE; | ||
48 | |||
41 | static int __init checkreqprot_setup(char *str) | 49 | static int __init checkreqprot_setup(char *str) |
42 | { | 50 | { |
43 | selinux_checkreqprot = simple_strtoul(str,NULL,0) ? 1 : 0; | 51 | selinux_checkreqprot = simple_strtoul(str,NULL,0) ? 1 : 0; |
@@ -45,6 +53,13 @@ static int __init checkreqprot_setup(char *str) | |||
45 | } | 53 | } |
46 | __setup("checkreqprot=", checkreqprot_setup); | 54 | __setup("checkreqprot=", checkreqprot_setup); |
47 | 55 | ||
56 | static int __init selinux_compat_net_setup(char *str) | ||
57 | { | ||
58 | selinux_compat_net = simple_strtoul(str,NULL,0) ? 1 : 0; | ||
59 | return 1; | ||
60 | } | ||
61 | __setup("selinux_compat_net=", selinux_compat_net_setup); | ||
62 | |||
48 | 63 | ||
49 | static DEFINE_MUTEX(sel_mutex); | 64 | static DEFINE_MUTEX(sel_mutex); |
50 | 65 | ||
@@ -85,6 +100,7 @@ enum sel_inos { | |||
85 | SEL_AVC, /* AVC management directory */ | 100 | SEL_AVC, /* AVC management directory */ |
86 | SEL_MEMBER, /* compute polyinstantiation membership decision */ | 101 | SEL_MEMBER, /* compute polyinstantiation membership decision */ |
87 | SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */ | 102 | SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */ |
103 | SEL_COMPAT_NET, /* whether to use old compat network packet controls */ | ||
88 | }; | 104 | }; |
89 | 105 | ||
90 | #define TMPBUFLEN 12 | 106 | #define TMPBUFLEN 12 |
@@ -364,6 +380,55 @@ static struct file_operations sel_checkreqprot_ops = { | |||
364 | .write = sel_write_checkreqprot, | 380 | .write = sel_write_checkreqprot, |
365 | }; | 381 | }; |
366 | 382 | ||
383 | static ssize_t sel_read_compat_net(struct file *filp, char __user *buf, | ||
384 | size_t count, loff_t *ppos) | ||
385 | { | ||
386 | char tmpbuf[TMPBUFLEN]; | ||
387 | ssize_t length; | ||
388 | |||
389 | length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_compat_net); | ||
390 | return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); | ||
391 | } | ||
392 | |||
393 | static ssize_t sel_write_compat_net(struct file * file, const char __user * buf, | ||
394 | size_t count, loff_t *ppos) | ||
395 | { | ||
396 | char *page; | ||
397 | ssize_t length; | ||
398 | int new_value; | ||
399 | |||
400 | length = task_has_security(current, SECURITY__LOAD_POLICY); | ||
401 | if (length) | ||
402 | return length; | ||
403 | |||
404 | if (count >= PAGE_SIZE) | ||
405 | return -ENOMEM; | ||
406 | if (*ppos != 0) { | ||
407 | /* No partial writes. */ | ||
408 | return -EINVAL; | ||
409 | } | ||
410 | page = (char*)get_zeroed_page(GFP_KERNEL); | ||
411 | if (!page) | ||
412 | return -ENOMEM; | ||
413 | length = -EFAULT; | ||
414 | if (copy_from_user(page, buf, count)) | ||
415 | goto out; | ||
416 | |||
417 | length = -EINVAL; | ||
418 | if (sscanf(page, "%d", &new_value) != 1) | ||
419 | goto out; | ||
420 | |||
421 | selinux_compat_net = new_value ? 1 : 0; | ||
422 | length = count; | ||
423 | out: | ||
424 | free_page((unsigned long) page); | ||
425 | return length; | ||
426 | } | ||
427 | static struct file_operations sel_compat_net_ops = { | ||
428 | .read = sel_read_compat_net, | ||
429 | .write = sel_write_compat_net, | ||
430 | }; | ||
431 | |||
367 | /* | 432 | /* |
368 | * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c | 433 | * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c |
369 | */ | 434 | */ |
@@ -1219,6 +1284,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent) | |||
1219 | [SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR}, | 1284 | [SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR}, |
1220 | [SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO}, | 1285 | [SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO}, |
1221 | [SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR}, | 1286 | [SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR}, |
1287 | [SEL_COMPAT_NET] = {"compat_net", &sel_compat_net_ops, S_IRUGO|S_IWUSR}, | ||
1222 | /* last one */ {""} | 1288 | /* last one */ {""} |
1223 | }; | 1289 | }; |
1224 | ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files); | 1290 | ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files); |