diff options
| -rw-r--r-- | security/selinux/hooks.c | 15 | ||||
| -rw-r--r-- | security/selinux/include/security.h | 8 | ||||
| -rw-r--r-- | security/selinux/ss/avtab.h | 22 | ||||
| -rw-r--r-- | security/selinux/ss/policydb.c | 130 | ||||
| -rw-r--r-- | security/selinux/ss/policydb.h | 14 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 45 |
6 files changed, 197 insertions, 37 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 099bbd07732f..6ae19fd28be5 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -1301,10 +1301,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
| 1301 | 1301 | ||
| 1302 | /* Try to obtain a transition SID. */ | 1302 | /* Try to obtain a transition SID. */ |
| 1303 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 1303 | isec->sclass = inode_mode_to_security_class(inode->i_mode); |
| 1304 | rc = security_transition_sid(isec->task_sid, | 1304 | rc = security_transition_sid(isec->task_sid, sbsec->sid, |
| 1305 | sbsec->sid, | 1305 | isec->sclass, NULL, &sid); |
| 1306 | isec->sclass, | ||
| 1307 | &sid); | ||
| 1308 | if (rc) | 1306 | if (rc) |
| 1309 | goto out_unlock; | 1307 | goto out_unlock; |
| 1310 | isec->sid = sid; | 1308 | isec->sid = sid; |
| @@ -1579,7 +1577,7 @@ static int may_create(struct inode *dir, | |||
| 1579 | return rc; | 1577 | return rc; |
| 1580 | 1578 | ||
| 1581 | if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { | 1579 | if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { |
| 1582 | rc = security_transition_sid(sid, dsec->sid, tclass, &newsid); | 1580 | rc = security_transition_sid(sid, dsec->sid, tclass, NULL, &newsid); |
| 1583 | if (rc) | 1581 | if (rc) |
| 1584 | return rc; | 1582 | return rc; |
| 1585 | } | 1583 | } |
| @@ -2061,7 +2059,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
| 2061 | } else { | 2059 | } else { |
| 2062 | /* Check for a default transition on this program. */ | 2060 | /* Check for a default transition on this program. */ |
| 2063 | rc = security_transition_sid(old_tsec->sid, isec->sid, | 2061 | rc = security_transition_sid(old_tsec->sid, isec->sid, |
| 2064 | SECCLASS_PROCESS, &new_tsec->sid); | 2062 | SECCLASS_PROCESS, NULL, |
| 2063 | &new_tsec->sid); | ||
| 2065 | if (rc) | 2064 | if (rc) |
| 2066 | return rc; | 2065 | return rc; |
| 2067 | } | 2066 | } |
| @@ -2532,7 +2531,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
| 2532 | else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { | 2531 | else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { |
| 2533 | rc = security_transition_sid(sid, dsec->sid, | 2532 | rc = security_transition_sid(sid, dsec->sid, |
| 2534 | inode_mode_to_security_class(inode->i_mode), | 2533 | inode_mode_to_security_class(inode->i_mode), |
| 2535 | &newsid); | 2534 | qstr, &newsid); |
| 2536 | if (rc) { | 2535 | if (rc) { |
| 2537 | printk(KERN_WARNING "%s: " | 2536 | printk(KERN_WARNING "%s: " |
| 2538 | "security_transition_sid failed, rc=%d (dev=%s " | 2537 | "security_transition_sid failed, rc=%d (dev=%s " |
| @@ -4845,7 +4844,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
| 4845 | * message queue this message will be stored in | 4844 | * message queue this message will be stored in |
| 4846 | */ | 4845 | */ |
| 4847 | rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG, | 4846 | rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG, |
| 4848 | &msec->sid); | 4847 | NULL, &msec->sid); |
| 4849 | if (rc) | 4848 | if (rc) |
| 4850 | return rc; | 4849 | return rc; |
| 4851 | } | 4850 | } |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 671273eb1115..348eb00cb668 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #ifndef _SELINUX_SECURITY_H_ | 8 | #ifndef _SELINUX_SECURITY_H_ |
| 9 | #define _SELINUX_SECURITY_H_ | 9 | #define _SELINUX_SECURITY_H_ |
| 10 | 10 | ||
| 11 | #include <linux/dcache.h> | ||
| 11 | #include <linux/magic.h> | 12 | #include <linux/magic.h> |
| 12 | #include <linux/types.h> | 13 | #include <linux/types.h> |
| 13 | #include "flask.h" | 14 | #include "flask.h" |
| @@ -28,13 +29,14 @@ | |||
| 28 | #define POLICYDB_VERSION_POLCAP 22 | 29 | #define POLICYDB_VERSION_POLCAP 22 |
| 29 | #define POLICYDB_VERSION_PERMISSIVE 23 | 30 | #define POLICYDB_VERSION_PERMISSIVE 23 |
| 30 | #define POLICYDB_VERSION_BOUNDARY 24 | 31 | #define POLICYDB_VERSION_BOUNDARY 24 |
| 32 | #define POLICYDB_VERSION_FILENAME_TRANS 25 | ||
| 31 | 33 | ||
| 32 | /* Range of policy versions we understand*/ | 34 | /* Range of policy versions we understand*/ |
| 33 | #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE | 35 | #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE |
| 34 | #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX | 36 | #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX |
| 35 | #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE | 37 | #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE |
| 36 | #else | 38 | #else |
| 37 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_BOUNDARY | 39 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_FILENAME_TRANS |
| 38 | #endif | 40 | #endif |
| 39 | 41 | ||
| 40 | /* Mask for just the mount related flags */ | 42 | /* Mask for just the mount related flags */ |
| @@ -106,8 +108,8 @@ void security_compute_av(u32 ssid, u32 tsid, | |||
| 106 | void security_compute_av_user(u32 ssid, u32 tsid, | 108 | void security_compute_av_user(u32 ssid, u32 tsid, |
| 107 | u16 tclass, struct av_decision *avd); | 109 | u16 tclass, struct av_decision *avd); |
| 108 | 110 | ||
| 109 | int security_transition_sid(u32 ssid, u32 tsid, | 111 | int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, |
| 110 | u16 tclass, u32 *out_sid); | 112 | const struct qstr *qstr, u32 *out_sid); |
| 111 | 113 | ||
| 112 | int security_transition_sid_user(u32 ssid, u32 tsid, | 114 | int security_transition_sid_user(u32 ssid, u32 tsid, |
| 113 | u16 tclass, u32 *out_sid); | 115 | u16 tclass, u32 *out_sid); |
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index 3417f9cc1cbd..63ce2f9e441d 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | * | 14 | * |
| 15 | * Copyright (C) 2003 Tresys Technology, LLC | 15 | * Copyright (C) 2003 Tresys Technology, LLC |
| 16 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
| 17 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
| 18 | * the Free Software Foundation, version 2. | 18 | * the Free Software Foundation, version 2. |
| 19 | * | 19 | * |
| 20 | * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp> | 20 | * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp> |
| @@ -27,16 +27,16 @@ struct avtab_key { | |||
| 27 | u16 source_type; /* source type */ | 27 | u16 source_type; /* source type */ |
| 28 | u16 target_type; /* target type */ | 28 | u16 target_type; /* target type */ |
| 29 | u16 target_class; /* target object class */ | 29 | u16 target_class; /* target object class */ |
| 30 | #define AVTAB_ALLOWED 1 | 30 | #define AVTAB_ALLOWED 0x0001 |
| 31 | #define AVTAB_AUDITALLOW 2 | 31 | #define AVTAB_AUDITALLOW 0x0002 |
| 32 | #define AVTAB_AUDITDENY 4 | 32 | #define AVTAB_AUDITDENY 0x0004 |
| 33 | #define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY) | 33 | #define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY) |
| 34 | #define AVTAB_TRANSITION 16 | 34 | #define AVTAB_TRANSITION 0x0010 |
| 35 | #define AVTAB_MEMBER 32 | 35 | #define AVTAB_MEMBER 0x0020 |
| 36 | #define AVTAB_CHANGE 64 | 36 | #define AVTAB_CHANGE 0x0040 |
| 37 | #define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) | 37 | #define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) |
| 38 | #define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */ | 38 | #define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */ |
| 39 | #define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ | 39 | #define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ |
| 40 | u16 specified; /* what field is specified */ | 40 | u16 specified; /* what field is specified */ |
| 41 | }; | 41 | }; |
| 42 | 42 | ||
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index be9de3872837..159c81806760 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
| @@ -123,6 +123,11 @@ static struct policydb_compat_info policydb_compat[] = { | |||
| 123 | .sym_num = SYM_NUM, | 123 | .sym_num = SYM_NUM, |
| 124 | .ocon_num = OCON_NUM, | 124 | .ocon_num = OCON_NUM, |
| 125 | }, | 125 | }, |
| 126 | { | ||
| 127 | .version = POLICYDB_VERSION_FILENAME_TRANS, | ||
| 128 | .sym_num = SYM_NUM, | ||
| 129 | .ocon_num = OCON_NUM, | ||
| 130 | }, | ||
| 126 | }; | 131 | }; |
| 127 | 132 | ||
| 128 | static struct policydb_compat_info *policydb_lookup_compat(int version) | 133 | static struct policydb_compat_info *policydb_lookup_compat(int version) |
| @@ -704,6 +709,7 @@ void policydb_destroy(struct policydb *p) | |||
| 704 | int i; | 709 | int i; |
| 705 | struct role_allow *ra, *lra = NULL; | 710 | struct role_allow *ra, *lra = NULL; |
| 706 | struct role_trans *tr, *ltr = NULL; | 711 | struct role_trans *tr, *ltr = NULL; |
| 712 | struct filename_trans *ft, *nft; | ||
| 707 | 713 | ||
| 708 | for (i = 0; i < SYM_NUM; i++) { | 714 | for (i = 0; i < SYM_NUM; i++) { |
| 709 | cond_resched(); | 715 | cond_resched(); |
| @@ -781,6 +787,15 @@ void policydb_destroy(struct policydb *p) | |||
| 781 | } | 787 | } |
| 782 | flex_array_free(p->type_attr_map_array); | 788 | flex_array_free(p->type_attr_map_array); |
| 783 | } | 789 | } |
| 790 | |||
| 791 | ft = p->filename_trans; | ||
| 792 | while (ft) { | ||
| 793 | nft = ft->next; | ||
| 794 | kfree(ft->name); | ||
| 795 | kfree(ft); | ||
| 796 | ft = nft; | ||
| 797 | } | ||
| 798 | |||
| 784 | ebitmap_destroy(&p->policycaps); | 799 | ebitmap_destroy(&p->policycaps); |
| 785 | ebitmap_destroy(&p->permissive_map); | 800 | ebitmap_destroy(&p->permissive_map); |
| 786 | 801 | ||
| @@ -1788,6 +1803,76 @@ out: | |||
| 1788 | return rc; | 1803 | return rc; |
| 1789 | } | 1804 | } |
| 1790 | 1805 | ||
| 1806 | static int filename_trans_read(struct policydb *p, void *fp) | ||
| 1807 | { | ||
| 1808 | struct filename_trans *ft, *last; | ||
| 1809 | u32 nel, len; | ||
| 1810 | char *name; | ||
| 1811 | __le32 buf[4]; | ||
| 1812 | int rc, i; | ||
| 1813 | |||
| 1814 | if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS) | ||
| 1815 | return 0; | ||
| 1816 | |||
| 1817 | rc = next_entry(buf, fp, sizeof(u32)); | ||
| 1818 | if (rc) | ||
| 1819 | goto out; | ||
| 1820 | nel = le32_to_cpu(buf[0]); | ||
| 1821 | |||
| 1822 | printk(KERN_ERR "%s: nel=%d\n", __func__, nel); | ||
| 1823 | |||
| 1824 | last = p->filename_trans; | ||
| 1825 | while (last && last->next) | ||
| 1826 | last = last->next; | ||
| 1827 | |||
| 1828 | for (i = 0; i < nel; i++) { | ||
| 1829 | rc = -ENOMEM; | ||
| 1830 | ft = kzalloc(sizeof(*ft), GFP_KERNEL); | ||
| 1831 | if (!ft) | ||
| 1832 | goto out; | ||
| 1833 | |||
| 1834 | /* add it to the tail of the list */ | ||
| 1835 | if (!last) | ||
| 1836 | p->filename_trans = ft; | ||
| 1837 | else | ||
| 1838 | last->next = ft; | ||
| 1839 | last = ft; | ||
| 1840 | |||
| 1841 | /* length of the path component string */ | ||
| 1842 | rc = next_entry(buf, fp, sizeof(u32)); | ||
| 1843 | if (rc) | ||
| 1844 | goto out; | ||
| 1845 | len = le32_to_cpu(buf[0]); | ||
| 1846 | |||
| 1847 | rc = -ENOMEM; | ||
| 1848 | name = kmalloc(len + 1, GFP_KERNEL); | ||
| 1849 | if (!name) | ||
| 1850 | goto out; | ||
| 1851 | |||
| 1852 | ft->name = name; | ||
| 1853 | |||
| 1854 | /* path component string */ | ||
| 1855 | rc = next_entry(name, fp, len); | ||
| 1856 | if (rc) | ||
| 1857 | goto out; | ||
| 1858 | name[len] = 0; | ||
| 1859 | |||
| 1860 | printk(KERN_ERR "%s: ft=%p ft->name=%p ft->name=%s\n", __func__, ft, ft->name, ft->name); | ||
| 1861 | |||
| 1862 | rc = next_entry(buf, fp, sizeof(u32) * 4); | ||
| 1863 | if (rc) | ||
| 1864 | goto out; | ||
| 1865 | |||
| 1866 | ft->stype = le32_to_cpu(buf[0]); | ||
| 1867 | ft->ttype = le32_to_cpu(buf[1]); | ||
| 1868 | ft->tclass = le32_to_cpu(buf[2]); | ||
| 1869 | ft->otype = le32_to_cpu(buf[3]); | ||
| 1870 | } | ||
| 1871 | rc = 0; | ||
| 1872 | out: | ||
| 1873 | return rc; | ||
| 1874 | } | ||
| 1875 | |||
| 1791 | static int genfs_read(struct policydb *p, void *fp) | 1876 | static int genfs_read(struct policydb *p, void *fp) |
| 1792 | { | 1877 | { |
| 1793 | int i, j, rc; | 1878 | int i, j, rc; |
| @@ -2251,6 +2336,10 @@ int policydb_read(struct policydb *p, void *fp) | |||
| 2251 | lra = ra; | 2336 | lra = ra; |
| 2252 | } | 2337 | } |
| 2253 | 2338 | ||
| 2339 | rc = filename_trans_read(p, fp); | ||
| 2340 | if (rc) | ||
| 2341 | goto bad; | ||
| 2342 | |||
| 2254 | rc = policydb_index(p); | 2343 | rc = policydb_index(p); |
| 2255 | if (rc) | 2344 | if (rc) |
| 2256 | goto bad; | 2345 | goto bad; |
| @@ -3025,6 +3114,43 @@ static int range_write(struct policydb *p, void *fp) | |||
| 3025 | return 0; | 3114 | return 0; |
| 3026 | } | 3115 | } |
| 3027 | 3116 | ||
| 3117 | static int filename_trans_write(struct policydb *p, void *fp) | ||
| 3118 | { | ||
| 3119 | struct filename_trans *ft; | ||
| 3120 | u32 len, nel = 0; | ||
| 3121 | __le32 buf[4]; | ||
| 3122 | int rc; | ||
| 3123 | |||
| 3124 | for (ft = p->filename_trans; ft; ft = ft->next) | ||
| 3125 | nel++; | ||
| 3126 | |||
| 3127 | buf[0] = cpu_to_le32(nel); | ||
| 3128 | rc = put_entry(buf, sizeof(u32), 1, fp); | ||
| 3129 | if (rc) | ||
| 3130 | return rc; | ||
| 3131 | |||
| 3132 | for (ft = p->filename_trans; ft; ft = ft->next) { | ||
| 3133 | len = strlen(ft->name); | ||
| 3134 | buf[0] = cpu_to_le32(len); | ||
| 3135 | rc = put_entry(buf, sizeof(u32), 1, fp); | ||
| 3136 | if (rc) | ||
| 3137 | return rc; | ||
| 3138 | |||
| 3139 | rc = put_entry(ft->name, sizeof(char), len, fp); | ||
| 3140 | if (rc) | ||
| 3141 | return rc; | ||
| 3142 | |||
| 3143 | buf[0] = ft->stype; | ||
| 3144 | buf[1] = ft->ttype; | ||
| 3145 | buf[2] = ft->tclass; | ||
| 3146 | buf[3] = ft->otype; | ||
| 3147 | |||
| 3148 | rc = put_entry(buf, sizeof(u32), 4, fp); | ||
| 3149 | if (rc) | ||
| 3150 | return rc; | ||
| 3151 | } | ||
| 3152 | return 0; | ||
| 3153 | } | ||
| 3028 | /* | 3154 | /* |
| 3029 | * Write the configuration data in a policy database | 3155 | * Write the configuration data in a policy database |
| 3030 | * structure to a policy database binary representation | 3156 | * structure to a policy database binary representation |
| @@ -3135,6 +3261,10 @@ int policydb_write(struct policydb *p, void *fp) | |||
| 3135 | if (rc) | 3261 | if (rc) |
| 3136 | return rc; | 3262 | return rc; |
| 3137 | 3263 | ||
| 3264 | rc = filename_trans_write(p, fp); | ||
| 3265 | if (rc) | ||
| 3266 | return rc; | ||
| 3267 | |||
| 3138 | rc = ocontext_write(p, info, fp); | 3268 | rc = ocontext_write(p, info, fp); |
| 3139 | if (rc) | 3269 | if (rc) |
| 3140 | return rc; | 3270 | return rc; |
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index 4e3ab9d0b315..732ea4a68682 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h | |||
| @@ -77,6 +77,15 @@ struct role_trans { | |||
| 77 | struct role_trans *next; | 77 | struct role_trans *next; |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | struct filename_trans { | ||
| 81 | struct filename_trans *next; | ||
| 82 | u32 stype; /* current process */ | ||
| 83 | u32 ttype; /* parent dir context */ | ||
| 84 | u16 tclass; /* class of new object */ | ||
| 85 | const char *name; /* last path component */ | ||
| 86 | u32 otype; /* expected of new object */ | ||
| 87 | }; | ||
| 88 | |||
| 80 | struct role_allow { | 89 | struct role_allow { |
| 81 | u32 role; /* current role */ | 90 | u32 role; /* current role */ |
| 82 | u32 new_role; /* new role */ | 91 | u32 new_role; /* new role */ |
| @@ -217,6 +226,9 @@ struct policydb { | |||
| 217 | /* role transitions */ | 226 | /* role transitions */ |
| 218 | struct role_trans *role_tr; | 227 | struct role_trans *role_tr; |
| 219 | 228 | ||
| 229 | /* file transitions with the last path component */ | ||
| 230 | struct filename_trans *filename_trans; | ||
| 231 | |||
| 220 | /* bools indexed by (value - 1) */ | 232 | /* bools indexed by (value - 1) */ |
| 221 | struct cond_bool_datum **bool_val_to_struct; | 233 | struct cond_bool_datum **bool_val_to_struct; |
| 222 | /* type enforcement conditional access vectors and transitions */ | 234 | /* type enforcement conditional access vectors and transitions */ |
| @@ -302,7 +314,7 @@ static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes) | |||
| 302 | return 0; | 314 | return 0; |
| 303 | } | 315 | } |
| 304 | 316 | ||
| 305 | static inline int put_entry(void *buf, size_t bytes, int num, struct policy_file *fp) | 317 | static inline int put_entry(const void *buf, size_t bytes, int num, struct policy_file *fp) |
| 306 | { | 318 | { |
| 307 | size_t len = bytes * num; | 319 | size_t len = bytes * num; |
| 308 | 320 | ||
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index a03cfaf0ee07..2e36e03c21f2 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
| @@ -1343,10 +1343,27 @@ out: | |||
| 1343 | return -EACCES; | 1343 | return -EACCES; |
| 1344 | } | 1344 | } |
| 1345 | 1345 | ||
| 1346 | static void filename_compute_type(struct policydb *p, struct context *newcontext, | ||
| 1347 | u32 scon, u32 tcon, u16 tclass, | ||
| 1348 | const struct qstr *qstr) | ||
| 1349 | { | ||
| 1350 | struct filename_trans *ft; | ||
| 1351 | for (ft = p->filename_trans; ft; ft = ft->next) { | ||
| 1352 | if (ft->stype == scon && | ||
| 1353 | ft->ttype == tcon && | ||
| 1354 | ft->tclass == tclass && | ||
| 1355 | !strcmp(ft->name, qstr->name)) { | ||
| 1356 | newcontext->type = ft->otype; | ||
| 1357 | return; | ||
| 1358 | } | ||
| 1359 | } | ||
| 1360 | } | ||
| 1361 | |||
| 1346 | static int security_compute_sid(u32 ssid, | 1362 | static int security_compute_sid(u32 ssid, |
| 1347 | u32 tsid, | 1363 | u32 tsid, |
| 1348 | u16 orig_tclass, | 1364 | u16 orig_tclass, |
| 1349 | u32 specified, | 1365 | u32 specified, |
| 1366 | const struct qstr *qstr, | ||
| 1350 | u32 *out_sid, | 1367 | u32 *out_sid, |
| 1351 | bool kern) | 1368 | bool kern) |
| 1352 | { | 1369 | { |
| @@ -1442,6 +1459,11 @@ static int security_compute_sid(u32 ssid, | |||
| 1442 | newcontext.type = avdatum->data; | 1459 | newcontext.type = avdatum->data; |
| 1443 | } | 1460 | } |
| 1444 | 1461 | ||
| 1462 | /* if we have a qstr this is a file trans check so check those rules */ | ||
| 1463 | if (qstr) | ||
| 1464 | filename_compute_type(&policydb, &newcontext, scontext->type, | ||
| 1465 | tcontext->type, tclass, qstr); | ||
| 1466 | |||
| 1445 | /* Check for class-specific changes. */ | 1467 | /* Check for class-specific changes. */ |
| 1446 | if (tclass == policydb.process_class) { | 1468 | if (tclass == policydb.process_class) { |
| 1447 | if (specified & AVTAB_TRANSITION) { | 1469 | if (specified & AVTAB_TRANSITION) { |
| @@ -1495,22 +1517,17 @@ out: | |||
| 1495 | * if insufficient memory is available, or %0 if the new SID was | 1517 | * if insufficient memory is available, or %0 if the new SID was |
| 1496 | * computed successfully. | 1518 | * computed successfully. |
| 1497 | */ | 1519 | */ |
| 1498 | int security_transition_sid(u32 ssid, | 1520 | int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, |
| 1499 | u32 tsid, | 1521 | const struct qstr *qstr, u32 *out_sid) |
| 1500 | u16 tclass, | ||
| 1501 | u32 *out_sid) | ||
| 1502 | { | 1522 | { |
| 1503 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, | 1523 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, |
| 1504 | out_sid, true); | 1524 | qstr, out_sid, true); |
| 1505 | } | 1525 | } |
| 1506 | 1526 | ||
| 1507 | int security_transition_sid_user(u32 ssid, | 1527 | int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid) |
| 1508 | u32 tsid, | ||
| 1509 | u16 tclass, | ||
| 1510 | u32 *out_sid) | ||
| 1511 | { | 1528 | { |
| 1512 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, | 1529 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, |
| 1513 | out_sid, false); | 1530 | NULL, out_sid, false); |
| 1514 | } | 1531 | } |
| 1515 | 1532 | ||
| 1516 | /** | 1533 | /** |
| @@ -1531,8 +1548,8 @@ int security_member_sid(u32 ssid, | |||
| 1531 | u16 tclass, | 1548 | u16 tclass, |
| 1532 | u32 *out_sid) | 1549 | u32 *out_sid) |
| 1533 | { | 1550 | { |
| 1534 | return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid, | 1551 | return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, NULL, |
| 1535 | false); | 1552 | out_sid, false); |
| 1536 | } | 1553 | } |
| 1537 | 1554 | ||
| 1538 | /** | 1555 | /** |
| @@ -1553,8 +1570,8 @@ int security_change_sid(u32 ssid, | |||
| 1553 | u16 tclass, | 1570 | u16 tclass, |
| 1554 | u32 *out_sid) | 1571 | u32 *out_sid) |
| 1555 | { | 1572 | { |
| 1556 | return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid, | 1573 | return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, NULL, |
| 1557 | false); | 1574 | out_sid, false); |
| 1558 | } | 1575 | } |
| 1559 | 1576 | ||
| 1560 | /* Clone the SID into the new SID table. */ | 1577 | /* Clone the SID into the new SID table. */ |
