diff options
Diffstat (limited to 'security')
25 files changed, 617 insertions, 270 deletions
diff --git a/security/Kconfig b/security/Kconfig index 5dfc206748cf..49b51f964897 100644 --- a/security/Kconfig +++ b/security/Kconfig | |||
@@ -113,10 +113,12 @@ config SECURITY_DEFAULT_MMAP_MIN_ADDR | |||
113 | from userspace allocation. Keeping a user from writing to low pages | 113 | from userspace allocation. Keeping a user from writing to low pages |
114 | can help reduce the impact of kernel NULL pointer bugs. | 114 | can help reduce the impact of kernel NULL pointer bugs. |
115 | 115 | ||
116 | For most users with lots of address space a value of 65536 is | 116 | For most ia64, ppc64 and x86 users with lots of address space |
117 | reasonable and should cause no problems. Programs which use vm86 | 117 | a value of 65536 is reasonable and should cause no problems. |
118 | functionality would either need additional permissions from either | 118 | On arm and other archs it should not be higher than 32768. |
119 | the LSM or the capabilities module or have this protection disabled. | 119 | Programs which use vm86 functionality would either need additional |
120 | permissions from either the LSM or the capabilities module or have | ||
121 | this protection disabled. | ||
120 | 122 | ||
121 | This value can be changed after boot using the | 123 | This value can be changed after boot using the |
122 | /proc/sys/vm/mmap_min_addr tunable. | 124 | /proc/sys/vm/mmap_min_addr tunable. |
diff --git a/security/commoncap.c b/security/commoncap.c index 06d5c9469ba3..852905789caf 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -267,7 +267,7 @@ static int get_file_caps(struct linux_binprm *bprm) | |||
267 | rc = cap_from_disk(&vcaps, bprm, rc); | 267 | rc = cap_from_disk(&vcaps, bprm, rc); |
268 | if (rc) | 268 | if (rc) |
269 | printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n", | 269 | printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n", |
270 | __FUNCTION__, rc, bprm->filename); | 270 | __func__, rc, bprm->filename); |
271 | 271 | ||
272 | out: | 272 | out: |
273 | dput(dentry); | 273 | dput(dentry); |
@@ -302,7 +302,7 @@ int cap_bprm_set_security (struct linux_binprm *bprm) | |||
302 | ret = get_file_caps(bprm); | 302 | ret = get_file_caps(bprm); |
303 | if (ret) | 303 | if (ret) |
304 | printk(KERN_NOTICE "%s: get_file_caps returned %d for %s\n", | 304 | printk(KERN_NOTICE "%s: get_file_caps returned %d for %s\n", |
305 | __FUNCTION__, ret, bprm->filename); | 305 | __func__, ret, bprm->filename); |
306 | 306 | ||
307 | /* To support inheritance of root-permissions and suid-root | 307 | /* To support inheritance of root-permissions and suid-root |
308 | * executables under compatibility mode, we raise all three | 308 | * executables under compatibility mode, we raise all three |
diff --git a/security/keys/internal.h b/security/keys/internal.h index d36d69393356..7d894ef70370 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
@@ -22,16 +22,16 @@ void no_printk(const char *fmt, ...) | |||
22 | 22 | ||
23 | #ifdef __KDEBUG | 23 | #ifdef __KDEBUG |
24 | #define kenter(FMT, ...) \ | 24 | #define kenter(FMT, ...) \ |
25 | printk(KERN_DEBUG "==> %s("FMT")\n", __FUNCTION__, ##__VA_ARGS__) | 25 | printk(KERN_DEBUG "==> %s("FMT")\n", __func__, ##__VA_ARGS__) |
26 | #define kleave(FMT, ...) \ | 26 | #define kleave(FMT, ...) \ |
27 | printk(KERN_DEBUG "<== %s()"FMT"\n", __FUNCTION__, ##__VA_ARGS__) | 27 | printk(KERN_DEBUG "<== %s()"FMT"\n", __func__, ##__VA_ARGS__) |
28 | #define kdebug(FMT, ...) \ | 28 | #define kdebug(FMT, ...) \ |
29 | printk(KERN_DEBUG "xxx" FMT"yyy\n", ##__VA_ARGS__) | 29 | printk(KERN_DEBUG "xxx" FMT"yyy\n", ##__VA_ARGS__) |
30 | #else | 30 | #else |
31 | #define kenter(FMT, ...) \ | 31 | #define kenter(FMT, ...) \ |
32 | no_printk(KERN_DEBUG "==> %s("FMT")\n", __FUNCTION__, ##__VA_ARGS__) | 32 | no_printk(KERN_DEBUG "==> %s("FMT")\n", __func__, ##__VA_ARGS__) |
33 | #define kleave(FMT, ...) \ | 33 | #define kleave(FMT, ...) \ |
34 | no_printk(KERN_DEBUG "<== %s()"FMT"\n", __FUNCTION__, ##__VA_ARGS__) | 34 | no_printk(KERN_DEBUG "<== %s()"FMT"\n", __func__, ##__VA_ARGS__) |
35 | #define kdebug(FMT, ...) \ | 35 | #define kdebug(FMT, ...) \ |
36 | no_printk(KERN_DEBUG FMT"\n", ##__VA_ARGS__) | 36 | no_printk(KERN_DEBUG FMT"\n", ##__VA_ARGS__) |
37 | #endif | 37 | #endif |
diff --git a/security/root_plug.c b/security/root_plug.c index 870f13095bb6..6112d1404c81 100644 --- a/security/root_plug.c +++ b/security/root_plug.c | |||
@@ -49,7 +49,7 @@ module_param(debug, bool, 0600); | |||
49 | do { \ | 49 | do { \ |
50 | if (debug) \ | 50 | if (debug) \ |
51 | printk(KERN_DEBUG "%s: %s: " fmt , \ | 51 | printk(KERN_DEBUG "%s: %s: " fmt , \ |
52 | MY_NAME , __FUNCTION__ , \ | 52 | MY_NAME , __func__ , \ |
53 | ## arg); \ | 53 | ## arg); \ |
54 | } while (0) | 54 | } while (0) |
55 | 55 | ||
diff --git a/security/security.c b/security/security.c index c9ff7d18c2f4..54affd0ce6ad 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -57,7 +57,7 @@ int __init security_init(void) | |||
57 | 57 | ||
58 | if (verify(&dummy_security_ops)) { | 58 | if (verify(&dummy_security_ops)) { |
59 | printk(KERN_ERR "%s could not verify " | 59 | printk(KERN_ERR "%s could not verify " |
60 | "dummy_security_ops structure.\n", __FUNCTION__); | 60 | "dummy_security_ops structure.\n", __func__); |
61 | return -EIO; | 61 | return -EIO; |
62 | } | 62 | } |
63 | 63 | ||
@@ -82,7 +82,7 @@ int register_security(struct security_operations *ops) | |||
82 | { | 82 | { |
83 | if (verify(ops)) { | 83 | if (verify(ops)) { |
84 | printk(KERN_DEBUG "%s could not verify " | 84 | printk(KERN_DEBUG "%s could not verify " |
85 | "security_operations structure.\n", __FUNCTION__); | 85 | "security_operations structure.\n", __func__); |
86 | return -EINVAL; | 86 | return -EINVAL; |
87 | } | 87 | } |
88 | 88 | ||
@@ -110,13 +110,13 @@ int mod_reg_security(const char *name, struct security_operations *ops) | |||
110 | { | 110 | { |
111 | if (verify(ops)) { | 111 | if (verify(ops)) { |
112 | printk(KERN_INFO "%s could not verify " | 112 | printk(KERN_INFO "%s could not verify " |
113 | "security operations.\n", __FUNCTION__); | 113 | "security operations.\n", __func__); |
114 | return -EINVAL; | 114 | return -EINVAL; |
115 | } | 115 | } |
116 | 116 | ||
117 | if (ops == security_ops) { | 117 | if (ops == security_ops) { |
118 | printk(KERN_INFO "%s security operations " | 118 | printk(KERN_INFO "%s security operations " |
119 | "already registered.\n", __FUNCTION__); | 119 | "already registered.\n", __func__); |
120 | return -EINVAL; | 120 | return -EINVAL; |
121 | } | 121 | } |
122 | 122 | ||
diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig index 2b517d618672..a436d1cfa88b 100644 --- a/security/selinux/Kconfig +++ b/security/selinux/Kconfig | |||
@@ -145,7 +145,7 @@ config SECURITY_SELINUX_POLICYDB_VERSION_MAX | |||
145 | config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE | 145 | config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE |
146 | int "NSA SELinux maximum supported policy format version value" | 146 | int "NSA SELinux maximum supported policy format version value" |
147 | depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX | 147 | depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX |
148 | range 15 22 | 148 | range 15 23 |
149 | default 19 | 149 | default 19 |
150 | help | 150 | help |
151 | This option sets the value for the maximum policy format version | 151 | This option sets the value for the maximum policy format version |
diff --git a/security/selinux/Makefile b/security/selinux/Makefile index 00afd85f1edb..d47fc5e545e0 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile | |||
@@ -11,6 +11,7 @@ selinux-y := avc.o \ | |||
11 | nlmsgtab.o \ | 11 | nlmsgtab.o \ |
12 | netif.o \ | 12 | netif.o \ |
13 | netnode.o \ | 13 | netnode.o \ |
14 | netport.o \ | ||
14 | exports.o | 15 | exports.o |
15 | 16 | ||
16 | selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o | 17 | selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o |
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 187964e88af1..a4fc6e6d038a 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
@@ -871,6 +871,8 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, | |||
871 | int rc = 0; | 871 | int rc = 0; |
872 | u32 denied; | 872 | u32 denied; |
873 | 873 | ||
874 | BUG_ON(!requested); | ||
875 | |||
874 | rcu_read_lock(); | 876 | rcu_read_lock(); |
875 | 877 | ||
876 | node = avc_lookup(ssid, tsid, tclass, requested); | 878 | node = avc_lookup(ssid, tsid, tclass, requested); |
@@ -890,13 +892,14 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, | |||
890 | 892 | ||
891 | denied = requested & ~(p_ae->avd.allowed); | 893 | denied = requested & ~(p_ae->avd.allowed); |
892 | 894 | ||
893 | if (!requested || denied) { | 895 | if (denied) { |
894 | if (selinux_enforcing || (flags & AVC_STRICT)) | 896 | if (flags & AVC_STRICT) |
895 | rc = -EACCES; | 897 | rc = -EACCES; |
898 | else if (!selinux_enforcing || security_permissive_sid(ssid)) | ||
899 | avc_update_node(AVC_CALLBACK_GRANT, requested, ssid, | ||
900 | tsid, tclass); | ||
896 | else | 901 | else |
897 | if (node) | 902 | rc = -EACCES; |
898 | avc_update_node(AVC_CALLBACK_GRANT,requested, | ||
899 | ssid,tsid,tclass); | ||
900 | } | 903 | } |
901 | 904 | ||
902 | rcu_read_unlock(); | 905 | rcu_read_unlock(); |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d39b59cf8a08..34f2d46c7984 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -80,6 +80,7 @@ | |||
80 | #include "objsec.h" | 80 | #include "objsec.h" |
81 | #include "netif.h" | 81 | #include "netif.h" |
82 | #include "netnode.h" | 82 | #include "netnode.h" |
83 | #include "netport.h" | ||
83 | #include "xfrm.h" | 84 | #include "xfrm.h" |
84 | #include "netlabel.h" | 85 | #include "netlabel.h" |
85 | 86 | ||
@@ -161,8 +162,7 @@ static int task_alloc_security(struct task_struct *task) | |||
161 | if (!tsec) | 162 | if (!tsec) |
162 | return -ENOMEM; | 163 | return -ENOMEM; |
163 | 164 | ||
164 | tsec->task = task; | 165 | tsec->osid = tsec->sid = SECINITSID_UNLABELED; |
165 | tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED; | ||
166 | task->security = tsec; | 166 | task->security = tsec; |
167 | 167 | ||
168 | return 0; | 168 | return 0; |
@@ -218,7 +218,6 @@ static int file_alloc_security(struct file *file) | |||
218 | if (!fsec) | 218 | if (!fsec) |
219 | return -ENOMEM; | 219 | return -ENOMEM; |
220 | 220 | ||
221 | fsec->file = file; | ||
222 | fsec->sid = tsec->sid; | 221 | fsec->sid = tsec->sid; |
223 | fsec->fown_sid = tsec->sid; | 222 | fsec->fown_sid = tsec->sid; |
224 | file->f_security = fsec; | 223 | file->f_security = fsec; |
@@ -275,12 +274,11 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) | |||
275 | if (!ssec) | 274 | if (!ssec) |
276 | return -ENOMEM; | 275 | return -ENOMEM; |
277 | 276 | ||
278 | ssec->sk = sk; | ||
279 | ssec->peer_sid = SECINITSID_UNLABELED; | 277 | ssec->peer_sid = SECINITSID_UNLABELED; |
280 | ssec->sid = SECINITSID_UNLABELED; | 278 | ssec->sid = SECINITSID_UNLABELED; |
281 | sk->sk_security = ssec; | 279 | sk->sk_security = ssec; |
282 | 280 | ||
283 | selinux_netlbl_sk_security_init(ssec, family); | 281 | selinux_netlbl_sk_security_reset(ssec, family); |
284 | 282 | ||
285 | return 0; | 283 | return 0; |
286 | } | 284 | } |
@@ -324,10 +322,10 @@ enum { | |||
324 | }; | 322 | }; |
325 | 323 | ||
326 | static match_table_t tokens = { | 324 | static match_table_t tokens = { |
327 | {Opt_context, "context=%s"}, | 325 | {Opt_context, CONTEXT_STR "%s"}, |
328 | {Opt_fscontext, "fscontext=%s"}, | 326 | {Opt_fscontext, FSCONTEXT_STR "%s"}, |
329 | {Opt_defcontext, "defcontext=%s"}, | 327 | {Opt_defcontext, DEFCONTEXT_STR "%s"}, |
330 | {Opt_rootcontext, "rootcontext=%s"}, | 328 | {Opt_rootcontext, ROOTCONTEXT_STR "%s"}, |
331 | {Opt_error, NULL}, | 329 | {Opt_error, NULL}, |
332 | }; | 330 | }; |
333 | 331 | ||
@@ -671,7 +669,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
671 | rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid); | 669 | rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid); |
672 | if (rc) { | 670 | if (rc) { |
673 | printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", | 671 | printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", |
674 | __FUNCTION__, sb->s_type->name, rc); | 672 | __func__, sb->s_type->name, rc); |
675 | goto out; | 673 | goto out; |
676 | } | 674 | } |
677 | 675 | ||
@@ -1137,7 +1135,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1137 | } | 1135 | } |
1138 | if (!dentry) { | 1136 | if (!dentry) { |
1139 | printk(KERN_WARNING "%s: no dentry for dev=%s " | 1137 | printk(KERN_WARNING "%s: no dentry for dev=%s " |
1140 | "ino=%ld\n", __FUNCTION__, inode->i_sb->s_id, | 1138 | "ino=%ld\n", __func__, inode->i_sb->s_id, |
1141 | inode->i_ino); | 1139 | inode->i_ino); |
1142 | goto out_unlock; | 1140 | goto out_unlock; |
1143 | } | 1141 | } |
@@ -1175,7 +1173,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1175 | if (rc < 0) { | 1173 | if (rc < 0) { |
1176 | if (rc != -ENODATA) { | 1174 | if (rc != -ENODATA) { |
1177 | printk(KERN_WARNING "%s: getxattr returned " | 1175 | printk(KERN_WARNING "%s: getxattr returned " |
1178 | "%d for dev=%s ino=%ld\n", __FUNCTION__, | 1176 | "%d for dev=%s ino=%ld\n", __func__, |
1179 | -rc, inode->i_sb->s_id, inode->i_ino); | 1177 | -rc, inode->i_sb->s_id, inode->i_ino); |
1180 | kfree(context); | 1178 | kfree(context); |
1181 | goto out_unlock; | 1179 | goto out_unlock; |
@@ -1190,7 +1188,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1190 | if (rc) { | 1188 | if (rc) { |
1191 | printk(KERN_WARNING "%s: context_to_sid(%s) " | 1189 | printk(KERN_WARNING "%s: context_to_sid(%s) " |
1192 | "returned %d for dev=%s ino=%ld\n", | 1190 | "returned %d for dev=%s ino=%ld\n", |
1193 | __FUNCTION__, context, -rc, | 1191 | __func__, context, -rc, |
1194 | inode->i_sb->s_id, inode->i_ino); | 1192 | inode->i_sb->s_id, inode->i_ino); |
1195 | kfree(context); | 1193 | kfree(context); |
1196 | /* Leave with the unlabeled SID */ | 1194 | /* Leave with the unlabeled SID */ |
@@ -1618,6 +1616,35 @@ static inline u32 file_mask_to_av(int mode, int mask) | |||
1618 | return av; | 1616 | return av; |
1619 | } | 1617 | } |
1620 | 1618 | ||
1619 | /* | ||
1620 | * Convert a file mask to an access vector and include the correct open | ||
1621 | * open permission. | ||
1622 | */ | ||
1623 | static inline u32 open_file_mask_to_av(int mode, int mask) | ||
1624 | { | ||
1625 | u32 av = file_mask_to_av(mode, mask); | ||
1626 | |||
1627 | if (selinux_policycap_openperm) { | ||
1628 | /* | ||
1629 | * lnk files and socks do not really have an 'open' | ||
1630 | */ | ||
1631 | if (S_ISREG(mode)) | ||
1632 | av |= FILE__OPEN; | ||
1633 | else if (S_ISCHR(mode)) | ||
1634 | av |= CHR_FILE__OPEN; | ||
1635 | else if (S_ISBLK(mode)) | ||
1636 | av |= BLK_FILE__OPEN; | ||
1637 | else if (S_ISFIFO(mode)) | ||
1638 | av |= FIFO_FILE__OPEN; | ||
1639 | else if (S_ISDIR(mode)) | ||
1640 | av |= DIR__OPEN; | ||
1641 | else | ||
1642 | printk(KERN_ERR "SELinux: WARNING: inside open_file_to_av " | ||
1643 | "with unknown mode:%x\n", mode); | ||
1644 | } | ||
1645 | return av; | ||
1646 | } | ||
1647 | |||
1621 | /* Convert a Linux file to an access vector. */ | 1648 | /* Convert a Linux file to an access vector. */ |
1622 | static inline u32 file_to_av(struct file *file) | 1649 | static inline u32 file_to_av(struct file *file) |
1623 | { | 1650 | { |
@@ -1645,19 +1672,13 @@ static inline u32 file_to_av(struct file *file) | |||
1645 | 1672 | ||
1646 | static int selinux_ptrace(struct task_struct *parent, struct task_struct *child) | 1673 | static int selinux_ptrace(struct task_struct *parent, struct task_struct *child) |
1647 | { | 1674 | { |
1648 | struct task_security_struct *psec = parent->security; | ||
1649 | struct task_security_struct *csec = child->security; | ||
1650 | int rc; | 1675 | int rc; |
1651 | 1676 | ||
1652 | rc = secondary_ops->ptrace(parent,child); | 1677 | rc = secondary_ops->ptrace(parent,child); |
1653 | if (rc) | 1678 | if (rc) |
1654 | return rc; | 1679 | return rc; |
1655 | 1680 | ||
1656 | rc = task_has_perm(parent, child, PROCESS__PTRACE); | 1681 | return task_has_perm(parent, child, PROCESS__PTRACE); |
1657 | /* Save the SID of the tracing process for later use in apply_creds. */ | ||
1658 | if (!(child->ptrace & PT_PTRACED) && !rc) | ||
1659 | csec->ptrace_sid = psec->sid; | ||
1660 | return rc; | ||
1661 | } | 1682 | } |
1662 | 1683 | ||
1663 | static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, | 1684 | static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, |
@@ -1879,6 +1900,22 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
1879 | return __vm_enough_memory(mm, pages, cap_sys_admin); | 1900 | return __vm_enough_memory(mm, pages, cap_sys_admin); |
1880 | } | 1901 | } |
1881 | 1902 | ||
1903 | /** | ||
1904 | * task_tracer_task - return the task that is tracing the given task | ||
1905 | * @task: task to consider | ||
1906 | * | ||
1907 | * Returns NULL if noone is tracing @task, or the &struct task_struct | ||
1908 | * pointer to its tracer. | ||
1909 | * | ||
1910 | * Must be called under rcu_read_lock(). | ||
1911 | */ | ||
1912 | static struct task_struct *task_tracer_task(struct task_struct *task) | ||
1913 | { | ||
1914 | if (task->ptrace & PT_PTRACED) | ||
1915 | return rcu_dereference(task->parent); | ||
1916 | return NULL; | ||
1917 | } | ||
1918 | |||
1882 | /* binprm security operations */ | 1919 | /* binprm security operations */ |
1883 | 1920 | ||
1884 | static int selinux_bprm_alloc_security(struct linux_binprm *bprm) | 1921 | static int selinux_bprm_alloc_security(struct linux_binprm *bprm) |
@@ -1889,7 +1926,6 @@ static int selinux_bprm_alloc_security(struct linux_binprm *bprm) | |||
1889 | if (!bsec) | 1926 | if (!bsec) |
1890 | return -ENOMEM; | 1927 | return -ENOMEM; |
1891 | 1928 | ||
1892 | bsec->bprm = bprm; | ||
1893 | bsec->sid = SECINITSID_UNLABELED; | 1929 | bsec->sid = SECINITSID_UNLABELED; |
1894 | bsec->set = 0; | 1930 | bsec->set = 0; |
1895 | 1931 | ||
@@ -2126,12 +2162,25 @@ static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) | |||
2126 | /* Check for ptracing, and update the task SID if ok. | 2162 | /* Check for ptracing, and update the task SID if ok. |
2127 | Otherwise, leave SID unchanged and kill. */ | 2163 | Otherwise, leave SID unchanged and kill. */ |
2128 | if (unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { | 2164 | if (unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { |
2129 | rc = avc_has_perm(tsec->ptrace_sid, sid, | 2165 | struct task_struct *tracer; |
2130 | SECCLASS_PROCESS, PROCESS__PTRACE, | 2166 | struct task_security_struct *sec; |
2131 | NULL); | 2167 | u32 ptsid = 0; |
2132 | if (rc) { | 2168 | |
2133 | bsec->unsafe = 1; | 2169 | rcu_read_lock(); |
2134 | return; | 2170 | tracer = task_tracer_task(current); |
2171 | if (likely(tracer != NULL)) { | ||
2172 | sec = tracer->security; | ||
2173 | ptsid = sec->sid; | ||
2174 | } | ||
2175 | rcu_read_unlock(); | ||
2176 | |||
2177 | if (ptsid != 0) { | ||
2178 | rc = avc_has_perm(ptsid, sid, SECCLASS_PROCESS, | ||
2179 | PROCESS__PTRACE, NULL); | ||
2180 | if (rc) { | ||
2181 | bsec->unsafe = 1; | ||
2182 | return; | ||
2183 | } | ||
2135 | } | 2184 | } |
2136 | } | 2185 | } |
2137 | tsec->sid = sid; | 2186 | tsec->sid = sid; |
@@ -2239,10 +2288,10 @@ static inline int match_prefix(char *prefix, int plen, char *option, int olen) | |||
2239 | 2288 | ||
2240 | static inline int selinux_option(char *option, int len) | 2289 | static inline int selinux_option(char *option, int len) |
2241 | { | 2290 | { |
2242 | return (match_prefix("context=", sizeof("context=")-1, option, len) || | 2291 | return (match_prefix(CONTEXT_STR, sizeof(CONTEXT_STR)-1, option, len) || |
2243 | match_prefix("fscontext=", sizeof("fscontext=")-1, option, len) || | 2292 | match_prefix(FSCONTEXT_STR, sizeof(FSCONTEXT_STR)-1, option, len) || |
2244 | match_prefix("defcontext=", sizeof("defcontext=")-1, option, len) || | 2293 | match_prefix(DEFCONTEXT_STR, sizeof(DEFCONTEXT_STR)-1, option, len) || |
2245 | match_prefix("rootcontext=", sizeof("rootcontext=")-1, option, len)); | 2294 | match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len)); |
2246 | } | 2295 | } |
2247 | 2296 | ||
2248 | static inline void take_option(char **to, char *from, int *first, int len) | 2297 | static inline void take_option(char **to, char *from, int *first, int len) |
@@ -2412,7 +2461,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
2412 | printk(KERN_WARNING "%s: " | 2461 | printk(KERN_WARNING "%s: " |
2413 | "security_transition_sid failed, rc=%d (dev=%s " | 2462 | "security_transition_sid failed, rc=%d (dev=%s " |
2414 | "ino=%ld)\n", | 2463 | "ino=%ld)\n", |
2415 | __FUNCTION__, | 2464 | __func__, |
2416 | -rc, inode->i_sb->s_id, inode->i_ino); | 2465 | -rc, inode->i_sb->s_id, inode->i_ino); |
2417 | return rc; | 2466 | return rc; |
2418 | } | 2467 | } |
@@ -2536,7 +2585,7 @@ static int selinux_inode_permission(struct inode *inode, int mask, | |||
2536 | } | 2585 | } |
2537 | 2586 | ||
2538 | return inode_has_perm(current, inode, | 2587 | return inode_has_perm(current, inode, |
2539 | file_mask_to_av(inode->i_mode, mask), NULL); | 2588 | open_file_mask_to_av(inode->i_mode, mask), NULL); |
2540 | } | 2589 | } |
2541 | 2590 | ||
2542 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | 2591 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) |
@@ -2646,7 +2695,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, char *name, | |||
2646 | rc = security_context_to_sid(value, size, &newsid); | 2695 | rc = security_context_to_sid(value, size, &newsid); |
2647 | if (rc) { | 2696 | if (rc) { |
2648 | printk(KERN_WARNING "%s: unable to obtain SID for context " | 2697 | printk(KERN_WARNING "%s: unable to obtain SID for context " |
2649 | "%s, rc=%d\n", __FUNCTION__, (char*)value, -rc); | 2698 | "%s, rc=%d\n", __func__, (char *)value, -rc); |
2650 | return; | 2699 | return; |
2651 | } | 2700 | } |
2652 | 2701 | ||
@@ -3087,11 +3136,6 @@ static int selinux_task_alloc_security(struct task_struct *tsk) | |||
3087 | tsec2->keycreate_sid = tsec1->keycreate_sid; | 3136 | tsec2->keycreate_sid = tsec1->keycreate_sid; |
3088 | tsec2->sockcreate_sid = tsec1->sockcreate_sid; | 3137 | tsec2->sockcreate_sid = tsec1->sockcreate_sid; |
3089 | 3138 | ||
3090 | /* Retain ptracer SID across fork, if any. | ||
3091 | This will be reset by the ptrace hook upon any | ||
3092 | subsequent ptrace_attach operations. */ | ||
3093 | tsec2->ptrace_sid = tsec1->ptrace_sid; | ||
3094 | |||
3095 | return 0; | 3139 | return 0; |
3096 | } | 3140 | } |
3097 | 3141 | ||
@@ -3627,10 +3671,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3627 | inet_get_local_port_range(&low, &high); | 3671 | inet_get_local_port_range(&low, &high); |
3628 | 3672 | ||
3629 | if (snum < max(PROT_SOCK, low) || snum > high) { | 3673 | if (snum < max(PROT_SOCK, low) || snum > high) { |
3630 | err = security_port_sid(sk->sk_family, | 3674 | err = sel_netport_sid(sk->sk_protocol, |
3631 | sk->sk_type, | 3675 | snum, &sid); |
3632 | sk->sk_protocol, snum, | ||
3633 | &sid); | ||
3634 | if (err) | 3676 | if (err) |
3635 | goto out; | 3677 | goto out; |
3636 | AVC_AUDIT_DATA_INIT(&ad,NET); | 3678 | AVC_AUDIT_DATA_INIT(&ad,NET); |
@@ -3718,8 +3760,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
3718 | snum = ntohs(addr6->sin6_port); | 3760 | snum = ntohs(addr6->sin6_port); |
3719 | } | 3761 | } |
3720 | 3762 | ||
3721 | err = security_port_sid(sk->sk_family, sk->sk_type, | 3763 | err = sel_netport_sid(sk->sk_protocol, snum, &sid); |
3722 | sk->sk_protocol, snum, &sid); | ||
3723 | if (err) | 3764 | if (err) |
3724 | goto out; | 3765 | goto out; |
3725 | 3766 | ||
@@ -3950,9 +3991,8 @@ static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk, | |||
3950 | 3991 | ||
3951 | if (!recv_perm) | 3992 | if (!recv_perm) |
3952 | return 0; | 3993 | return 0; |
3953 | err = security_port_sid(sk->sk_family, sk->sk_type, | 3994 | err = sel_netport_sid(sk->sk_protocol, |
3954 | sk->sk_protocol, ntohs(ad->u.net.sport), | 3995 | ntohs(ad->u.net.sport), &port_sid); |
3955 | &port_sid); | ||
3956 | if (unlikely(err)) { | 3996 | if (unlikely(err)) { |
3957 | printk(KERN_WARNING | 3997 | printk(KERN_WARNING |
3958 | "SELinux: failure in" | 3998 | "SELinux: failure in" |
@@ -4139,7 +4179,7 @@ static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) | |||
4139 | newssec->peer_sid = ssec->peer_sid; | 4179 | newssec->peer_sid = ssec->peer_sid; |
4140 | newssec->sclass = ssec->sclass; | 4180 | newssec->sclass = ssec->sclass; |
4141 | 4181 | ||
4142 | selinux_netlbl_sk_security_clone(ssec, newssec); | 4182 | selinux_netlbl_sk_security_reset(newssec, newsk->sk_family); |
4143 | } | 4183 | } |
4144 | 4184 | ||
4145 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) | 4185 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) |
@@ -4373,9 +4413,8 @@ static int selinux_ip_postroute_iptables_compat(struct sock *sk, | |||
4373 | if (send_perm != 0) | 4413 | if (send_perm != 0) |
4374 | return 0; | 4414 | return 0; |
4375 | 4415 | ||
4376 | err = security_port_sid(sk->sk_family, sk->sk_type, | 4416 | err = sel_netport_sid(sk->sk_protocol, |
4377 | sk->sk_protocol, ntohs(ad->u.net.dport), | 4417 | ntohs(ad->u.net.dport), &port_sid); |
4378 | &port_sid); | ||
4379 | if (unlikely(err)) { | 4418 | if (unlikely(err)) { |
4380 | printk(KERN_WARNING | 4419 | printk(KERN_WARNING |
4381 | "SELinux: failure in" | 4420 | "SELinux: failure in" |
@@ -4561,7 +4600,6 @@ static int ipc_alloc_security(struct task_struct *task, | |||
4561 | return -ENOMEM; | 4600 | return -ENOMEM; |
4562 | 4601 | ||
4563 | isec->sclass = sclass; | 4602 | isec->sclass = sclass; |
4564 | isec->ipc_perm = perm; | ||
4565 | isec->sid = tsec->sid; | 4603 | isec->sid = tsec->sid; |
4566 | perm->security = isec; | 4604 | perm->security = isec; |
4567 | 4605 | ||
@@ -4583,7 +4621,6 @@ static int msg_msg_alloc_security(struct msg_msg *msg) | |||
4583 | if (!msec) | 4621 | if (!msec) |
4584 | return -ENOMEM; | 4622 | return -ENOMEM; |
4585 | 4623 | ||
4586 | msec->msg = msg; | ||
4587 | msec->sid = SECINITSID_UNLABELED; | 4624 | msec->sid = SECINITSID_UNLABELED; |
4588 | msg->security = msec; | 4625 | msg->security = msec; |
4589 | 4626 | ||
@@ -4994,14 +5031,14 @@ static int selinux_register_security (const char *name, struct security_operatio | |||
4994 | { | 5031 | { |
4995 | if (secondary_ops != original_ops) { | 5032 | if (secondary_ops != original_ops) { |
4996 | printk(KERN_ERR "%s: There is already a secondary security " | 5033 | printk(KERN_ERR "%s: There is already a secondary security " |
4997 | "module registered.\n", __FUNCTION__); | 5034 | "module registered.\n", __func__); |
4998 | return -EINVAL; | 5035 | return -EINVAL; |
4999 | } | 5036 | } |
5000 | 5037 | ||
5001 | secondary_ops = ops; | 5038 | secondary_ops = ops; |
5002 | 5039 | ||
5003 | printk(KERN_INFO "%s: Registering secondary module %s\n", | 5040 | printk(KERN_INFO "%s: Registering secondary module %s\n", |
5004 | __FUNCTION__, | 5041 | __func__, |
5005 | name); | 5042 | name); |
5006 | 5043 | ||
5007 | return 0; | 5044 | return 0; |
@@ -5057,6 +5094,7 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5057 | char *name, void *value, size_t size) | 5094 | char *name, void *value, size_t size) |
5058 | { | 5095 | { |
5059 | struct task_security_struct *tsec; | 5096 | struct task_security_struct *tsec; |
5097 | struct task_struct *tracer; | ||
5060 | u32 sid = 0; | 5098 | u32 sid = 0; |
5061 | int error; | 5099 | int error; |
5062 | char *str = value; | 5100 | char *str = value; |
@@ -5145,18 +5183,24 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5145 | /* Check for ptracing, and update the task SID if ok. | 5183 | /* Check for ptracing, and update the task SID if ok. |
5146 | Otherwise, leave SID unchanged and fail. */ | 5184 | Otherwise, leave SID unchanged and fail. */ |
5147 | task_lock(p); | 5185 | task_lock(p); |
5148 | if (p->ptrace & PT_PTRACED) { | 5186 | rcu_read_lock(); |
5149 | error = avc_has_perm_noaudit(tsec->ptrace_sid, sid, | 5187 | tracer = task_tracer_task(p); |
5188 | if (tracer != NULL) { | ||
5189 | struct task_security_struct *ptsec = tracer->security; | ||
5190 | u32 ptsid = ptsec->sid; | ||
5191 | rcu_read_unlock(); | ||
5192 | error = avc_has_perm_noaudit(ptsid, sid, | ||
5150 | SECCLASS_PROCESS, | 5193 | SECCLASS_PROCESS, |
5151 | PROCESS__PTRACE, 0, &avd); | 5194 | PROCESS__PTRACE, 0, &avd); |
5152 | if (!error) | 5195 | if (!error) |
5153 | tsec->sid = sid; | 5196 | tsec->sid = sid; |
5154 | task_unlock(p); | 5197 | task_unlock(p); |
5155 | avc_audit(tsec->ptrace_sid, sid, SECCLASS_PROCESS, | 5198 | avc_audit(ptsid, sid, SECCLASS_PROCESS, |
5156 | PROCESS__PTRACE, &avd, error, NULL); | 5199 | PROCESS__PTRACE, &avd, error, NULL); |
5157 | if (error) | 5200 | if (error) |
5158 | return error; | 5201 | return error; |
5159 | } else { | 5202 | } else { |
5203 | rcu_read_unlock(); | ||
5160 | tsec->sid = sid; | 5204 | tsec->sid = sid; |
5161 | task_unlock(p); | 5205 | task_unlock(p); |
5162 | } | 5206 | } |
@@ -5194,7 +5238,6 @@ static int selinux_key_alloc(struct key *k, struct task_struct *tsk, | |||
5194 | if (!ksec) | 5238 | if (!ksec) |
5195 | return -ENOMEM; | 5239 | return -ENOMEM; |
5196 | 5240 | ||
5197 | ksec->obj = k; | ||
5198 | if (tsec->keycreate_sid) | 5241 | if (tsec->keycreate_sid) |
5199 | ksec->sid = tsec->keycreate_sid; | 5242 | ksec->sid = tsec->keycreate_sid; |
5200 | else | 5243 | else |
@@ -5631,5 +5674,3 @@ int selinux_disable(void) | |||
5631 | return 0; | 5674 | return 0; |
5632 | } | 5675 | } |
5633 | #endif | 5676 | #endif |
5634 | |||
5635 | |||
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h index d5696690d3a2..1223b4ff9bee 100644 --- a/security/selinux/include/av_perm_to_string.h +++ b/security/selinux/include/av_perm_to_string.h | |||
@@ -14,12 +14,17 @@ | |||
14 | S_(SECCLASS_DIR, DIR__REPARENT, "reparent") | 14 | S_(SECCLASS_DIR, DIR__REPARENT, "reparent") |
15 | S_(SECCLASS_DIR, DIR__SEARCH, "search") | 15 | S_(SECCLASS_DIR, DIR__SEARCH, "search") |
16 | S_(SECCLASS_DIR, DIR__RMDIR, "rmdir") | 16 | S_(SECCLASS_DIR, DIR__RMDIR, "rmdir") |
17 | S_(SECCLASS_DIR, DIR__OPEN, "open") | ||
17 | S_(SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, "execute_no_trans") | 18 | S_(SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, "execute_no_trans") |
18 | S_(SECCLASS_FILE, FILE__ENTRYPOINT, "entrypoint") | 19 | S_(SECCLASS_FILE, FILE__ENTRYPOINT, "entrypoint") |
19 | S_(SECCLASS_FILE, FILE__EXECMOD, "execmod") | 20 | S_(SECCLASS_FILE, FILE__EXECMOD, "execmod") |
21 | S_(SECCLASS_FILE, FILE__OPEN, "open") | ||
20 | S_(SECCLASS_CHR_FILE, CHR_FILE__EXECUTE_NO_TRANS, "execute_no_trans") | 22 | S_(SECCLASS_CHR_FILE, CHR_FILE__EXECUTE_NO_TRANS, "execute_no_trans") |
21 | S_(SECCLASS_CHR_FILE, CHR_FILE__ENTRYPOINT, "entrypoint") | 23 | S_(SECCLASS_CHR_FILE, CHR_FILE__ENTRYPOINT, "entrypoint") |
22 | S_(SECCLASS_CHR_FILE, CHR_FILE__EXECMOD, "execmod") | 24 | S_(SECCLASS_CHR_FILE, CHR_FILE__EXECMOD, "execmod") |
25 | S_(SECCLASS_CHR_FILE, CHR_FILE__OPEN, "open") | ||
26 | S_(SECCLASS_BLK_FILE, BLK_FILE__OPEN, "open") | ||
27 | S_(SECCLASS_FIFO_FILE, FIFO_FILE__OPEN, "open") | ||
23 | S_(SECCLASS_FD, FD__USE, "use") | 28 | S_(SECCLASS_FD, FD__USE, "use") |
24 | S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto") | 29 | S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto") |
25 | S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NEWCONN, "newconn") | 30 | S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NEWCONN, "newconn") |
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index 75b41311ab86..c4c51165c505 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h | |||
@@ -79,6 +79,7 @@ | |||
79 | #define DIR__REPARENT 0x00080000UL | 79 | #define DIR__REPARENT 0x00080000UL |
80 | #define DIR__SEARCH 0x00100000UL | 80 | #define DIR__SEARCH 0x00100000UL |
81 | #define DIR__RMDIR 0x00200000UL | 81 | #define DIR__RMDIR 0x00200000UL |
82 | #define DIR__OPEN 0x00400000UL | ||
82 | #define FILE__IOCTL 0x00000001UL | 83 | #define FILE__IOCTL 0x00000001UL |
83 | #define FILE__READ 0x00000002UL | 84 | #define FILE__READ 0x00000002UL |
84 | #define FILE__WRITE 0x00000004UL | 85 | #define FILE__WRITE 0x00000004UL |
@@ -99,6 +100,7 @@ | |||
99 | #define FILE__EXECUTE_NO_TRANS 0x00020000UL | 100 | #define FILE__EXECUTE_NO_TRANS 0x00020000UL |
100 | #define FILE__ENTRYPOINT 0x00040000UL | 101 | #define FILE__ENTRYPOINT 0x00040000UL |
101 | #define FILE__EXECMOD 0x00080000UL | 102 | #define FILE__EXECMOD 0x00080000UL |
103 | #define FILE__OPEN 0x00100000UL | ||
102 | #define LNK_FILE__IOCTL 0x00000001UL | 104 | #define LNK_FILE__IOCTL 0x00000001UL |
103 | #define LNK_FILE__READ 0x00000002UL | 105 | #define LNK_FILE__READ 0x00000002UL |
104 | #define LNK_FILE__WRITE 0x00000004UL | 106 | #define LNK_FILE__WRITE 0x00000004UL |
@@ -136,6 +138,7 @@ | |||
136 | #define CHR_FILE__EXECUTE_NO_TRANS 0x00020000UL | 138 | #define CHR_FILE__EXECUTE_NO_TRANS 0x00020000UL |
137 | #define CHR_FILE__ENTRYPOINT 0x00040000UL | 139 | #define CHR_FILE__ENTRYPOINT 0x00040000UL |
138 | #define CHR_FILE__EXECMOD 0x00080000UL | 140 | #define CHR_FILE__EXECMOD 0x00080000UL |
141 | #define CHR_FILE__OPEN 0x00100000UL | ||
139 | #define BLK_FILE__IOCTL 0x00000001UL | 142 | #define BLK_FILE__IOCTL 0x00000001UL |
140 | #define BLK_FILE__READ 0x00000002UL | 143 | #define BLK_FILE__READ 0x00000002UL |
141 | #define BLK_FILE__WRITE 0x00000004UL | 144 | #define BLK_FILE__WRITE 0x00000004UL |
@@ -153,6 +156,7 @@ | |||
153 | #define BLK_FILE__SWAPON 0x00004000UL | 156 | #define BLK_FILE__SWAPON 0x00004000UL |
154 | #define BLK_FILE__QUOTAON 0x00008000UL | 157 | #define BLK_FILE__QUOTAON 0x00008000UL |
155 | #define BLK_FILE__MOUNTON 0x00010000UL | 158 | #define BLK_FILE__MOUNTON 0x00010000UL |
159 | #define BLK_FILE__OPEN 0x00020000UL | ||
156 | #define SOCK_FILE__IOCTL 0x00000001UL | 160 | #define SOCK_FILE__IOCTL 0x00000001UL |
157 | #define SOCK_FILE__READ 0x00000002UL | 161 | #define SOCK_FILE__READ 0x00000002UL |
158 | #define SOCK_FILE__WRITE 0x00000004UL | 162 | #define SOCK_FILE__WRITE 0x00000004UL |
@@ -187,6 +191,7 @@ | |||
187 | #define FIFO_FILE__SWAPON 0x00004000UL | 191 | #define FIFO_FILE__SWAPON 0x00004000UL |
188 | #define FIFO_FILE__QUOTAON 0x00008000UL | 192 | #define FIFO_FILE__QUOTAON 0x00008000UL |
189 | #define FIFO_FILE__MOUNTON 0x00010000UL | 193 | #define FIFO_FILE__MOUNTON 0x00010000UL |
194 | #define FIFO_FILE__OPEN 0x00020000UL | ||
190 | #define FD__USE 0x00000001UL | 195 | #define FD__USE 0x00000001UL |
191 | #define SOCKET__IOCTL 0x00000001UL | 196 | #define SOCKET__IOCTL 0x00000001UL |
192 | #define SOCKET__READ 0x00000002UL | 197 | #define SOCKET__READ 0x00000002UL |
diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h index 00a2809c8506..9a9e7cd9a379 100644 --- a/security/selinux/include/netlabel.h +++ b/security/selinux/include/netlabel.h | |||
@@ -41,10 +41,6 @@ void selinux_netlbl_cache_invalidate(void); | |||
41 | 41 | ||
42 | void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec, | 42 | void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec, |
43 | int family); | 43 | int family); |
44 | void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec, | ||
45 | int family); | ||
46 | void selinux_netlbl_sk_security_clone(struct sk_security_struct *ssec, | ||
47 | struct sk_security_struct *newssec); | ||
48 | 44 | ||
49 | int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, | 45 | int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, |
50 | u16 family, | 46 | u16 family, |
@@ -73,18 +69,6 @@ static inline void selinux_netlbl_sk_security_reset( | |||
73 | { | 69 | { |
74 | return; | 70 | return; |
75 | } | 71 | } |
76 | static inline void selinux_netlbl_sk_security_init( | ||
77 | struct sk_security_struct *ssec, | ||
78 | int family) | ||
79 | { | ||
80 | return; | ||
81 | } | ||
82 | static inline void selinux_netlbl_sk_security_clone( | ||
83 | struct sk_security_struct *ssec, | ||
84 | struct sk_security_struct *newssec) | ||
85 | { | ||
86 | return; | ||
87 | } | ||
88 | 72 | ||
89 | static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, | 73 | static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, |
90 | u16 family, | 74 | u16 family, |
diff --git a/security/selinux/include/netport.h b/security/selinux/include/netport.h new file mode 100644 index 000000000000..8991752eaf93 --- /dev/null +++ b/security/selinux/include/netport.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * Network port table | ||
3 | * | ||
4 | * SELinux must keep a mapping of network ports to labels/SIDs. This | ||
5 | * mapping is maintained as part of the normal policy but a fast cache is | ||
6 | * needed to reduce the lookup overhead. | ||
7 | * | ||
8 | * Author: Paul Moore <paul.moore@hp.com> | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2008 | ||
14 | * | ||
15 | * This program is free software: you can redistribute it and/or modify | ||
16 | * it under the terms of version 2 of the GNU General Public License as | ||
17 | * published by the Free Software Foundation. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #ifndef _SELINUX_NETPORT_H | ||
27 | #define _SELINUX_NETPORT_H | ||
28 | |||
29 | int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid); | ||
30 | |||
31 | #endif | ||
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index c6c2bb4ebacc..300b61bad7b3 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h | |||
@@ -28,14 +28,12 @@ | |||
28 | #include "avc.h" | 28 | #include "avc.h" |
29 | 29 | ||
30 | struct task_security_struct { | 30 | struct task_security_struct { |
31 | struct task_struct *task; /* back pointer to task object */ | ||
32 | u32 osid; /* SID prior to last execve */ | 31 | u32 osid; /* SID prior to last execve */ |
33 | u32 sid; /* current SID */ | 32 | u32 sid; /* current SID */ |
34 | u32 exec_sid; /* exec SID */ | 33 | u32 exec_sid; /* exec SID */ |
35 | u32 create_sid; /* fscreate SID */ | 34 | u32 create_sid; /* fscreate SID */ |
36 | u32 keycreate_sid; /* keycreate SID */ | 35 | u32 keycreate_sid; /* keycreate SID */ |
37 | u32 sockcreate_sid; /* fscreate SID */ | 36 | u32 sockcreate_sid; /* fscreate SID */ |
38 | u32 ptrace_sid; /* SID of ptrace parent */ | ||
39 | }; | 37 | }; |
40 | 38 | ||
41 | struct inode_security_struct { | 39 | struct inode_security_struct { |
@@ -50,7 +48,6 @@ struct inode_security_struct { | |||
50 | }; | 48 | }; |
51 | 49 | ||
52 | struct file_security_struct { | 50 | struct file_security_struct { |
53 | struct file *file; /* back pointer to file object */ | ||
54 | u32 sid; /* SID of open file description */ | 51 | u32 sid; /* SID of open file description */ |
55 | u32 fown_sid; /* SID of file owner (for SIGIO) */ | 52 | u32 fown_sid; /* SID of file owner (for SIGIO) */ |
56 | u32 isid; /* SID of inode at the time of file open */ | 53 | u32 isid; /* SID of inode at the time of file open */ |
@@ -73,18 +70,15 @@ struct superblock_security_struct { | |||
73 | }; | 70 | }; |
74 | 71 | ||
75 | struct msg_security_struct { | 72 | struct msg_security_struct { |
76 | struct msg_msg *msg; /* back pointer */ | ||
77 | u32 sid; /* SID of message */ | 73 | u32 sid; /* SID of message */ |
78 | }; | 74 | }; |
79 | 75 | ||
80 | struct ipc_security_struct { | 76 | struct ipc_security_struct { |
81 | struct kern_ipc_perm *ipc_perm; /* back pointer */ | ||
82 | u16 sclass; /* security class of this object */ | 77 | u16 sclass; /* security class of this object */ |
83 | u32 sid; /* SID of IPC resource */ | 78 | u32 sid; /* SID of IPC resource */ |
84 | }; | 79 | }; |
85 | 80 | ||
86 | struct bprm_security_struct { | 81 | struct bprm_security_struct { |
87 | struct linux_binprm *bprm; /* back pointer to bprm object */ | ||
88 | u32 sid; /* SID for transformed process */ | 82 | u32 sid; /* SID for transformed process */ |
89 | unsigned char set; | 83 | unsigned char set; |
90 | 84 | ||
@@ -109,8 +103,13 @@ struct netnode_security_struct { | |||
109 | u16 family; /* address family */ | 103 | u16 family; /* address family */ |
110 | }; | 104 | }; |
111 | 105 | ||
106 | struct netport_security_struct { | ||
107 | u32 sid; /* SID for this node */ | ||
108 | u16 port; /* port number */ | ||
109 | u8 protocol; /* transport protocol */ | ||
110 | }; | ||
111 | |||
112 | struct sk_security_struct { | 112 | struct sk_security_struct { |
113 | struct sock *sk; /* back pointer to sk object */ | ||
114 | u32 sid; /* SID of this object */ | 113 | u32 sid; /* SID of this object */ |
115 | u32 peer_sid; /* SID of peer */ | 114 | u32 peer_sid; /* SID of peer */ |
116 | u16 sclass; /* sock security class */ | 115 | u16 sclass; /* sock security class */ |
@@ -120,12 +119,10 @@ struct sk_security_struct { | |||
120 | NLBL_REQUIRE, | 119 | NLBL_REQUIRE, |
121 | NLBL_LABELED, | 120 | NLBL_LABELED, |
122 | } nlbl_state; | 121 | } nlbl_state; |
123 | spinlock_t nlbl_lock; /* protects nlbl_state */ | ||
124 | #endif | 122 | #endif |
125 | }; | 123 | }; |
126 | 124 | ||
127 | struct key_security_struct { | 125 | struct key_security_struct { |
128 | struct key *obj; /* back pointer */ | ||
129 | u32 sid; /* SID of key */ | 126 | u32 sid; /* SID of key */ |
130 | }; | 127 | }; |
131 | 128 | ||
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 44e12ec88090..1904c462a605 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -26,13 +26,14 @@ | |||
26 | #define POLICYDB_VERSION_AVTAB 20 | 26 | #define POLICYDB_VERSION_AVTAB 20 |
27 | #define POLICYDB_VERSION_RANGETRANS 21 | 27 | #define POLICYDB_VERSION_RANGETRANS 21 |
28 | #define POLICYDB_VERSION_POLCAP 22 | 28 | #define POLICYDB_VERSION_POLCAP 22 |
29 | #define POLICYDB_VERSION_PERMISSIVE 23 | ||
29 | 30 | ||
30 | /* Range of policy versions we understand*/ | 31 | /* Range of policy versions we understand*/ |
31 | #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE | 32 | #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE |
32 | #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX | 33 | #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX |
33 | #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE | 34 | #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE |
34 | #else | 35 | #else |
35 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP | 36 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_PERMISSIVE |
36 | #endif | 37 | #endif |
37 | 38 | ||
38 | #define CONTEXT_MNT 0x01 | 39 | #define CONTEXT_MNT 0x01 |
@@ -40,6 +41,11 @@ | |||
40 | #define ROOTCONTEXT_MNT 0x04 | 41 | #define ROOTCONTEXT_MNT 0x04 |
41 | #define DEFCONTEXT_MNT 0x08 | 42 | #define DEFCONTEXT_MNT 0x08 |
42 | 43 | ||
44 | #define CONTEXT_STR "context=" | ||
45 | #define FSCONTEXT_STR "fscontext=" | ||
46 | #define ROOTCONTEXT_STR "rootcontext=" | ||
47 | #define DEFCONTEXT_STR "defcontext=" | ||
48 | |||
43 | struct netlbl_lsm_secattr; | 49 | struct netlbl_lsm_secattr; |
44 | 50 | ||
45 | extern int selinux_enabled; | 51 | extern int selinux_enabled; |
@@ -48,11 +54,13 @@ extern int selinux_mls_enabled; | |||
48 | /* Policy capabilities */ | 54 | /* Policy capabilities */ |
49 | enum { | 55 | enum { |
50 | POLICYDB_CAPABILITY_NETPEER, | 56 | POLICYDB_CAPABILITY_NETPEER, |
57 | POLICYDB_CAPABILITY_OPENPERM, | ||
51 | __POLICYDB_CAPABILITY_MAX | 58 | __POLICYDB_CAPABILITY_MAX |
52 | }; | 59 | }; |
53 | #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) | 60 | #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) |
54 | 61 | ||
55 | extern int selinux_policycap_netpeer; | 62 | extern int selinux_policycap_netpeer; |
63 | extern int selinux_policycap_openperm; | ||
56 | 64 | ||
57 | int security_load_policy(void * data, size_t len); | 65 | int security_load_policy(void * data, size_t len); |
58 | 66 | ||
@@ -67,6 +75,8 @@ struct av_decision { | |||
67 | u32 seqno; | 75 | u32 seqno; |
68 | }; | 76 | }; |
69 | 77 | ||
78 | int security_permissive_sid(u32 sid); | ||
79 | |||
70 | int security_compute_av(u32 ssid, u32 tsid, | 80 | int security_compute_av(u32 ssid, u32 tsid, |
71 | u16 tclass, u32 requested, | 81 | u16 tclass, u32 requested, |
72 | struct av_decision *avd); | 82 | struct av_decision *avd); |
@@ -92,8 +102,7 @@ int security_context_to_sid_default(char *scontext, u32 scontext_len, | |||
92 | int security_get_user_sids(u32 callsid, char *username, | 102 | int security_get_user_sids(u32 callsid, char *username, |
93 | u32 **sids, u32 *nel); | 103 | u32 **sids, u32 *nel); |
94 | 104 | ||
95 | int security_port_sid(u16 domain, u16 type, u8 protocol, u16 port, | 105 | int security_port_sid(u8 protocol, u16 port, u32 *out_sid); |
96 | u32 *out_sid); | ||
97 | 106 | ||
98 | int security_netif_sid(char *name, u32 *if_sid); | 107 | int security_netif_sid(char *name, u32 *if_sid); |
99 | 108 | ||
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 0fa2be4149e8..e8ee91ac12ef 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #include "objsec.h" | 35 | #include "objsec.h" |
36 | #include "security.h" | 36 | #include "security.h" |
37 | #include "netlabel.h" | ||
37 | 38 | ||
38 | /** | 39 | /** |
39 | * selinux_netlbl_sidlookup_cached - Cache a SID lookup | 40 | * selinux_netlbl_sidlookup_cached - Cache a SID lookup |
@@ -69,9 +70,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb, | |||
69 | * | 70 | * |
70 | * Description: | 71 | * Description: |
71 | * Attempt to label a socket using the NetLabel mechanism using the given | 72 | * Attempt to label a socket using the NetLabel mechanism using the given |
72 | * SID. Returns zero values on success, negative values on failure. The | 73 | * SID. Returns zero values on success, negative values on failure. |
73 | * caller is responsibile for calling rcu_read_lock() before calling this | ||
74 | * this function and rcu_read_unlock() after this function returns. | ||
75 | * | 74 | * |
76 | */ | 75 | */ |
77 | static int selinux_netlbl_sock_setsid(struct sock *sk, u32 sid) | 76 | static int selinux_netlbl_sock_setsid(struct sock *sk, u32 sid) |
@@ -86,11 +85,8 @@ static int selinux_netlbl_sock_setsid(struct sock *sk, u32 sid) | |||
86 | if (rc != 0) | 85 | if (rc != 0) |
87 | goto sock_setsid_return; | 86 | goto sock_setsid_return; |
88 | rc = netlbl_sock_setattr(sk, &secattr); | 87 | rc = netlbl_sock_setattr(sk, &secattr); |
89 | if (rc == 0) { | 88 | if (rc == 0) |
90 | spin_lock_bh(&sksec->nlbl_lock); | ||
91 | sksec->nlbl_state = NLBL_LABELED; | 89 | sksec->nlbl_state = NLBL_LABELED; |
92 | spin_unlock_bh(&sksec->nlbl_lock); | ||
93 | } | ||
94 | 90 | ||
95 | sock_setsid_return: | 91 | sock_setsid_return: |
96 | netlbl_secattr_destroy(&secattr); | 92 | netlbl_secattr_destroy(&secattr); |
@@ -129,45 +125,6 @@ void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec, | |||
129 | } | 125 | } |
130 | 126 | ||
131 | /** | 127 | /** |
132 | * selinux_netlbl_sk_security_init - Setup the NetLabel fields | ||
133 | * @ssec: the sk_security_struct | ||
134 | * @family: the socket family | ||
135 | * | ||
136 | * Description: | ||
137 | * Called when a new sk_security_struct is allocated to initialize the NetLabel | ||
138 | * fields. | ||
139 | * | ||
140 | */ | ||
141 | void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec, | ||
142 | int family) | ||
143 | { | ||
144 | /* No locking needed, we are the only one who has access to ssec */ | ||
145 | selinux_netlbl_sk_security_reset(ssec, family); | ||
146 | spin_lock_init(&ssec->nlbl_lock); | ||
147 | } | ||
148 | |||
149 | /** | ||
150 | * selinux_netlbl_sk_security_clone - Copy the NetLabel fields | ||
151 | * @ssec: the original sk_security_struct | ||
152 | * @newssec: the cloned sk_security_struct | ||
153 | * | ||
154 | * Description: | ||
155 | * Clone the NetLabel specific sk_security_struct fields from @ssec to | ||
156 | * @newssec. | ||
157 | * | ||
158 | */ | ||
159 | void selinux_netlbl_sk_security_clone(struct sk_security_struct *ssec, | ||
160 | struct sk_security_struct *newssec) | ||
161 | { | ||
162 | /* We don't need to take newssec->nlbl_lock because we are the only | ||
163 | * thread with access to newssec, but we do need to take the RCU read | ||
164 | * lock as other threads could have access to ssec */ | ||
165 | rcu_read_lock(); | ||
166 | selinux_netlbl_sk_security_reset(newssec, ssec->sk->sk_family); | ||
167 | rcu_read_unlock(); | ||
168 | } | ||
169 | |||
170 | /** | ||
171 | * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel | 128 | * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel |
172 | * @skb: the packet | 129 | * @skb: the packet |
173 | * @family: protocol family | 130 | * @family: protocol family |
@@ -221,12 +178,8 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock) | |||
221 | struct netlbl_lsm_secattr secattr; | 178 | struct netlbl_lsm_secattr secattr; |
222 | u32 nlbl_peer_sid; | 179 | u32 nlbl_peer_sid; |
223 | 180 | ||
224 | rcu_read_lock(); | 181 | if (sksec->nlbl_state != NLBL_REQUIRE) |
225 | |||
226 | if (sksec->nlbl_state != NLBL_REQUIRE) { | ||
227 | rcu_read_unlock(); | ||
228 | return; | 182 | return; |
229 | } | ||
230 | 183 | ||
231 | netlbl_secattr_init(&secattr); | 184 | netlbl_secattr_init(&secattr); |
232 | if (netlbl_sock_getattr(sk, &secattr) == 0 && | 185 | if (netlbl_sock_getattr(sk, &secattr) == 0 && |
@@ -239,8 +192,6 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock) | |||
239 | * here we will pick up the pieces in later calls to | 192 | * here we will pick up the pieces in later calls to |
240 | * selinux_netlbl_inode_permission(). */ | 193 | * selinux_netlbl_inode_permission(). */ |
241 | selinux_netlbl_sock_setsid(sk, sksec->sid); | 194 | selinux_netlbl_sock_setsid(sk, sksec->sid); |
242 | |||
243 | rcu_read_unlock(); | ||
244 | } | 195 | } |
245 | 196 | ||
246 | /** | 197 | /** |
@@ -254,16 +205,13 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock) | |||
254 | */ | 205 | */ |
255 | int selinux_netlbl_socket_post_create(struct socket *sock) | 206 | int selinux_netlbl_socket_post_create(struct socket *sock) |
256 | { | 207 | { |
257 | int rc = 0; | ||
258 | struct sock *sk = sock->sk; | 208 | struct sock *sk = sock->sk; |
259 | struct sk_security_struct *sksec = sk->sk_security; | 209 | struct sk_security_struct *sksec = sk->sk_security; |
260 | 210 | ||
261 | rcu_read_lock(); | 211 | if (sksec->nlbl_state != NLBL_REQUIRE) |
262 | if (sksec->nlbl_state == NLBL_REQUIRE) | 212 | return 0; |
263 | rc = selinux_netlbl_sock_setsid(sk, sksec->sid); | ||
264 | rcu_read_unlock(); | ||
265 | 213 | ||
266 | return rc; | 214 | return selinux_netlbl_sock_setsid(sk, sksec->sid); |
267 | } | 215 | } |
268 | 216 | ||
269 | /** | 217 | /** |
@@ -288,21 +236,21 @@ int selinux_netlbl_inode_permission(struct inode *inode, int mask) | |||
288 | if (!S_ISSOCK(inode->i_mode) || | 236 | if (!S_ISSOCK(inode->i_mode) || |
289 | ((mask & (MAY_WRITE | MAY_APPEND)) == 0)) | 237 | ((mask & (MAY_WRITE | MAY_APPEND)) == 0)) |
290 | return 0; | 238 | return 0; |
239 | |||
291 | sock = SOCKET_I(inode); | 240 | sock = SOCKET_I(inode); |
292 | sk = sock->sk; | 241 | sk = sock->sk; |
293 | sksec = sk->sk_security; | 242 | sksec = sk->sk_security; |
294 | 243 | if (sksec->nlbl_state != NLBL_REQUIRE) | |
295 | rcu_read_lock(); | ||
296 | if (sksec->nlbl_state != NLBL_REQUIRE) { | ||
297 | rcu_read_unlock(); | ||
298 | return 0; | 244 | return 0; |
299 | } | 245 | |
300 | local_bh_disable(); | 246 | local_bh_disable(); |
301 | bh_lock_sock_nested(sk); | 247 | bh_lock_sock_nested(sk); |
302 | rc = selinux_netlbl_sock_setsid(sk, sksec->sid); | 248 | if (likely(sksec->nlbl_state == NLBL_REQUIRE)) |
249 | rc = selinux_netlbl_sock_setsid(sk, sksec->sid); | ||
250 | else | ||
251 | rc = 0; | ||
303 | bh_unlock_sock(sk); | 252 | bh_unlock_sock(sk); |
304 | local_bh_enable(); | 253 | local_bh_enable(); |
305 | rcu_read_unlock(); | ||
306 | 254 | ||
307 | return rc; | 255 | return rc; |
308 | } | 256 | } |
@@ -385,7 +333,6 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, | |||
385 | struct sk_security_struct *sksec = sk->sk_security; | 333 | struct sk_security_struct *sksec = sk->sk_security; |
386 | struct netlbl_lsm_secattr secattr; | 334 | struct netlbl_lsm_secattr secattr; |
387 | 335 | ||
388 | rcu_read_lock(); | ||
389 | if (level == IPPROTO_IP && optname == IP_OPTIONS && | 336 | if (level == IPPROTO_IP && optname == IP_OPTIONS && |
390 | sksec->nlbl_state == NLBL_LABELED) { | 337 | sksec->nlbl_state == NLBL_LABELED) { |
391 | netlbl_secattr_init(&secattr); | 338 | netlbl_secattr_init(&secattr); |
@@ -396,7 +343,6 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, | |||
396 | rc = -EACCES; | 343 | rc = -EACCES; |
397 | netlbl_secattr_destroy(&secattr); | 344 | netlbl_secattr_destroy(&secattr); |
398 | } | 345 | } |
399 | rcu_read_unlock(); | ||
400 | 346 | ||
401 | return rc; | 347 | return rc; |
402 | } | 348 | } |
diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c index b59871d74dad..6214a7a73149 100644 --- a/security/selinux/netlink.c +++ b/security/selinux/netlink.c | |||
@@ -89,7 +89,7 @@ out: | |||
89 | nlmsg_failure: | 89 | nlmsg_failure: |
90 | kfree_skb(skb); | 90 | kfree_skb(skb); |
91 | oom: | 91 | oom: |
92 | printk(KERN_ERR "SELinux: OOM in %s\n", __FUNCTION__); | 92 | printk(KERN_ERR "SELinux: OOM in %s\n", __func__); |
93 | goto out; | 93 | goto out; |
94 | } | 94 | } |
95 | 95 | ||
diff --git a/security/selinux/netport.c b/security/selinux/netport.c new file mode 100644 index 000000000000..68ede3c498ab --- /dev/null +++ b/security/selinux/netport.c | |||
@@ -0,0 +1,286 @@ | |||
1 | /* | ||
2 | * Network port table | ||
3 | * | ||
4 | * SELinux must keep a mapping of network ports to labels/SIDs. This | ||
5 | * mapping is maintained as part of the normal policy but a fast cache is | ||
6 | * needed to reduce the lookup overhead. | ||
7 | * | ||
8 | * Author: Paul Moore <paul.moore@hp.com> | ||
9 | * | ||
10 | * This code is heavily based on the "netif" concept originally developed by | ||
11 | * James Morris <jmorris@redhat.com> | ||
12 | * (see security/selinux/netif.c for more information) | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2008 | ||
18 | * | ||
19 | * This program is free software: you can redistribute it and/or modify | ||
20 | * it under the terms of version 2 of the GNU General Public License as | ||
21 | * published by the Free Software Foundation. | ||
22 | * | ||
23 | * This program is distributed in the hope that it will be useful, | ||
24 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
26 | * GNU General Public License for more details. | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #include <linux/types.h> | ||
31 | #include <linux/rcupdate.h> | ||
32 | #include <linux/list.h> | ||
33 | #include <linux/spinlock.h> | ||
34 | #include <linux/in.h> | ||
35 | #include <linux/in6.h> | ||
36 | #include <linux/ip.h> | ||
37 | #include <linux/ipv6.h> | ||
38 | #include <net/ip.h> | ||
39 | #include <net/ipv6.h> | ||
40 | #include <asm/bug.h> | ||
41 | |||
42 | #include "netport.h" | ||
43 | #include "objsec.h" | ||
44 | |||
45 | #define SEL_NETPORT_HASH_SIZE 256 | ||
46 | #define SEL_NETPORT_HASH_BKT_LIMIT 16 | ||
47 | |||
48 | struct sel_netport_bkt { | ||
49 | int size; | ||
50 | struct list_head list; | ||
51 | }; | ||
52 | |||
53 | struct sel_netport { | ||
54 | struct netport_security_struct psec; | ||
55 | |||
56 | struct list_head list; | ||
57 | struct rcu_head rcu; | ||
58 | }; | ||
59 | |||
60 | /* NOTE: we are using a combined hash table for both IPv4 and IPv6, the reason | ||
61 | * for this is that I suspect most users will not make heavy use of both | ||
62 | * address families at the same time so one table will usually end up wasted, | ||
63 | * if this becomes a problem we can always add a hash table for each address | ||
64 | * family later */ | ||
65 | |||
66 | static LIST_HEAD(sel_netport_list); | ||
67 | static DEFINE_SPINLOCK(sel_netport_lock); | ||
68 | static struct sel_netport_bkt sel_netport_hash[SEL_NETPORT_HASH_SIZE]; | ||
69 | |||
70 | /** | ||
71 | * sel_netport_free - Frees a port entry | ||
72 | * @p: the entry's RCU field | ||
73 | * | ||
74 | * Description: | ||
75 | * This function is designed to be used as a callback to the call_rcu() | ||
76 | * function so that memory allocated to a hash table port entry can be | ||
77 | * released safely. | ||
78 | * | ||
79 | */ | ||
80 | static void sel_netport_free(struct rcu_head *p) | ||
81 | { | ||
82 | struct sel_netport *port = container_of(p, struct sel_netport, rcu); | ||
83 | kfree(port); | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * sel_netport_hashfn - Hashing function for the port table | ||
88 | * @pnum: port number | ||
89 | * | ||
90 | * Description: | ||
91 | * This is the hashing function for the port table, it returns the bucket | ||
92 | * number for the given port. | ||
93 | * | ||
94 | */ | ||
95 | static unsigned int sel_netport_hashfn(u16 pnum) | ||
96 | { | ||
97 | return (pnum & (SEL_NETPORT_HASH_SIZE - 1)); | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * sel_netport_find - Search for a port record | ||
102 | * @protocol: protocol | ||
103 | * @port: pnum | ||
104 | * | ||
105 | * Description: | ||
106 | * Search the network port table and return the matching record. If an entry | ||
107 | * can not be found in the table return NULL. | ||
108 | * | ||
109 | */ | ||
110 | static struct sel_netport *sel_netport_find(u8 protocol, u16 pnum) | ||
111 | { | ||
112 | unsigned int idx; | ||
113 | struct sel_netport *port; | ||
114 | |||
115 | idx = sel_netport_hashfn(pnum); | ||
116 | list_for_each_entry_rcu(port, &sel_netport_hash[idx].list, list) | ||
117 | if (port->psec.port == pnum && | ||
118 | port->psec.protocol == protocol) | ||
119 | return port; | ||
120 | |||
121 | return NULL; | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * sel_netport_insert - Insert a new port into the table | ||
126 | * @port: the new port record | ||
127 | * | ||
128 | * Description: | ||
129 | * Add a new port record to the network address hash table. Returns zero on | ||
130 | * success, negative values on failure. | ||
131 | * | ||
132 | */ | ||
133 | static int sel_netport_insert(struct sel_netport *port) | ||
134 | { | ||
135 | unsigned int idx; | ||
136 | |||
137 | /* we need to impose a limit on the growth of the hash table so check | ||
138 | * this bucket to make sure it is within the specified bounds */ | ||
139 | idx = sel_netport_hashfn(port->psec.port); | ||
140 | list_add_rcu(&port->list, &sel_netport_hash[idx].list); | ||
141 | if (sel_netport_hash[idx].size == SEL_NETPORT_HASH_BKT_LIMIT) { | ||
142 | struct sel_netport *tail; | ||
143 | tail = list_entry(port->list.prev, struct sel_netport, list); | ||
144 | list_del_rcu(port->list.prev); | ||
145 | call_rcu(&tail->rcu, sel_netport_free); | ||
146 | } else | ||
147 | sel_netport_hash[idx].size++; | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | /** | ||
153 | * sel_netport_sid_slow - Lookup the SID of a network address using the policy | ||
154 | * @protocol: protocol | ||
155 | * @pnum: port | ||
156 | * @sid: port SID | ||
157 | * | ||
158 | * Description: | ||
159 | * This function determines the SID of a network port by quering the security | ||
160 | * policy. The result is added to the network port table to speedup future | ||
161 | * queries. Returns zero on success, negative values on failure. | ||
162 | * | ||
163 | */ | ||
164 | static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid) | ||
165 | { | ||
166 | int ret; | ||
167 | struct sel_netport *port; | ||
168 | struct sel_netport *new = NULL; | ||
169 | |||
170 | spin_lock_bh(&sel_netport_lock); | ||
171 | port = sel_netport_find(protocol, pnum); | ||
172 | if (port != NULL) { | ||
173 | *sid = port->psec.sid; | ||
174 | ret = 0; | ||
175 | goto out; | ||
176 | } | ||
177 | new = kzalloc(sizeof(*new), GFP_ATOMIC); | ||
178 | if (new == NULL) { | ||
179 | ret = -ENOMEM; | ||
180 | goto out; | ||
181 | } | ||
182 | ret = security_port_sid(protocol, pnum, &new->psec.sid); | ||
183 | if (ret != 0) | ||
184 | goto out; | ||
185 | new->psec.port = pnum; | ||
186 | new->psec.protocol = protocol; | ||
187 | ret = sel_netport_insert(new); | ||
188 | if (ret != 0) | ||
189 | goto out; | ||
190 | *sid = new->psec.sid; | ||
191 | |||
192 | out: | ||
193 | spin_unlock_bh(&sel_netport_lock); | ||
194 | if (unlikely(ret)) { | ||
195 | printk(KERN_WARNING | ||
196 | "SELinux: failure in sel_netport_sid_slow()," | ||
197 | " unable to determine network port label\n"); | ||
198 | kfree(new); | ||
199 | } | ||
200 | return ret; | ||
201 | } | ||
202 | |||
203 | /** | ||
204 | * sel_netport_sid - Lookup the SID of a network port | ||
205 | * @protocol: protocol | ||
206 | * @pnum: port | ||
207 | * @sid: port SID | ||
208 | * | ||
209 | * Description: | ||
210 | * This function determines the SID of a network port using the fastest method | ||
211 | * possible. First the port table is queried, but if an entry can't be found | ||
212 | * then the policy is queried and the result is added to the table to speedup | ||
213 | * future queries. Returns zero on success, negative values on failure. | ||
214 | * | ||
215 | */ | ||
216 | int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid) | ||
217 | { | ||
218 | struct sel_netport *port; | ||
219 | |||
220 | rcu_read_lock(); | ||
221 | port = sel_netport_find(protocol, pnum); | ||
222 | if (port != NULL) { | ||
223 | *sid = port->psec.sid; | ||
224 | rcu_read_unlock(); | ||
225 | return 0; | ||
226 | } | ||
227 | rcu_read_unlock(); | ||
228 | |||
229 | return sel_netport_sid_slow(protocol, pnum, sid); | ||
230 | } | ||
231 | |||
232 | /** | ||
233 | * sel_netport_flush - Flush the entire network port table | ||
234 | * | ||
235 | * Description: | ||
236 | * Remove all entries from the network address table. | ||
237 | * | ||
238 | */ | ||
239 | static void sel_netport_flush(void) | ||
240 | { | ||
241 | unsigned int idx; | ||
242 | struct sel_netport *port; | ||
243 | |||
244 | spin_lock_bh(&sel_netport_lock); | ||
245 | for (idx = 0; idx < SEL_NETPORT_HASH_SIZE; idx++) { | ||
246 | list_for_each_entry(port, &sel_netport_hash[idx].list, list) { | ||
247 | list_del_rcu(&port->list); | ||
248 | call_rcu(&port->rcu, sel_netport_free); | ||
249 | } | ||
250 | sel_netport_hash[idx].size = 0; | ||
251 | } | ||
252 | spin_unlock_bh(&sel_netport_lock); | ||
253 | } | ||
254 | |||
255 | static int sel_netport_avc_callback(u32 event, u32 ssid, u32 tsid, | ||
256 | u16 class, u32 perms, u32 *retained) | ||
257 | { | ||
258 | if (event == AVC_CALLBACK_RESET) { | ||
259 | sel_netport_flush(); | ||
260 | synchronize_net(); | ||
261 | } | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static __init int sel_netport_init(void) | ||
266 | { | ||
267 | int iter; | ||
268 | int ret; | ||
269 | |||
270 | if (!selinux_enabled) | ||
271 | return 0; | ||
272 | |||
273 | for (iter = 0; iter < SEL_NETPORT_HASH_SIZE; iter++) { | ||
274 | INIT_LIST_HEAD(&sel_netport_hash[iter].list); | ||
275 | sel_netport_hash[iter].size = 0; | ||
276 | } | ||
277 | |||
278 | ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET, | ||
279 | SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); | ||
280 | if (ret != 0) | ||
281 | panic("avc_add_callback() failed, error %d\n", ret); | ||
282 | |||
283 | return ret; | ||
284 | } | ||
285 | |||
286 | __initcall(sel_netport_init); | ||
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 0341567665b3..26fabad09769 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -42,7 +42,8 @@ | |||
42 | 42 | ||
43 | /* Policy capability filenames */ | 43 | /* Policy capability filenames */ |
44 | static char *policycap_names[] = { | 44 | static char *policycap_names[] = { |
45 | "network_peer_controls" | 45 | "network_peer_controls", |
46 | "open_perms" | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; | 49 | unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; |
@@ -391,7 +392,7 @@ static ssize_t sel_write_context(struct file * file, char *buf, size_t size) | |||
391 | 392 | ||
392 | if (len > SIMPLE_TRANSACTION_LIMIT) { | 393 | if (len > SIMPLE_TRANSACTION_LIMIT) { |
393 | printk(KERN_ERR "%s: context size (%u) exceeds payload " | 394 | printk(KERN_ERR "%s: context size (%u) exceeds payload " |
394 | "max\n", __FUNCTION__, len); | 395 | "max\n", __func__, len); |
395 | length = -ERANGE; | 396 | length = -ERANGE; |
396 | goto out; | 397 | goto out; |
397 | } | 398 | } |
@@ -644,7 +645,7 @@ static ssize_t sel_write_create(struct file * file, char *buf, size_t size) | |||
644 | 645 | ||
645 | if (len > SIMPLE_TRANSACTION_LIMIT) { | 646 | if (len > SIMPLE_TRANSACTION_LIMIT) { |
646 | printk(KERN_ERR "%s: context size (%u) exceeds payload " | 647 | printk(KERN_ERR "%s: context size (%u) exceeds payload " |
647 | "max\n", __FUNCTION__, len); | 648 | "max\n", __func__, len); |
648 | length = -ERANGE; | 649 | length = -ERANGE; |
649 | goto out3; | 650 | goto out3; |
650 | } | 651 | } |
@@ -821,7 +822,7 @@ static ssize_t sel_write_member(struct file * file, char *buf, size_t size) | |||
821 | 822 | ||
822 | if (len > SIMPLE_TRANSACTION_LIMIT) { | 823 | if (len > SIMPLE_TRANSACTION_LIMIT) { |
823 | printk(KERN_ERR "%s: context size (%u) exceeds payload " | 824 | printk(KERN_ERR "%s: context size (%u) exceeds payload " |
824 | "max\n", __FUNCTION__, len); | 825 | "max\n", __func__, len); |
825 | length = -ERANGE; | 826 | length = -ERANGE; |
826 | goto out3; | 827 | goto out3; |
827 | } | 828 | } |
@@ -1760,7 +1761,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent) | |||
1760 | out: | 1761 | out: |
1761 | return ret; | 1762 | return ret; |
1762 | err: | 1763 | err: |
1763 | printk(KERN_ERR "%s: failed while creating inodes\n", __FUNCTION__); | 1764 | printk(KERN_ERR "%s: failed while creating inodes\n", __func__); |
1764 | goto out; | 1765 | goto out; |
1765 | } | 1766 | } |
1766 | 1767 | ||
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index cd10e27fc9e6..916e73a18bc5 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c | |||
@@ -280,8 +280,8 @@ int avtab_alloc(struct avtab *h, u32 nrules) | |||
280 | h->nel = 0; | 280 | h->nel = 0; |
281 | h->nslot = nslot; | 281 | h->nslot = nslot; |
282 | h->mask = mask; | 282 | h->mask = mask; |
283 | printk(KERN_DEBUG "SELinux:%d avtab hash slots allocated. " | 283 | printk(KERN_DEBUG "SELinux: %d avtab hash slots, %d rules.\n", |
284 | "Num of rules:%d\n", h->nslot, nrules); | 284 | h->nslot, nrules); |
285 | return 0; | 285 | return 0; |
286 | } | 286 | } |
287 | 287 | ||
@@ -345,18 +345,18 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, | |||
345 | if (vers < POLICYDB_VERSION_AVTAB) { | 345 | if (vers < POLICYDB_VERSION_AVTAB) { |
346 | rc = next_entry(buf32, fp, sizeof(u32)); | 346 | rc = next_entry(buf32, fp, sizeof(u32)); |
347 | if (rc < 0) { | 347 | if (rc < 0) { |
348 | printk(KERN_ERR "security: avtab: truncated entry\n"); | 348 | printk(KERN_ERR "SELinux: avtab: truncated entry\n"); |
349 | return -1; | 349 | return -1; |
350 | } | 350 | } |
351 | items2 = le32_to_cpu(buf32[0]); | 351 | items2 = le32_to_cpu(buf32[0]); |
352 | if (items2 > ARRAY_SIZE(buf32)) { | 352 | if (items2 > ARRAY_SIZE(buf32)) { |
353 | printk(KERN_ERR "security: avtab: entry overflow\n"); | 353 | printk(KERN_ERR "SELinux: avtab: entry overflow\n"); |
354 | return -1; | 354 | return -1; |
355 | 355 | ||
356 | } | 356 | } |
357 | rc = next_entry(buf32, fp, sizeof(u32)*items2); | 357 | rc = next_entry(buf32, fp, sizeof(u32)*items2); |
358 | if (rc < 0) { | 358 | if (rc < 0) { |
359 | printk(KERN_ERR "security: avtab: truncated entry\n"); | 359 | printk(KERN_ERR "SELinux: avtab: truncated entry\n"); |
360 | return -1; | 360 | return -1; |
361 | } | 361 | } |
362 | items = 0; | 362 | items = 0; |
@@ -364,19 +364,19 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, | |||
364 | val = le32_to_cpu(buf32[items++]); | 364 | val = le32_to_cpu(buf32[items++]); |
365 | key.source_type = (u16)val; | 365 | key.source_type = (u16)val; |
366 | if (key.source_type != val) { | 366 | if (key.source_type != val) { |
367 | printk("security: avtab: truncated source type\n"); | 367 | printk("SELinux: avtab: truncated source type\n"); |
368 | return -1; | 368 | return -1; |
369 | } | 369 | } |
370 | val = le32_to_cpu(buf32[items++]); | 370 | val = le32_to_cpu(buf32[items++]); |
371 | key.target_type = (u16)val; | 371 | key.target_type = (u16)val; |
372 | if (key.target_type != val) { | 372 | if (key.target_type != val) { |
373 | printk("security: avtab: truncated target type\n"); | 373 | printk("SELinux: avtab: truncated target type\n"); |
374 | return -1; | 374 | return -1; |
375 | } | 375 | } |
376 | val = le32_to_cpu(buf32[items++]); | 376 | val = le32_to_cpu(buf32[items++]); |
377 | key.target_class = (u16)val; | 377 | key.target_class = (u16)val; |
378 | if (key.target_class != val) { | 378 | if (key.target_class != val) { |
379 | printk("security: avtab: truncated target class\n"); | 379 | printk("SELinux: avtab: truncated target class\n"); |
380 | return -1; | 380 | return -1; |
381 | } | 381 | } |
382 | 382 | ||
@@ -384,12 +384,12 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, | |||
384 | enabled = (val & AVTAB_ENABLED_OLD) ? AVTAB_ENABLED : 0; | 384 | enabled = (val & AVTAB_ENABLED_OLD) ? AVTAB_ENABLED : 0; |
385 | 385 | ||
386 | if (!(val & (AVTAB_AV | AVTAB_TYPE))) { | 386 | if (!(val & (AVTAB_AV | AVTAB_TYPE))) { |
387 | printk("security: avtab: null entry\n"); | 387 | printk("SELinux: avtab: null entry\n"); |
388 | return -1; | 388 | return -1; |
389 | } | 389 | } |
390 | if ((val & AVTAB_AV) && | 390 | if ((val & AVTAB_AV) && |
391 | (val & AVTAB_TYPE)) { | 391 | (val & AVTAB_TYPE)) { |
392 | printk("security: avtab: entry has both access vectors and types\n"); | 392 | printk("SELinux: avtab: entry has both access vectors and types\n"); |
393 | return -1; | 393 | return -1; |
394 | } | 394 | } |
395 | 395 | ||
@@ -403,7 +403,7 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, | |||
403 | } | 403 | } |
404 | 404 | ||
405 | if (items != items2) { | 405 | if (items != items2) { |
406 | printk("security: avtab: entry only had %d items, expected %d\n", items2, items); | 406 | printk("SELinux: avtab: entry only had %d items, expected %d\n", items2, items); |
407 | return -1; | 407 | return -1; |
408 | } | 408 | } |
409 | return 0; | 409 | return 0; |
@@ -411,7 +411,7 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, | |||
411 | 411 | ||
412 | rc = next_entry(buf16, fp, sizeof(u16)*4); | 412 | rc = next_entry(buf16, fp, sizeof(u16)*4); |
413 | if (rc < 0) { | 413 | if (rc < 0) { |
414 | printk("security: avtab: truncated entry\n"); | 414 | printk("SELinux: avtab: truncated entry\n"); |
415 | return -1; | 415 | return -1; |
416 | } | 416 | } |
417 | 417 | ||
@@ -424,7 +424,7 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, | |||
424 | if (!policydb_type_isvalid(pol, key.source_type) || | 424 | if (!policydb_type_isvalid(pol, key.source_type) || |
425 | !policydb_type_isvalid(pol, key.target_type) || | 425 | !policydb_type_isvalid(pol, key.target_type) || |
426 | !policydb_class_isvalid(pol, key.target_class)) { | 426 | !policydb_class_isvalid(pol, key.target_class)) { |
427 | printk(KERN_WARNING "security: avtab: invalid type or class\n"); | 427 | printk(KERN_WARNING "SELinux: avtab: invalid type or class\n"); |
428 | return -1; | 428 | return -1; |
429 | } | 429 | } |
430 | 430 | ||
@@ -435,19 +435,19 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol, | |||
435 | } | 435 | } |
436 | if (!set || set > 1) { | 436 | if (!set || set > 1) { |
437 | printk(KERN_WARNING | 437 | printk(KERN_WARNING |
438 | "security: avtab: more than one specifier\n"); | 438 | "SELinux: avtab: more than one specifier\n"); |
439 | return -1; | 439 | return -1; |
440 | } | 440 | } |
441 | 441 | ||
442 | rc = next_entry(buf32, fp, sizeof(u32)); | 442 | rc = next_entry(buf32, fp, sizeof(u32)); |
443 | if (rc < 0) { | 443 | if (rc < 0) { |
444 | printk("security: avtab: truncated entry\n"); | 444 | printk("SELinux: avtab: truncated entry\n"); |
445 | return -1; | 445 | return -1; |
446 | } | 446 | } |
447 | datum.data = le32_to_cpu(*buf32); | 447 | datum.data = le32_to_cpu(*buf32); |
448 | if ((key.specified & AVTAB_TYPE) && | 448 | if ((key.specified & AVTAB_TYPE) && |
449 | !policydb_type_isvalid(pol, datum.data)) { | 449 | !policydb_type_isvalid(pol, datum.data)) { |
450 | printk(KERN_WARNING "security: avtab: invalid type\n"); | 450 | printk(KERN_WARNING "SELinux: avtab: invalid type\n"); |
451 | return -1; | 451 | return -1; |
452 | } | 452 | } |
453 | return insertf(a, &key, &datum, p); | 453 | return insertf(a, &key, &datum, p); |
@@ -468,12 +468,12 @@ int avtab_read(struct avtab *a, void *fp, struct policydb *pol) | |||
468 | 468 | ||
469 | rc = next_entry(buf, fp, sizeof(u32)); | 469 | rc = next_entry(buf, fp, sizeof(u32)); |
470 | if (rc < 0) { | 470 | if (rc < 0) { |
471 | printk(KERN_ERR "security: avtab: truncated table\n"); | 471 | printk(KERN_ERR "SELinux: avtab: truncated table\n"); |
472 | goto bad; | 472 | goto bad; |
473 | } | 473 | } |
474 | nel = le32_to_cpu(buf[0]); | 474 | nel = le32_to_cpu(buf[0]); |
475 | if (!nel) { | 475 | if (!nel) { |
476 | printk(KERN_ERR "security: avtab: table is empty\n"); | 476 | printk(KERN_ERR "SELinux: avtab: table is empty\n"); |
477 | rc = -EINVAL; | 477 | rc = -EINVAL; |
478 | goto bad; | 478 | goto bad; |
479 | } | 479 | } |
@@ -486,9 +486,9 @@ int avtab_read(struct avtab *a, void *fp, struct policydb *pol) | |||
486 | rc = avtab_read_item(a, fp, pol, avtab_insertf, NULL); | 486 | rc = avtab_read_item(a, fp, pol, avtab_insertf, NULL); |
487 | if (rc) { | 487 | if (rc) { |
488 | if (rc == -ENOMEM) | 488 | if (rc == -ENOMEM) |
489 | printk(KERN_ERR "security: avtab: out of memory\n"); | 489 | printk(KERN_ERR "SELinux: avtab: out of memory\n"); |
490 | else if (rc == -EEXIST) | 490 | else if (rc == -EEXIST) |
491 | printk(KERN_ERR "security: avtab: duplicate entry\n"); | 491 | printk(KERN_ERR "SELinux: avtab: duplicate entry\n"); |
492 | else | 492 | else |
493 | rc = -EINVAL; | 493 | rc = -EINVAL; |
494 | goto bad; | 494 | goto bad; |
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index 50ad85d4b77c..a996cf1d378a 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c | |||
@@ -96,7 +96,7 @@ int evaluate_cond_node(struct policydb *p, struct cond_node *node) | |||
96 | if (new_state != node->cur_state) { | 96 | if (new_state != node->cur_state) { |
97 | node->cur_state = new_state; | 97 | node->cur_state = new_state; |
98 | if (new_state == -1) | 98 | if (new_state == -1) |
99 | printk(KERN_ERR "security: expression result was undefined - disabling all rules.\n"); | 99 | printk(KERN_ERR "SELinux: expression result was undefined - disabling all rules.\n"); |
100 | /* turn the rules on or off */ | 100 | /* turn the rules on or off */ |
101 | for (cur = node->true_list; cur != NULL; cur = cur->next) { | 101 | for (cur = node->true_list; cur != NULL; cur = cur->next) { |
102 | if (new_state <= 0) { | 102 | if (new_state <= 0) { |
@@ -276,7 +276,7 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum | |||
276 | */ | 276 | */ |
277 | if (k->specified & AVTAB_TYPE) { | 277 | if (k->specified & AVTAB_TYPE) { |
278 | if (avtab_search(&p->te_avtab, k)) { | 278 | if (avtab_search(&p->te_avtab, k)) { |
279 | printk("security: type rule already exists outside of a conditional."); | 279 | printk("SELinux: type rule already exists outside of a conditional."); |
280 | goto err; | 280 | goto err; |
281 | } | 281 | } |
282 | /* | 282 | /* |
@@ -291,7 +291,7 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum | |||
291 | node_ptr = avtab_search_node(&p->te_cond_avtab, k); | 291 | node_ptr = avtab_search_node(&p->te_cond_avtab, k); |
292 | if (node_ptr) { | 292 | if (node_ptr) { |
293 | if (avtab_search_node_next(node_ptr, k->specified)) { | 293 | if (avtab_search_node_next(node_ptr, k->specified)) { |
294 | printk("security: too many conflicting type rules."); | 294 | printk("SELinux: too many conflicting type rules."); |
295 | goto err; | 295 | goto err; |
296 | } | 296 | } |
297 | found = 0; | 297 | found = 0; |
@@ -302,13 +302,13 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum | |||
302 | } | 302 | } |
303 | } | 303 | } |
304 | if (!found) { | 304 | if (!found) { |
305 | printk("security: conflicting type rules.\n"); | 305 | printk("SELinux: conflicting type rules.\n"); |
306 | goto err; | 306 | goto err; |
307 | } | 307 | } |
308 | } | 308 | } |
309 | } else { | 309 | } else { |
310 | if (avtab_search(&p->te_cond_avtab, k)) { | 310 | if (avtab_search(&p->te_cond_avtab, k)) { |
311 | printk("security: conflicting type rules when adding type rule for true.\n"); | 311 | printk("SELinux: conflicting type rules when adding type rule for true.\n"); |
312 | goto err; | 312 | goto err; |
313 | } | 313 | } |
314 | } | 314 | } |
@@ -316,7 +316,7 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum | |||
316 | 316 | ||
317 | node_ptr = avtab_insert_nonunique(&p->te_cond_avtab, k, d); | 317 | node_ptr = avtab_insert_nonunique(&p->te_cond_avtab, k, d); |
318 | if (!node_ptr) { | 318 | if (!node_ptr) { |
319 | printk("security: could not insert rule."); | 319 | printk("SELinux: could not insert rule."); |
320 | goto err; | 320 | goto err; |
321 | } | 321 | } |
322 | 322 | ||
@@ -376,12 +376,12 @@ static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list * | |||
376 | static int expr_isvalid(struct policydb *p, struct cond_expr *expr) | 376 | static int expr_isvalid(struct policydb *p, struct cond_expr *expr) |
377 | { | 377 | { |
378 | if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) { | 378 | if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) { |
379 | printk("security: conditional expressions uses unknown operator.\n"); | 379 | printk("SELinux: conditional expressions uses unknown operator.\n"); |
380 | return 0; | 380 | return 0; |
381 | } | 381 | } |
382 | 382 | ||
383 | if (expr->bool > p->p_bools.nprim) { | 383 | if (expr->bool > p->p_bools.nprim) { |
384 | printk("security: conditional expressions uses unknown bool.\n"); | 384 | printk("SELinux: conditional expressions uses unknown bool.\n"); |
385 | return 0; | 385 | return 0; |
386 | } | 386 | } |
387 | return 1; | 387 | return 1; |
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index 920b5e36a1af..e499af474b35 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c | |||
@@ -364,7 +364,7 @@ int ebitmap_read(struct ebitmap *e, void *fp) | |||
364 | count = le32_to_cpu(buf[2]); | 364 | count = le32_to_cpu(buf[2]); |
365 | 365 | ||
366 | if (mapunit != sizeof(u64) * 8) { | 366 | if (mapunit != sizeof(u64) * 8) { |
367 | printk(KERN_ERR "security: ebitmap: map size %u does not " | 367 | printk(KERN_ERR "SELinux: ebitmap: map size %u does not " |
368 | "match my size %Zd (high bit was %d)\n", | 368 | "match my size %Zd (high bit was %d)\n", |
369 | mapunit, sizeof(u64) * 8, e->highbit); | 369 | mapunit, sizeof(u64) * 8, e->highbit); |
370 | goto bad; | 370 | goto bad; |
@@ -382,19 +382,19 @@ int ebitmap_read(struct ebitmap *e, void *fp) | |||
382 | for (i = 0; i < count; i++) { | 382 | for (i = 0; i < count; i++) { |
383 | rc = next_entry(&startbit, fp, sizeof(u32)); | 383 | rc = next_entry(&startbit, fp, sizeof(u32)); |
384 | if (rc < 0) { | 384 | if (rc < 0) { |
385 | printk(KERN_ERR "security: ebitmap: truncated map\n"); | 385 | printk(KERN_ERR "SELinux: ebitmap: truncated map\n"); |
386 | goto bad; | 386 | goto bad; |
387 | } | 387 | } |
388 | startbit = le32_to_cpu(startbit); | 388 | startbit = le32_to_cpu(startbit); |
389 | 389 | ||
390 | if (startbit & (mapunit - 1)) { | 390 | if (startbit & (mapunit - 1)) { |
391 | printk(KERN_ERR "security: ebitmap start bit (%d) is " | 391 | printk(KERN_ERR "SELinux: ebitmap start bit (%d) is " |
392 | "not a multiple of the map unit size (%u)\n", | 392 | "not a multiple of the map unit size (%u)\n", |
393 | startbit, mapunit); | 393 | startbit, mapunit); |
394 | goto bad; | 394 | goto bad; |
395 | } | 395 | } |
396 | if (startbit > e->highbit - mapunit) { | 396 | if (startbit > e->highbit - mapunit) { |
397 | printk(KERN_ERR "security: ebitmap start bit (%d) is " | 397 | printk(KERN_ERR "SELinux: ebitmap start bit (%d) is " |
398 | "beyond the end of the bitmap (%u)\n", | 398 | "beyond the end of the bitmap (%u)\n", |
399 | startbit, (e->highbit - mapunit)); | 399 | startbit, (e->highbit - mapunit)); |
400 | goto bad; | 400 | goto bad; |
@@ -405,7 +405,7 @@ int ebitmap_read(struct ebitmap *e, void *fp) | |||
405 | tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); | 405 | tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); |
406 | if (!tmp) { | 406 | if (!tmp) { |
407 | printk(KERN_ERR | 407 | printk(KERN_ERR |
408 | "security: ebitmap: out of memory\n"); | 408 | "SELinux: ebitmap: out of memory\n"); |
409 | rc = -ENOMEM; | 409 | rc = -ENOMEM; |
410 | goto bad; | 410 | goto bad; |
411 | } | 411 | } |
@@ -418,7 +418,7 @@ int ebitmap_read(struct ebitmap *e, void *fp) | |||
418 | } | 418 | } |
419 | n = tmp; | 419 | n = tmp; |
420 | } else if (startbit <= n->startbit) { | 420 | } else if (startbit <= n->startbit) { |
421 | printk(KERN_ERR "security: ebitmap: start bit %d" | 421 | printk(KERN_ERR "SELinux: ebitmap: start bit %d" |
422 | " comes after start bit %d\n", | 422 | " comes after start bit %d\n", |
423 | startbit, n->startbit); | 423 | startbit, n->startbit); |
424 | goto bad; | 424 | goto bad; |
@@ -426,7 +426,7 @@ int ebitmap_read(struct ebitmap *e, void *fp) | |||
426 | 426 | ||
427 | rc = next_entry(&map, fp, sizeof(u64)); | 427 | rc = next_entry(&map, fp, sizeof(u64)); |
428 | if (rc < 0) { | 428 | if (rc < 0) { |
429 | printk(KERN_ERR "security: ebitmap: truncated map\n"); | 429 | printk(KERN_ERR "SELinux: ebitmap: truncated map\n"); |
430 | goto bad; | 430 | goto bad; |
431 | } | 431 | } |
432 | map = le64_to_cpu(map); | 432 | map = le64_to_cpu(map); |
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index bd7d6a00342d..6bdb0ff6a927 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
@@ -111,6 +111,11 @@ static struct policydb_compat_info policydb_compat[] = { | |||
111 | .version = POLICYDB_VERSION_POLCAP, | 111 | .version = POLICYDB_VERSION_POLCAP, |
112 | .sym_num = SYM_NUM, | 112 | .sym_num = SYM_NUM, |
113 | .ocon_num = OCON_NUM, | 113 | .ocon_num = OCON_NUM, |
114 | }, | ||
115 | { | ||
116 | .version = POLICYDB_VERSION_PERMISSIVE, | ||
117 | .sym_num = SYM_NUM, | ||
118 | .ocon_num = OCON_NUM, | ||
114 | } | 119 | } |
115 | }; | 120 | }; |
116 | 121 | ||
@@ -194,6 +199,7 @@ static int policydb_init(struct policydb *p) | |||
194 | goto out_free_symtab; | 199 | goto out_free_symtab; |
195 | 200 | ||
196 | ebitmap_init(&p->policycaps); | 201 | ebitmap_init(&p->policycaps); |
202 | ebitmap_init(&p->permissive_map); | ||
197 | 203 | ||
198 | out: | 204 | out: |
199 | return rc; | 205 | return rc; |
@@ -401,14 +407,14 @@ static int policydb_index_others(struct policydb *p) | |||
401 | { | 407 | { |
402 | int i, rc = 0; | 408 | int i, rc = 0; |
403 | 409 | ||
404 | printk(KERN_DEBUG "security: %d users, %d roles, %d types, %d bools", | 410 | printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools", |
405 | p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); | 411 | p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); |
406 | if (selinux_mls_enabled) | 412 | if (selinux_mls_enabled) |
407 | printk(", %d sens, %d cats", p->p_levels.nprim, | 413 | printk(", %d sens, %d cats", p->p_levels.nprim, |
408 | p->p_cats.nprim); | 414 | p->p_cats.nprim); |
409 | printk("\n"); | 415 | printk("\n"); |
410 | 416 | ||
411 | printk(KERN_DEBUG "security: %d classes, %d rules\n", | 417 | printk(KERN_DEBUG "SELinux: %d classes, %d rules\n", |
412 | p->p_classes.nprim, p->te_avtab.nel); | 418 | p->p_classes.nprim, p->te_avtab.nel); |
413 | 419 | ||
414 | #ifdef DEBUG_HASHES | 420 | #ifdef DEBUG_HASHES |
@@ -687,6 +693,7 @@ void policydb_destroy(struct policydb *p) | |||
687 | kfree(p->type_attr_map); | 693 | kfree(p->type_attr_map); |
688 | kfree(p->undefined_perms); | 694 | kfree(p->undefined_perms); |
689 | ebitmap_destroy(&p->policycaps); | 695 | ebitmap_destroy(&p->policycaps); |
696 | ebitmap_destroy(&p->permissive_map); | ||
690 | 697 | ||
691 | return; | 698 | return; |
692 | } | 699 | } |
@@ -702,20 +709,20 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s) | |||
702 | 709 | ||
703 | rc = sidtab_init(s); | 710 | rc = sidtab_init(s); |
704 | if (rc) { | 711 | if (rc) { |
705 | printk(KERN_ERR "security: out of memory on SID table init\n"); | 712 | printk(KERN_ERR "SELinux: out of memory on SID table init\n"); |
706 | goto out; | 713 | goto out; |
707 | } | 714 | } |
708 | 715 | ||
709 | head = p->ocontexts[OCON_ISID]; | 716 | head = p->ocontexts[OCON_ISID]; |
710 | for (c = head; c; c = c->next) { | 717 | for (c = head; c; c = c->next) { |
711 | if (!c->context[0].user) { | 718 | if (!c->context[0].user) { |
712 | printk(KERN_ERR "security: SID %s was never " | 719 | printk(KERN_ERR "SELinux: SID %s was never " |
713 | "defined.\n", c->u.name); | 720 | "defined.\n", c->u.name); |
714 | rc = -EINVAL; | 721 | rc = -EINVAL; |
715 | goto out; | 722 | goto out; |
716 | } | 723 | } |
717 | if (sidtab_insert(s, c->sid[0], &c->context[0])) { | 724 | if (sidtab_insert(s, c->sid[0], &c->context[0])) { |
718 | printk(KERN_ERR "security: unable to load initial " | 725 | printk(KERN_ERR "SELinux: unable to load initial " |
719 | "SID %s.\n", c->u.name); | 726 | "SID %s.\n", c->u.name); |
720 | rc = -EINVAL; | 727 | rc = -EINVAL; |
721 | goto out; | 728 | goto out; |
@@ -809,13 +816,13 @@ static int mls_read_range_helper(struct mls_range *r, void *fp) | |||
809 | 816 | ||
810 | items = le32_to_cpu(buf[0]); | 817 | items = le32_to_cpu(buf[0]); |
811 | if (items > ARRAY_SIZE(buf)) { | 818 | if (items > ARRAY_SIZE(buf)) { |
812 | printk(KERN_ERR "security: mls: range overflow\n"); | 819 | printk(KERN_ERR "SELinux: mls: range overflow\n"); |
813 | rc = -EINVAL; | 820 | rc = -EINVAL; |
814 | goto out; | 821 | goto out; |
815 | } | 822 | } |
816 | rc = next_entry(buf, fp, sizeof(u32) * items); | 823 | rc = next_entry(buf, fp, sizeof(u32) * items); |
817 | if (rc < 0) { | 824 | if (rc < 0) { |
818 | printk(KERN_ERR "security: mls: truncated range\n"); | 825 | printk(KERN_ERR "SELinux: mls: truncated range\n"); |
819 | goto out; | 826 | goto out; |
820 | } | 827 | } |
821 | r->level[0].sens = le32_to_cpu(buf[0]); | 828 | r->level[0].sens = le32_to_cpu(buf[0]); |
@@ -826,21 +833,21 @@ static int mls_read_range_helper(struct mls_range *r, void *fp) | |||
826 | 833 | ||
827 | rc = ebitmap_read(&r->level[0].cat, fp); | 834 | rc = ebitmap_read(&r->level[0].cat, fp); |
828 | if (rc) { | 835 | if (rc) { |
829 | printk(KERN_ERR "security: mls: error reading low " | 836 | printk(KERN_ERR "SELinux: mls: error reading low " |
830 | "categories\n"); | 837 | "categories\n"); |
831 | goto out; | 838 | goto out; |
832 | } | 839 | } |
833 | if (items > 1) { | 840 | if (items > 1) { |
834 | rc = ebitmap_read(&r->level[1].cat, fp); | 841 | rc = ebitmap_read(&r->level[1].cat, fp); |
835 | if (rc) { | 842 | if (rc) { |
836 | printk(KERN_ERR "security: mls: error reading high " | 843 | printk(KERN_ERR "SELinux: mls: error reading high " |
837 | "categories\n"); | 844 | "categories\n"); |
838 | goto bad_high; | 845 | goto bad_high; |
839 | } | 846 | } |
840 | } else { | 847 | } else { |
841 | rc = ebitmap_cpy(&r->level[1].cat, &r->level[0].cat); | 848 | rc = ebitmap_cpy(&r->level[1].cat, &r->level[0].cat); |
842 | if (rc) { | 849 | if (rc) { |
843 | printk(KERN_ERR "security: mls: out of memory\n"); | 850 | printk(KERN_ERR "SELinux: mls: out of memory\n"); |
844 | goto bad_high; | 851 | goto bad_high; |
845 | } | 852 | } |
846 | } | 853 | } |
@@ -866,7 +873,7 @@ static int context_read_and_validate(struct context *c, | |||
866 | 873 | ||
867 | rc = next_entry(buf, fp, sizeof buf); | 874 | rc = next_entry(buf, fp, sizeof buf); |
868 | if (rc < 0) { | 875 | if (rc < 0) { |
869 | printk(KERN_ERR "security: context truncated\n"); | 876 | printk(KERN_ERR "SELinux: context truncated\n"); |
870 | goto out; | 877 | goto out; |
871 | } | 878 | } |
872 | c->user = le32_to_cpu(buf[0]); | 879 | c->user = le32_to_cpu(buf[0]); |
@@ -874,7 +881,7 @@ static int context_read_and_validate(struct context *c, | |||
874 | c->type = le32_to_cpu(buf[2]); | 881 | c->type = le32_to_cpu(buf[2]); |
875 | if (p->policyvers >= POLICYDB_VERSION_MLS) { | 882 | if (p->policyvers >= POLICYDB_VERSION_MLS) { |
876 | if (mls_read_range_helper(&c->range, fp)) { | 883 | if (mls_read_range_helper(&c->range, fp)) { |
877 | printk(KERN_ERR "security: error reading MLS range of " | 884 | printk(KERN_ERR "SELinux: error reading MLS range of " |
878 | "context\n"); | 885 | "context\n"); |
879 | rc = -EINVAL; | 886 | rc = -EINVAL; |
880 | goto out; | 887 | goto out; |
@@ -882,7 +889,7 @@ static int context_read_and_validate(struct context *c, | |||
882 | } | 889 | } |
883 | 890 | ||
884 | if (!policydb_context_isvalid(p, c)) { | 891 | if (!policydb_context_isvalid(p, c)) { |
885 | printk(KERN_ERR "security: invalid security context\n"); | 892 | printk(KERN_ERR "SELinux: invalid security context\n"); |
886 | context_destroy(c); | 893 | context_destroy(c); |
887 | rc = -EINVAL; | 894 | rc = -EINVAL; |
888 | } | 895 | } |
@@ -1128,7 +1135,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1128 | cladatum->comdatum = hashtab_search(p->p_commons.table, | 1135 | cladatum->comdatum = hashtab_search(p->p_commons.table, |
1129 | cladatum->comkey); | 1136 | cladatum->comkey); |
1130 | if (!cladatum->comdatum) { | 1137 | if (!cladatum->comdatum) { |
1131 | printk(KERN_ERR "security: unknown common %s\n", | 1138 | printk(KERN_ERR "SELinux: unknown common %s\n", |
1132 | cladatum->comkey); | 1139 | cladatum->comkey); |
1133 | rc = -EINVAL; | 1140 | rc = -EINVAL; |
1134 | goto bad; | 1141 | goto bad; |
@@ -1283,13 +1290,13 @@ static int mls_read_level(struct mls_level *lp, void *fp) | |||
1283 | 1290 | ||
1284 | rc = next_entry(buf, fp, sizeof buf); | 1291 | rc = next_entry(buf, fp, sizeof buf); |
1285 | if (rc < 0) { | 1292 | if (rc < 0) { |
1286 | printk(KERN_ERR "security: mls: truncated level\n"); | 1293 | printk(KERN_ERR "SELinux: mls: truncated level\n"); |
1287 | goto bad; | 1294 | goto bad; |
1288 | } | 1295 | } |
1289 | lp->sens = le32_to_cpu(buf[0]); | 1296 | lp->sens = le32_to_cpu(buf[0]); |
1290 | 1297 | ||
1291 | if (ebitmap_read(&lp->cat, fp)) { | 1298 | if (ebitmap_read(&lp->cat, fp)) { |
1292 | printk(KERN_ERR "security: mls: error reading level " | 1299 | printk(KERN_ERR "SELinux: mls: error reading level " |
1293 | "categories\n"); | 1300 | "categories\n"); |
1294 | goto bad; | 1301 | goto bad; |
1295 | } | 1302 | } |
@@ -1491,7 +1498,7 @@ int policydb_read(struct policydb *p, void *fp) | |||
1491 | goto bad; | 1498 | goto bad; |
1492 | 1499 | ||
1493 | if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) { | 1500 | if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) { |
1494 | printk(KERN_ERR "security: policydb magic number 0x%x does " | 1501 | printk(KERN_ERR "SELinux: policydb magic number 0x%x does " |
1495 | "not match expected magic number 0x%x\n", | 1502 | "not match expected magic number 0x%x\n", |
1496 | le32_to_cpu(buf[0]), POLICYDB_MAGIC); | 1503 | le32_to_cpu(buf[0]), POLICYDB_MAGIC); |
1497 | goto bad; | 1504 | goto bad; |
@@ -1499,27 +1506,27 @@ int policydb_read(struct policydb *p, void *fp) | |||
1499 | 1506 | ||
1500 | len = le32_to_cpu(buf[1]); | 1507 | len = le32_to_cpu(buf[1]); |
1501 | if (len != strlen(POLICYDB_STRING)) { | 1508 | if (len != strlen(POLICYDB_STRING)) { |
1502 | printk(KERN_ERR "security: policydb string length %d does not " | 1509 | printk(KERN_ERR "SELinux: policydb string length %d does not " |
1503 | "match expected length %Zu\n", | 1510 | "match expected length %Zu\n", |
1504 | len, strlen(POLICYDB_STRING)); | 1511 | len, strlen(POLICYDB_STRING)); |
1505 | goto bad; | 1512 | goto bad; |
1506 | } | 1513 | } |
1507 | policydb_str = kmalloc(len + 1,GFP_KERNEL); | 1514 | policydb_str = kmalloc(len + 1,GFP_KERNEL); |
1508 | if (!policydb_str) { | 1515 | if (!policydb_str) { |
1509 | printk(KERN_ERR "security: unable to allocate memory for policydb " | 1516 | printk(KERN_ERR "SELinux: unable to allocate memory for policydb " |
1510 | "string of length %d\n", len); | 1517 | "string of length %d\n", len); |
1511 | rc = -ENOMEM; | 1518 | rc = -ENOMEM; |
1512 | goto bad; | 1519 | goto bad; |
1513 | } | 1520 | } |
1514 | rc = next_entry(policydb_str, fp, len); | 1521 | rc = next_entry(policydb_str, fp, len); |
1515 | if (rc < 0) { | 1522 | if (rc < 0) { |
1516 | printk(KERN_ERR "security: truncated policydb string identifier\n"); | 1523 | printk(KERN_ERR "SELinux: truncated policydb string identifier\n"); |
1517 | kfree(policydb_str); | 1524 | kfree(policydb_str); |
1518 | goto bad; | 1525 | goto bad; |
1519 | } | 1526 | } |
1520 | policydb_str[len] = 0; | 1527 | policydb_str[len] = 0; |
1521 | if (strcmp(policydb_str, POLICYDB_STRING)) { | 1528 | if (strcmp(policydb_str, POLICYDB_STRING)) { |
1522 | printk(KERN_ERR "security: policydb string %s does not match " | 1529 | printk(KERN_ERR "SELinux: policydb string %s does not match " |
1523 | "my string %s\n", policydb_str, POLICYDB_STRING); | 1530 | "my string %s\n", policydb_str, POLICYDB_STRING); |
1524 | kfree(policydb_str); | 1531 | kfree(policydb_str); |
1525 | goto bad; | 1532 | goto bad; |
@@ -1536,7 +1543,7 @@ int policydb_read(struct policydb *p, void *fp) | |||
1536 | p->policyvers = le32_to_cpu(buf[0]); | 1543 | p->policyvers = le32_to_cpu(buf[0]); |
1537 | if (p->policyvers < POLICYDB_VERSION_MIN || | 1544 | if (p->policyvers < POLICYDB_VERSION_MIN || |
1538 | p->policyvers > POLICYDB_VERSION_MAX) { | 1545 | p->policyvers > POLICYDB_VERSION_MAX) { |
1539 | printk(KERN_ERR "security: policydb version %d does not match " | 1546 | printk(KERN_ERR "SELinux: policydb version %d does not match " |
1540 | "my version range %d-%d\n", | 1547 | "my version range %d-%d\n", |
1541 | le32_to_cpu(buf[0]), POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); | 1548 | le32_to_cpu(buf[0]), POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); |
1542 | goto bad; | 1549 | goto bad; |
@@ -1570,16 +1577,20 @@ int policydb_read(struct policydb *p, void *fp) | |||
1570 | ebitmap_read(&p->policycaps, fp) != 0) | 1577 | ebitmap_read(&p->policycaps, fp) != 0) |
1571 | goto bad; | 1578 | goto bad; |
1572 | 1579 | ||
1580 | if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && | ||
1581 | ebitmap_read(&p->permissive_map, fp) != 0) | ||
1582 | goto bad; | ||
1583 | |||
1573 | info = policydb_lookup_compat(p->policyvers); | 1584 | info = policydb_lookup_compat(p->policyvers); |
1574 | if (!info) { | 1585 | if (!info) { |
1575 | printk(KERN_ERR "security: unable to find policy compat info " | 1586 | printk(KERN_ERR "SELinux: unable to find policy compat info " |
1576 | "for version %d\n", p->policyvers); | 1587 | "for version %d\n", p->policyvers); |
1577 | goto bad; | 1588 | goto bad; |
1578 | } | 1589 | } |
1579 | 1590 | ||
1580 | if (le32_to_cpu(buf[2]) != info->sym_num || | 1591 | if (le32_to_cpu(buf[2]) != info->sym_num || |
1581 | le32_to_cpu(buf[3]) != info->ocon_num) { | 1592 | le32_to_cpu(buf[3]) != info->ocon_num) { |
1582 | printk(KERN_ERR "security: policydb table sizes (%d,%d) do " | 1593 | printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do " |
1583 | "not match mine (%d,%d)\n", le32_to_cpu(buf[2]), | 1594 | "not match mine (%d,%d)\n", le32_to_cpu(buf[2]), |
1584 | le32_to_cpu(buf[3]), | 1595 | le32_to_cpu(buf[3]), |
1585 | info->sym_num, info->ocon_num); | 1596 | info->sym_num, info->ocon_num); |
@@ -1823,7 +1834,7 @@ int policydb_read(struct policydb *p, void *fp) | |||
1823 | for (genfs_p = NULL, genfs = p->genfs; genfs; | 1834 | for (genfs_p = NULL, genfs = p->genfs; genfs; |
1824 | genfs_p = genfs, genfs = genfs->next) { | 1835 | genfs_p = genfs, genfs = genfs->next) { |
1825 | if (strcmp(newgenfs->fstype, genfs->fstype) == 0) { | 1836 | if (strcmp(newgenfs->fstype, genfs->fstype) == 0) { |
1826 | printk(KERN_ERR "security: dup genfs " | 1837 | printk(KERN_ERR "SELinux: dup genfs " |
1827 | "fstype %s\n", newgenfs->fstype); | 1838 | "fstype %s\n", newgenfs->fstype); |
1828 | kfree(newgenfs->fstype); | 1839 | kfree(newgenfs->fstype); |
1829 | kfree(newgenfs); | 1840 | kfree(newgenfs); |
@@ -1873,7 +1884,7 @@ int policydb_read(struct policydb *p, void *fp) | |||
1873 | if (!strcmp(newc->u.name, c->u.name) && | 1884 | if (!strcmp(newc->u.name, c->u.name) && |
1874 | (!c->v.sclass || !newc->v.sclass || | 1885 | (!c->v.sclass || !newc->v.sclass || |
1875 | newc->v.sclass == c->v.sclass)) { | 1886 | newc->v.sclass == c->v.sclass)) { |
1876 | printk(KERN_ERR "security: dup genfs " | 1887 | printk(KERN_ERR "SELinux: dup genfs " |
1877 | "entry (%s,%s)\n", | 1888 | "entry (%s,%s)\n", |
1878 | newgenfs->fstype, c->u.name); | 1889 | newgenfs->fstype, c->u.name); |
1879 | goto bad_newc; | 1890 | goto bad_newc; |
@@ -1931,7 +1942,7 @@ int policydb_read(struct policydb *p, void *fp) | |||
1931 | if (rc) | 1942 | if (rc) |
1932 | goto bad; | 1943 | goto bad; |
1933 | if (!mls_range_isvalid(p, &rt->target_range)) { | 1944 | if (!mls_range_isvalid(p, &rt->target_range)) { |
1934 | printk(KERN_WARNING "security: rangetrans: invalid range\n"); | 1945 | printk(KERN_WARNING "SELinux: rangetrans: invalid range\n"); |
1935 | goto bad; | 1946 | goto bad; |
1936 | } | 1947 | } |
1937 | lrt = rt; | 1948 | lrt = rt; |
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index c4ce996e202c..ba593a3da877 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h | |||
@@ -243,6 +243,8 @@ struct policydb { | |||
243 | 243 | ||
244 | struct ebitmap policycaps; | 244 | struct ebitmap policycaps; |
245 | 245 | ||
246 | struct ebitmap permissive_map; | ||
247 | |||
246 | unsigned int policyvers; | 248 | unsigned int policyvers; |
247 | 249 | ||
248 | unsigned int reject_unknown : 1; | 250 | unsigned int reject_unknown : 1; |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 5fd54f2bbaac..33425b1ac8d6 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/sched.h> | 40 | #include <linux/sched.h> |
41 | #include <linux/audit.h> | 41 | #include <linux/audit.h> |
42 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
43 | #include <linux/selinux.h> | ||
43 | #include <net/netlabel.h> | 44 | #include <net/netlabel.h> |
44 | 45 | ||
45 | #include "flask.h" | 46 | #include "flask.h" |
@@ -61,6 +62,7 @@ extern void selnl_notify_policyload(u32 seqno); | |||
61 | unsigned int policydb_loaded_version; | 62 | unsigned int policydb_loaded_version; |
62 | 63 | ||
63 | int selinux_policycap_netpeer; | 64 | int selinux_policycap_netpeer; |
65 | int selinux_policycap_openperm; | ||
64 | 66 | ||
65 | /* | 67 | /* |
66 | * This is declared in avc.c | 68 | * This is declared in avc.c |
@@ -412,10 +414,35 @@ static int context_struct_compute_av(struct context *scontext, | |||
412 | return 0; | 414 | return 0; |
413 | 415 | ||
414 | inval_class: | 416 | inval_class: |
415 | printk(KERN_ERR "%s: unrecognized class %d\n", __FUNCTION__, tclass); | 417 | printk(KERN_ERR "%s: unrecognized class %d\n", __func__, tclass); |
416 | return -EINVAL; | 418 | return -EINVAL; |
417 | } | 419 | } |
418 | 420 | ||
421 | /* | ||
422 | * Given a sid find if the type has the permissive flag set | ||
423 | */ | ||
424 | int security_permissive_sid(u32 sid) | ||
425 | { | ||
426 | struct context *context; | ||
427 | u32 type; | ||
428 | int rc; | ||
429 | |||
430 | POLICY_RDLOCK; | ||
431 | |||
432 | context = sidtab_search(&sidtab, sid); | ||
433 | BUG_ON(!context); | ||
434 | |||
435 | type = context->type; | ||
436 | /* | ||
437 | * we are intentionally using type here, not type-1, the 0th bit may | ||
438 | * someday indicate that we are globally setting permissive in policy. | ||
439 | */ | ||
440 | rc = ebitmap_get_bit(&policydb.permissive_map, type); | ||
441 | |||
442 | POLICY_RDUNLOCK; | ||
443 | return rc; | ||
444 | } | ||
445 | |||
419 | static int security_validtrans_handle_fail(struct context *ocontext, | 446 | static int security_validtrans_handle_fail(struct context *ocontext, |
420 | struct context *ncontext, | 447 | struct context *ncontext, |
421 | struct context *tcontext, | 448 | struct context *tcontext, |
@@ -1096,7 +1123,7 @@ static int validate_classes(struct policydb *p) | |||
1096 | continue; | 1123 | continue; |
1097 | if (i > p->p_classes.nprim) { | 1124 | if (i > p->p_classes.nprim) { |
1098 | printk(KERN_INFO | 1125 | printk(KERN_INFO |
1099 | "security: class %s not defined in policy\n", | 1126 | "SELinux: class %s not defined in policy\n", |
1100 | def_class); | 1127 | def_class); |
1101 | if (p->reject_unknown) | 1128 | if (p->reject_unknown) |
1102 | return -EINVAL; | 1129 | return -EINVAL; |
@@ -1107,7 +1134,7 @@ static int validate_classes(struct policydb *p) | |||
1107 | pol_class = p->p_class_val_to_name[i-1]; | 1134 | pol_class = p->p_class_val_to_name[i-1]; |
1108 | if (strcmp(pol_class, def_class)) { | 1135 | if (strcmp(pol_class, def_class)) { |
1109 | printk(KERN_ERR | 1136 | printk(KERN_ERR |
1110 | "security: class %d is incorrect, found %s but should be %s\n", | 1137 | "SELinux: class %d is incorrect, found %s but should be %s\n", |
1111 | i, pol_class, def_class); | 1138 | i, pol_class, def_class); |
1112 | return -EINVAL; | 1139 | return -EINVAL; |
1113 | } | 1140 | } |
@@ -1125,7 +1152,7 @@ static int validate_classes(struct policydb *p) | |||
1125 | nprim = 1 << (perms->nprim - 1); | 1152 | nprim = 1 << (perms->nprim - 1); |
1126 | if (perm_val > nprim) { | 1153 | if (perm_val > nprim) { |
1127 | printk(KERN_INFO | 1154 | printk(KERN_INFO |
1128 | "security: permission %s in class %s not defined in policy\n", | 1155 | "SELinux: permission %s in class %s not defined in policy\n", |
1129 | def_perm, pol_class); | 1156 | def_perm, pol_class); |
1130 | if (p->reject_unknown) | 1157 | if (p->reject_unknown) |
1131 | return -EINVAL; | 1158 | return -EINVAL; |
@@ -1136,14 +1163,14 @@ static int validate_classes(struct policydb *p) | |||
1136 | perdatum = hashtab_search(perms->table, def_perm); | 1163 | perdatum = hashtab_search(perms->table, def_perm); |
1137 | if (perdatum == NULL) { | 1164 | if (perdatum == NULL) { |
1138 | printk(KERN_ERR | 1165 | printk(KERN_ERR |
1139 | "security: permission %s in class %s not found in policy, bad policy\n", | 1166 | "SELinux: permission %s in class %s not found in policy, bad policy\n", |
1140 | def_perm, pol_class); | 1167 | def_perm, pol_class); |
1141 | return -EINVAL; | 1168 | return -EINVAL; |
1142 | } | 1169 | } |
1143 | pol_val = 1 << (perdatum->value - 1); | 1170 | pol_val = 1 << (perdatum->value - 1); |
1144 | if (pol_val != perm_val) { | 1171 | if (pol_val != perm_val) { |
1145 | printk(KERN_ERR | 1172 | printk(KERN_ERR |
1146 | "security: permission %s in class %s has incorrect value\n", | 1173 | "SELinux: permission %s in class %s has incorrect value\n", |
1147 | def_perm, pol_class); | 1174 | def_perm, pol_class); |
1148 | return -EINVAL; | 1175 | return -EINVAL; |
1149 | } | 1176 | } |
@@ -1157,7 +1184,7 @@ static int validate_classes(struct policydb *p) | |||
1157 | BUG_ON(!cladatum); | 1184 | BUG_ON(!cladatum); |
1158 | if (!cladatum->comdatum) { | 1185 | if (!cladatum->comdatum) { |
1159 | printk(KERN_ERR | 1186 | printk(KERN_ERR |
1160 | "security: class %s should have an inherits clause but does not\n", | 1187 | "SELinux: class %s should have an inherits clause but does not\n", |
1161 | pol_class); | 1188 | pol_class); |
1162 | return -EINVAL; | 1189 | return -EINVAL; |
1163 | } | 1190 | } |
@@ -1172,7 +1199,7 @@ static int validate_classes(struct policydb *p) | |||
1172 | def_perm = kdefs->av_inherit[i].common_pts[j]; | 1199 | def_perm = kdefs->av_inherit[i].common_pts[j]; |
1173 | if (j >= perms->nprim) { | 1200 | if (j >= perms->nprim) { |
1174 | printk(KERN_INFO | 1201 | printk(KERN_INFO |
1175 | "security: permission %s in class %s not defined in policy\n", | 1202 | "SELinux: permission %s in class %s not defined in policy\n", |
1176 | def_perm, pol_class); | 1203 | def_perm, pol_class); |
1177 | if (p->reject_unknown) | 1204 | if (p->reject_unknown) |
1178 | return -EINVAL; | 1205 | return -EINVAL; |
@@ -1183,13 +1210,13 @@ static int validate_classes(struct policydb *p) | |||
1183 | perdatum = hashtab_search(perms->table, def_perm); | 1210 | perdatum = hashtab_search(perms->table, def_perm); |
1184 | if (perdatum == NULL) { | 1211 | if (perdatum == NULL) { |
1185 | printk(KERN_ERR | 1212 | printk(KERN_ERR |
1186 | "security: permission %s in class %s not found in policy, bad policy\n", | 1213 | "SELinux: permission %s in class %s not found in policy, bad policy\n", |
1187 | def_perm, pol_class); | 1214 | def_perm, pol_class); |
1188 | return -EINVAL; | 1215 | return -EINVAL; |
1189 | } | 1216 | } |
1190 | if (perdatum->value != j + 1) { | 1217 | if (perdatum->value != j + 1) { |
1191 | printk(KERN_ERR | 1218 | printk(KERN_ERR |
1192 | "security: permission %s in class %s has incorrect value\n", | 1219 | "SELinux: permission %s in class %s has incorrect value\n", |
1193 | def_perm, pol_class); | 1220 | def_perm, pol_class); |
1194 | return -EINVAL; | 1221 | return -EINVAL; |
1195 | } | 1222 | } |
@@ -1219,7 +1246,7 @@ static inline int convert_context_handle_invalid_context(struct context *context | |||
1219 | u32 len; | 1246 | u32 len; |
1220 | 1247 | ||
1221 | context_struct_to_string(context, &s, &len); | 1248 | context_struct_to_string(context, &s, &len); |
1222 | printk(KERN_ERR "security: context %s is invalid\n", s); | 1249 | printk(KERN_ERR "SELinux: context %s is invalid\n", s); |
1223 | kfree(s); | 1250 | kfree(s); |
1224 | } | 1251 | } |
1225 | return rc; | 1252 | return rc; |
@@ -1299,7 +1326,7 @@ out: | |||
1299 | bad: | 1326 | bad: |
1300 | context_struct_to_string(&oldc, &s, &len); | 1327 | context_struct_to_string(&oldc, &s, &len); |
1301 | context_destroy(&oldc); | 1328 | context_destroy(&oldc); |
1302 | printk(KERN_ERR "security: invalidating context %s\n", s); | 1329 | printk(KERN_ERR "SELinux: invalidating context %s\n", s); |
1303 | kfree(s); | 1330 | kfree(s); |
1304 | goto out; | 1331 | goto out; |
1305 | } | 1332 | } |
@@ -1308,6 +1335,8 @@ static void security_load_policycaps(void) | |||
1308 | { | 1335 | { |
1309 | selinux_policycap_netpeer = ebitmap_get_bit(&policydb.policycaps, | 1336 | selinux_policycap_netpeer = ebitmap_get_bit(&policydb.policycaps, |
1310 | POLICYDB_CAPABILITY_NETPEER); | 1337 | POLICYDB_CAPABILITY_NETPEER); |
1338 | selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, | ||
1339 | POLICYDB_CAPABILITY_OPENPERM); | ||
1311 | } | 1340 | } |
1312 | 1341 | ||
1313 | extern void selinux_complete_init(void); | 1342 | extern void selinux_complete_init(void); |
@@ -1350,7 +1379,7 @@ int security_load_policy(void *data, size_t len) | |||
1350 | /* Verify that the kernel defined classes are correct. */ | 1379 | /* Verify that the kernel defined classes are correct. */ |
1351 | if (validate_classes(&policydb)) { | 1380 | if (validate_classes(&policydb)) { |
1352 | printk(KERN_ERR | 1381 | printk(KERN_ERR |
1353 | "security: the definition of a class is incorrect\n"); | 1382 | "SELinux: the definition of a class is incorrect\n"); |
1354 | LOAD_UNLOCK; | 1383 | LOAD_UNLOCK; |
1355 | sidtab_destroy(&sidtab); | 1384 | sidtab_destroy(&sidtab); |
1356 | policydb_destroy(&policydb); | 1385 | policydb_destroy(&policydb); |
@@ -1384,14 +1413,14 @@ int security_load_policy(void *data, size_t len) | |||
1384 | /* Verify that the kernel defined classes are correct. */ | 1413 | /* Verify that the kernel defined classes are correct. */ |
1385 | if (validate_classes(&newpolicydb)) { | 1414 | if (validate_classes(&newpolicydb)) { |
1386 | printk(KERN_ERR | 1415 | printk(KERN_ERR |
1387 | "security: the definition of a class is incorrect\n"); | 1416 | "SELinux: the definition of a class is incorrect\n"); |
1388 | rc = -EINVAL; | 1417 | rc = -EINVAL; |
1389 | goto err; | 1418 | goto err; |
1390 | } | 1419 | } |
1391 | 1420 | ||
1392 | rc = security_preserve_bools(&newpolicydb); | 1421 | rc = security_preserve_bools(&newpolicydb); |
1393 | if (rc) { | 1422 | if (rc) { |
1394 | printk(KERN_ERR "security: unable to preserve booleans\n"); | 1423 | printk(KERN_ERR "SELinux: unable to preserve booleans\n"); |
1395 | goto err; | 1424 | goto err; |
1396 | } | 1425 | } |
1397 | 1426 | ||
@@ -1443,17 +1472,11 @@ err: | |||
1443 | 1472 | ||
1444 | /** | 1473 | /** |
1445 | * security_port_sid - Obtain the SID for a port. | 1474 | * security_port_sid - Obtain the SID for a port. |
1446 | * @domain: communication domain aka address family | ||
1447 | * @type: socket type | ||
1448 | * @protocol: protocol number | 1475 | * @protocol: protocol number |
1449 | * @port: port number | 1476 | * @port: port number |
1450 | * @out_sid: security identifier | 1477 | * @out_sid: security identifier |
1451 | */ | 1478 | */ |
1452 | int security_port_sid(u16 domain, | 1479 | int security_port_sid(u8 protocol, u16 port, u32 *out_sid) |
1453 | u16 type, | ||
1454 | u8 protocol, | ||
1455 | u16 port, | ||
1456 | u32 *out_sid) | ||
1457 | { | 1480 | { |
1458 | struct ocontext *c; | 1481 | struct ocontext *c; |
1459 | int rc = 0; | 1482 | int rc = 0; |
@@ -2203,7 +2226,7 @@ int security_get_permissions(char *class, char ***perms, int *nperms) | |||
2203 | match = hashtab_search(policydb.p_classes.table, class); | 2226 | match = hashtab_search(policydb.p_classes.table, class); |
2204 | if (!match) { | 2227 | if (!match) { |
2205 | printk(KERN_ERR "%s: unrecognized class %s\n", | 2228 | printk(KERN_ERR "%s: unrecognized class %s\n", |
2206 | __FUNCTION__, class); | 2229 | __func__, class); |
2207 | rc = -EINVAL; | 2230 | rc = -EINVAL; |
2208 | goto out; | 2231 | goto out; |
2209 | } | 2232 | } |