Commit b7b57551bbda1390959207f79f2038aa7adb72ae

Authored by James Morris

Merge branch 'master' of git://git.infradead.org/users/eparis/selinux into for-linus

Conflicts:
	lib/flex_array.c
	security/selinux/avc.c
	security/selinux/hooks.c
	security/selinux/ss/policydb.c
	security/smack/smack_lsm.c

Manually resolve conflicts.

Signed-off-by: James Morris <jmorris@namei.org>

Showing 14 changed files Side-by-side Diff

... ... @@ -5592,10 +5592,11 @@
5592 5592 M: Eric Paris <eparis@parisplace.org>
5593 5593 L: selinux@tycho.nsa.gov (subscribers-only, general discussion)
5594 5594 W: http://selinuxproject.org
5595   -T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
  5595 +T: git git://git.infradead.org/users/eparis/selinux.git
5596 5596 S: Supported
5597 5597 F: include/linux/selinux*
5598 5598 F: security/selinux/
  5599 +F: scripts/selinux/
5599 5600  
5600 5601 APPARMOR SECURITY MODULE
5601 5602 M: John Johansen <john.johansen@canonical.com>
include/linux/lsm_audit.h
... ... @@ -27,7 +27,7 @@
27 27 /* Auxiliary data to use in generating the audit record. */
28 28 struct common_audit_data {
29 29 char type;
30   -#define LSM_AUDIT_DATA_FS 1
  30 +#define LSM_AUDIT_DATA_PATH 1
31 31 #define LSM_AUDIT_DATA_NET 2
32 32 #define LSM_AUDIT_DATA_CAP 3
33 33 #define LSM_AUDIT_DATA_IPC 4
34 34  
... ... @@ -35,12 +35,13 @@
35 35 #define LSM_AUDIT_DATA_KEY 6
36 36 #define LSM_AUDIT_DATA_NONE 7
37 37 #define LSM_AUDIT_DATA_KMOD 8
  38 +#define LSM_AUDIT_DATA_INODE 9
  39 +#define LSM_AUDIT_DATA_DENTRY 10
38 40 struct task_struct *tsk;
39 41 union {
40   - struct {
41   - struct path path;
42   - struct inode *inode;
43   - } fs;
  42 + struct path path;
  43 + struct dentry *dentry;
  44 + struct inode *inode;
44 45 struct {
45 46 int netif;
46 47 struct sock *sk;
... ... @@ -88,9 +88,12 @@
88 88 gfp_t flags)
89 89 {
90 90 struct flex_array *ret;
91   - int max_size = FLEX_ARRAY_NR_BASE_PTRS *
92   - FLEX_ARRAY_ELEMENTS_PER_PART(element_size);
  91 + int max_size = 0;
93 92  
  93 + if (element_size)
  94 + max_size = FLEX_ARRAY_NR_BASE_PTRS *
  95 + FLEX_ARRAY_ELEMENTS_PER_PART(element_size);
  96 +
94 97 /* max_size will end up 0 if element_size > PAGE_SIZE */
95 98 if (total > max_size)
96 99 return NULL;
97 100  
98 101  
... ... @@ -183,15 +186,18 @@
183 186 int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src,
184 187 gfp_t flags)
185 188 {
186   - int part_nr = fa_element_to_part_nr(fa, element_nr);
  189 + int part_nr;
187 190 struct flex_array_part *part;
188 191 void *dst;
189 192  
190 193 if (element_nr >= fa->total_nr_elements)
191 194 return -ENOSPC;
  195 + if (!fa->element_size)
  196 + return 0;
192 197 if (elements_fit_in_base(fa))
193 198 part = (struct flex_array_part *)&fa->parts[0];
194 199 else {
  200 + part_nr = fa_element_to_part_nr(fa, element_nr);
195 201 part = __fa_get_part(fa, part_nr, flags);
196 202 if (!part)
197 203 return -ENOMEM;
198 204  
199 205  
... ... @@ -211,15 +217,18 @@
211 217 */
212 218 int flex_array_clear(struct flex_array *fa, unsigned int element_nr)
213 219 {
214   - int part_nr = fa_element_to_part_nr(fa, element_nr);
  220 + int part_nr;
215 221 struct flex_array_part *part;
216 222 void *dst;
217 223  
218 224 if (element_nr >= fa->total_nr_elements)
219 225 return -ENOSPC;
  226 + if (!fa->element_size)
  227 + return 0;
220 228 if (elements_fit_in_base(fa))
221 229 part = (struct flex_array_part *)&fa->parts[0];
222 230 else {
  231 + part_nr = fa_element_to_part_nr(fa, element_nr);
223 232 part = fa->parts[part_nr];
224 233 if (!part)
225 234 return -EINVAL;
... ... @@ -264,6 +273,8 @@
264 273  
265 274 if (end >= fa->total_nr_elements)
266 275 return -ENOSPC;
  276 + if (!fa->element_size)
  277 + return 0;
267 278 if (elements_fit_in_base(fa))
268 279 return 0;
269 280 start_part = fa_element_to_part_nr(fa, start);
270 281  
271 282  
... ... @@ -291,14 +302,17 @@
291 302 */
292 303 void *flex_array_get(struct flex_array *fa, unsigned int element_nr)
293 304 {
294   - int part_nr = fa_element_to_part_nr(fa, element_nr);
  305 + int part_nr;
295 306 struct flex_array_part *part;
296 307  
  308 + if (!fa->element_size)
  309 + return NULL;
297 310 if (element_nr >= fa->total_nr_elements)
298 311 return NULL;
299 312 if (elements_fit_in_base(fa))
300 313 part = (struct flex_array_part *)&fa->parts[0];
301 314 else {
  315 + part_nr = fa_element_to_part_nr(fa, element_nr);
302 316 part = fa->parts[part_nr];
303 317 if (!part)
304 318 return NULL;
... ... @@ -353,7 +367,7 @@
353 367 int part_nr;
354 368 int ret = 0;
355 369  
356   - if (!fa->total_nr_elements)
  370 + if (!fa->total_nr_elements || !fa->element_size)
357 371 return 0;
358 372 if (elements_fit_in_base(fa))
359 373 return ret;
security/lsm_audit.c
... ... @@ -210,7 +210,6 @@
210 210 static void dump_common_audit_data(struct audit_buffer *ab,
211 211 struct common_audit_data *a)
212 212 {
213   - struct inode *inode = NULL;
214 213 struct task_struct *tsk = current;
215 214  
216 215 if (a->tsk)
217 216  
... ... @@ -229,33 +228,47 @@
229 228 case LSM_AUDIT_DATA_CAP:
230 229 audit_log_format(ab, " capability=%d ", a->u.cap);
231 230 break;
232   - case LSM_AUDIT_DATA_FS:
233   - if (a->u.fs.path.dentry) {
234   - struct dentry *dentry = a->u.fs.path.dentry;
235   - if (a->u.fs.path.mnt) {
236   - audit_log_d_path(ab, "path=", &a->u.fs.path);
237   - } else {
238   - audit_log_format(ab, " name=");
239   - audit_log_untrustedstring(ab,
240   - dentry->d_name.name);
241   - }
242   - inode = dentry->d_inode;
243   - } else if (a->u.fs.inode) {
244   - struct dentry *dentry;
245   - inode = a->u.fs.inode;
246   - dentry = d_find_alias(inode);
247   - if (dentry) {
248   - audit_log_format(ab, " name=");
249   - audit_log_untrustedstring(ab,
250   - dentry->d_name.name);
251   - dput(dentry);
252   - }
253   - }
  231 + case LSM_AUDIT_DATA_PATH: {
  232 + struct inode *inode;
  233 +
  234 + audit_log_d_path(ab, "path=", &a->u.path);
  235 +
  236 + inode = a->u.path.dentry->d_inode;
254 237 if (inode)
255 238 audit_log_format(ab, " dev=%s ino=%lu",
256 239 inode->i_sb->s_id,
257 240 inode->i_ino);
258 241 break;
  242 + }
  243 + case LSM_AUDIT_DATA_DENTRY: {
  244 + struct inode *inode;
  245 +
  246 + audit_log_format(ab, " name=");
  247 + audit_log_untrustedstring(ab, a->u.dentry->d_name.name);
  248 +
  249 + inode = a->u.dentry->d_inode;
  250 + if (inode)
  251 + audit_log_format(ab, " dev=%s ino=%lu",
  252 + inode->i_sb->s_id,
  253 + inode->i_ino);
  254 + break;
  255 + }
  256 + case LSM_AUDIT_DATA_INODE: {
  257 + struct dentry *dentry;
  258 + struct inode *inode;
  259 +
  260 + inode = a->u.inode;
  261 + dentry = d_find_alias(inode);
  262 + if (dentry) {
  263 + audit_log_format(ab, " name=");
  264 + audit_log_untrustedstring(ab,
  265 + dentry->d_name.name);
  266 + dput(dentry);
  267 + }
  268 + audit_log_format(ab, " dev=%s ino=%lu", inode->i_sb->s_id,
  269 + inode->i_ino);
  270 + break;
  271 + }
259 272 case LSM_AUDIT_DATA_TASK:
260 273 tsk = a->u.tsk;
261 274 if (tsk && tsk->pid) {
security/selinux/avc.c
... ... @@ -526,7 +526,7 @@
526 526 * during retry. However this is logically just as if the operation
527 527 * happened a little later.
528 528 */
529   - if ((a->type == LSM_AUDIT_DATA_FS) &&
  529 + if ((a->type == LSM_AUDIT_DATA_INODE) &&
530 530 (flags & IPERM_FLAG_RCU))
531 531 return -ECHILD;
532 532  
security/selinux/hooks.c
... ... @@ -990,6 +990,7 @@
990 990 continue;
991 991 default:
992 992 BUG();
  993 + return;
993 994 };
994 995 /* we need a comma before each option */
995 996 seq_putc(m, ',');
... ... @@ -1443,6 +1444,7 @@
1443 1444 printk(KERN_ERR
1444 1445 "SELinux: out of range capability %d\n", cap);
1445 1446 BUG();
  1447 + return -EINVAL;
1446 1448 }
1447 1449  
1448 1450 rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd);
... ... @@ -1487,8 +1489,8 @@
1487 1489  
1488 1490 if (!adp) {
1489 1491 adp = &ad;
1490   - COMMON_AUDIT_DATA_INIT(&ad, FS);
1491   - ad.u.fs.inode = inode;
  1492 + COMMON_AUDIT_DATA_INIT(&ad, INODE);
  1493 + ad.u.inode = inode;
1492 1494 }
1493 1495  
1494 1496 return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
1495 1497  
1496 1498  
... ... @@ -1498,19 +1500,32 @@
1498 1500 the dentry to help the auditing code to more easily generate the
1499 1501 pathname if needed. */
1500 1502 static inline int dentry_has_perm(const struct cred *cred,
1501   - struct vfsmount *mnt,
1502 1503 struct dentry *dentry,
1503 1504 u32 av)
1504 1505 {
1505 1506 struct inode *inode = dentry->d_inode;
1506 1507 struct common_audit_data ad;
1507 1508  
1508   - COMMON_AUDIT_DATA_INIT(&ad, FS);
1509   - ad.u.fs.path.mnt = mnt;
1510   - ad.u.fs.path.dentry = dentry;
  1509 + COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
  1510 + ad.u.dentry = dentry;
1511 1511 return inode_has_perm(cred, inode, av, &ad, 0);
1512 1512 }
1513 1513  
  1514 +/* Same as inode_has_perm, but pass explicit audit data containing
  1515 + the path to help the auditing code to more easily generate the
  1516 + pathname if needed. */
  1517 +static inline int path_has_perm(const struct cred *cred,
  1518 + struct path *path,
  1519 + u32 av)
  1520 +{
  1521 + struct inode *inode = path->dentry->d_inode;
  1522 + struct common_audit_data ad;
  1523 +
  1524 + COMMON_AUDIT_DATA_INIT(&ad, PATH);
  1525 + ad.u.path = *path;
  1526 + return inode_has_perm(cred, inode, av, &ad, 0);
  1527 +}
  1528 +
1514 1529 /* Check whether a task can use an open file descriptor to
1515 1530 access an inode in a given way. Check access to the
1516 1531 descriptor itself, and then use dentry_has_perm to
... ... @@ -1529,8 +1544,8 @@
1529 1544 u32 sid = cred_sid(cred);
1530 1545 int rc;
1531 1546  
1532   - COMMON_AUDIT_DATA_INIT(&ad, FS);
1533   - ad.u.fs.path = file->f_path;
  1547 + COMMON_AUDIT_DATA_INIT(&ad, PATH);
  1548 + ad.u.path = file->f_path;
1534 1549  
1535 1550 if (sid != fsec->sid) {
1536 1551 rc = avc_has_perm(sid, fsec->sid,
... ... @@ -1568,8 +1583,8 @@
1568 1583 sid = tsec->sid;
1569 1584 newsid = tsec->create_sid;
1570 1585  
1571   - COMMON_AUDIT_DATA_INIT(&ad, FS);
1572   - ad.u.fs.path.dentry = dentry;
  1586 + COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
  1587 + ad.u.dentry = dentry;
1573 1588  
1574 1589 rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
1575 1590 DIR__ADD_NAME | DIR__SEARCH,
... ... @@ -1621,8 +1636,8 @@
1621 1636 dsec = dir->i_security;
1622 1637 isec = dentry->d_inode->i_security;
1623 1638  
1624   - COMMON_AUDIT_DATA_INIT(&ad, FS);
1625   - ad.u.fs.path.dentry = dentry;
  1639 + COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
  1640 + ad.u.dentry = dentry;
1626 1641  
1627 1642 av = DIR__SEARCH;
1628 1643 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
1629 1644  
... ... @@ -1667,9 +1682,9 @@
1667 1682 old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
1668 1683 new_dsec = new_dir->i_security;
1669 1684  
1670   - COMMON_AUDIT_DATA_INIT(&ad, FS);
  1685 + COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1671 1686  
1672   - ad.u.fs.path.dentry = old_dentry;
  1687 + ad.u.dentry = old_dentry;
1673 1688 rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
1674 1689 DIR__REMOVE_NAME | DIR__SEARCH, &ad);
1675 1690 if (rc)
... ... @@ -1685,7 +1700,7 @@
1685 1700 return rc;
1686 1701 }
1687 1702  
1688   - ad.u.fs.path.dentry = new_dentry;
  1703 + ad.u.dentry = new_dentry;
1689 1704 av = DIR__ADD_NAME | DIR__SEARCH;
1690 1705 if (new_dentry->d_inode)
1691 1706 av |= DIR__REMOVE_NAME;
... ... @@ -1895,7 +1910,7 @@
1895 1910 {
1896 1911 const struct cred *cred = current_cred();
1897 1912  
1898   - return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON);
  1913 + return dentry_has_perm(cred, dentry, FILE__QUOTAON);
1899 1914 }
1900 1915  
1901 1916 static int selinux_syslog(int type)
... ... @@ -1992,8 +2007,8 @@
1992 2007 return rc;
1993 2008 }
1994 2009  
1995   - COMMON_AUDIT_DATA_INIT(&ad, FS);
1996   - ad.u.fs.path = bprm->file->f_path;
  2010 + COMMON_AUDIT_DATA_INIT(&ad, PATH);
  2011 + ad.u.path = bprm->file->f_path;
1997 2012  
1998 2013 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
1999 2014 new_tsec->sid = old_tsec->sid;
... ... @@ -2121,7 +2136,7 @@
2121 2136  
2122 2137 /* Revalidate access to inherited open files. */
2123 2138  
2124   - COMMON_AUDIT_DATA_INIT(&ad, FS);
  2139 + COMMON_AUDIT_DATA_INIT(&ad, INODE);
2125 2140  
2126 2141 spin_lock(&files->file_lock);
2127 2142 for (;;) {
... ... @@ -2469,8 +2484,8 @@
2469 2484 if (flags & MS_KERNMOUNT)
2470 2485 return 0;
2471 2486  
2472   - COMMON_AUDIT_DATA_INIT(&ad, FS);
2473   - ad.u.fs.path.dentry = sb->s_root;
  2487 + COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
  2488 + ad.u.dentry = sb->s_root;
2474 2489 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
2475 2490 }
2476 2491  
... ... @@ -2479,8 +2494,8 @@
2479 2494 const struct cred *cred = current_cred();
2480 2495 struct common_audit_data ad;
2481 2496  
2482   - COMMON_AUDIT_DATA_INIT(&ad, FS);
2483   - ad.u.fs.path.dentry = dentry->d_sb->s_root;
  2497 + COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
  2498 + ad.u.dentry = dentry->d_sb->s_root;
2484 2499 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
2485 2500 }
2486 2501  
... ... @@ -2496,8 +2511,7 @@
2496 2511 return superblock_has_perm(cred, path->mnt->mnt_sb,
2497 2512 FILESYSTEM__REMOUNT, NULL);
2498 2513 else
2499   - return dentry_has_perm(cred, path->mnt, path->dentry,
2500   - FILE__MOUNTON);
  2514 + return path_has_perm(cred, path, FILE__MOUNTON);
2501 2515 }
2502 2516  
2503 2517 static int selinux_umount(struct vfsmount *mnt, int flags)
2504 2518  
... ... @@ -2630,14 +2644,14 @@
2630 2644 {
2631 2645 const struct cred *cred = current_cred();
2632 2646  
2633   - return dentry_has_perm(cred, NULL, dentry, FILE__READ);
  2647 + return dentry_has_perm(cred, dentry, FILE__READ);
2634 2648 }
2635 2649  
2636 2650 static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
2637 2651 {
2638 2652 const struct cred *cred = current_cred();
2639 2653  
2640   - return dentry_has_perm(cred, NULL, dentry, FILE__READ);
  2654 + return dentry_has_perm(cred, dentry, FILE__READ);
2641 2655 }
2642 2656  
2643 2657 static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags)
... ... @@ -2654,8 +2668,8 @@
2654 2668 if (!mask)
2655 2669 return 0;
2656 2670  
2657   - COMMON_AUDIT_DATA_INIT(&ad, FS);
2658   - ad.u.fs.inode = inode;
  2671 + COMMON_AUDIT_DATA_INIT(&ad, INODE);
  2672 + ad.u.inode = inode;
2659 2673  
2660 2674 if (from_access)
2661 2675 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS;
2662 2676  
2663 2677  
2664 2678  
... ... @@ -2680,16 +2694,20 @@
2680 2694  
2681 2695 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
2682 2696 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
2683   - return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR);
  2697 + return dentry_has_perm(cred, dentry, FILE__SETATTR);
2684 2698  
2685   - return dentry_has_perm(cred, NULL, dentry, FILE__WRITE);
  2699 + return dentry_has_perm(cred, dentry, FILE__WRITE);
2686 2700 }
2687 2701  
2688 2702 static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
2689 2703 {
2690 2704 const struct cred *cred = current_cred();
  2705 + struct path path;
2691 2706  
2692   - return dentry_has_perm(cred, mnt, dentry, FILE__GETATTR);
  2707 + path.dentry = dentry;
  2708 + path.mnt = mnt;
  2709 +
  2710 + return path_has_perm(cred, &path, FILE__GETATTR);
2693 2711 }
2694 2712  
2695 2713 static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
... ... @@ -2710,7 +2728,7 @@
2710 2728  
2711 2729 /* Not an attribute we recognize, so just check the
2712 2730 ordinary setattr permission. */
2713   - return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR);
  2731 + return dentry_has_perm(cred, dentry, FILE__SETATTR);
2714 2732 }
2715 2733  
2716 2734 static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
... ... @@ -2733,8 +2751,8 @@
2733 2751 if (!inode_owner_or_capable(inode))
2734 2752 return -EPERM;
2735 2753  
2736   - COMMON_AUDIT_DATA_INIT(&ad, FS);
2737   - ad.u.fs.path.dentry = dentry;
  2754 + COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
  2755 + ad.u.dentry = dentry;
2738 2756  
2739 2757 rc = avc_has_perm(sid, isec->sid, isec->sclass,
2740 2758 FILE__RELABELFROM, &ad);
2741 2759  
... ... @@ -2797,14 +2815,14 @@
2797 2815 {
2798 2816 const struct cred *cred = current_cred();
2799 2817  
2800   - return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR);
  2818 + return dentry_has_perm(cred, dentry, FILE__GETATTR);
2801 2819 }
2802 2820  
2803 2821 static int selinux_inode_listxattr(struct dentry *dentry)
2804 2822 {
2805 2823 const struct cred *cred = current_cred();
2806 2824  
2807   - return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR);
  2825 + return dentry_has_perm(cred, dentry, FILE__GETATTR);
2808 2826 }
2809 2827  
2810 2828 static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
security/selinux/include/security.h
... ... @@ -30,13 +30,14 @@
30 30 #define POLICYDB_VERSION_PERMISSIVE 23
31 31 #define POLICYDB_VERSION_BOUNDARY 24
32 32 #define POLICYDB_VERSION_FILENAME_TRANS 25
  33 +#define POLICYDB_VERSION_ROLETRANS 26
33 34  
34 35 /* Range of policy versions we understand*/
35 36 #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
36 37 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
37 38 #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
38 39 #else
39   -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_FILENAME_TRANS
  40 +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_ROLETRANS
40 41 #endif
41 42  
42 43 /* Mask for just the mount related flags */
... ... @@ -85,7 +86,7 @@
85 86 int security_mls_enabled(void);
86 87  
87 88 int security_load_policy(void *data, size_t len);
88   -int security_read_policy(void **data, ssize_t *len);
  89 +int security_read_policy(void **data, size_t *len);
89 90 size_t security_policydb_len(void);
90 91  
91 92 int security_policycap_supported(unsigned int req_cap);
... ... @@ -111,8 +112,8 @@
111 112 int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
112 113 const struct qstr *qstr, u32 *out_sid);
113 114  
114   -int security_transition_sid_user(u32 ssid, u32 tsid,
115   - u16 tclass, u32 *out_sid);
  115 +int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
  116 + const char *objname, u32 *out_sid);
116 117  
117 118 int security_member_sid(u32 ssid, u32 tsid,
118 119 u16 tclass, u32 *out_sid);
security/selinux/netnode.c
... ... @@ -141,6 +141,7 @@
141 141 break;
142 142 default:
143 143 BUG();
  144 + return NULL;
144 145 }
145 146  
146 147 list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list)
security/selinux/selinuxfs.c
... ... @@ -28,6 +28,7 @@
28 28 #include <linux/percpu.h>
29 29 #include <linux/audit.h>
30 30 #include <linux/uaccess.h>
  31 +#include <linux/kobject.h>
31 32  
32 33 /* selinuxfs pseudo filesystem for exporting the security policy API.
33 34 Based on the proc code and the fs/nfsd/nfsctl.c code. */
34 35  
... ... @@ -753,11 +754,13 @@
753 754 static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
754 755 {
755 756 char *scon = NULL, *tcon = NULL;
  757 + char *namebuf = NULL, *objname = NULL;
756 758 u32 ssid, tsid, newsid;
757 759 u16 tclass;
758 760 ssize_t length;
759 761 char *newcon = NULL;
760 762 u32 len;
  763 + int nargs;
761 764  
762 765 length = task_has_security(current, SECURITY__COMPUTE_CREATE);
763 766 if (length)
764 767  
765 768  
... ... @@ -773,9 +776,17 @@
773 776 if (!tcon)
774 777 goto out;
775 778  
  779 + length = -ENOMEM;
  780 + namebuf = kzalloc(size + 1, GFP_KERNEL);
  781 + if (!namebuf)
  782 + goto out;
  783 +
776 784 length = -EINVAL;
777   - if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
  785 + nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf);
  786 + if (nargs < 3 || nargs > 4)
778 787 goto out;
  788 + if (nargs == 4)
  789 + objname = namebuf;
779 790  
780 791 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
781 792 if (length)
... ... @@ -785,7 +796,8 @@
785 796 if (length)
786 797 goto out;
787 798  
788   - length = security_transition_sid_user(ssid, tsid, tclass, &newsid);
  799 + length = security_transition_sid_user(ssid, tsid, tclass,
  800 + objname, &newsid);
789 801 if (length)
790 802 goto out;
791 803  
... ... @@ -804,6 +816,7 @@
804 816 length = len;
805 817 out:
806 818 kfree(newcon);
  819 + kfree(namebuf);
807 820 kfree(tcon);
808 821 kfree(scon);
809 822 return length;
... ... @@ -1901,6 +1914,7 @@
1901 1914 };
1902 1915  
1903 1916 struct vfsmount *selinuxfs_mount;
  1917 +static struct kobject *selinuxfs_kobj;
1904 1918  
1905 1919 static int __init init_sel_fs(void)
1906 1920 {
1907 1921  
1908 1922  
... ... @@ -1908,9 +1922,16 @@
1908 1922  
1909 1923 if (!selinux_enabled)
1910 1924 return 0;
  1925 +
  1926 + selinuxfs_kobj = kobject_create_and_add("selinux", fs_kobj);
  1927 + if (!selinuxfs_kobj)
  1928 + return -ENOMEM;
  1929 +
1911 1930 err = register_filesystem(&sel_fs_type);
1912   - if (err)
  1931 + if (err) {
  1932 + kobject_put(selinuxfs_kobj);
1913 1933 return err;
  1934 + }
1914 1935  
1915 1936 selinuxfs_mount = kern_mount(&sel_fs_type);
1916 1937 if (IS_ERR(selinuxfs_mount)) {
... ... @@ -1927,6 +1948,7 @@
1927 1948 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
1928 1949 void exit_sel_fs(void)
1929 1950 {
  1951 + kobject_put(selinuxfs_kobj);
1930 1952 unregister_filesystem(&sel_fs_type);
1931 1953 }
1932 1954 #endif
security/selinux/ss/policydb.c
... ... @@ -128,6 +128,11 @@
128 128 .sym_num = SYM_NUM,
129 129 .ocon_num = OCON_NUM,
130 130 },
  131 + {
  132 + .version = POLICYDB_VERSION_ROLETRANS,
  133 + .sym_num = SYM_NUM,
  134 + .ocon_num = OCON_NUM,
  135 + },
131 136 };
132 137  
133 138 static struct policydb_compat_info *policydb_lookup_compat(int version)
... ... @@ -179,6 +184,43 @@
179 184 return rc;
180 185 }
181 186  
  187 +static u32 filenametr_hash(struct hashtab *h, const void *k)
  188 +{
  189 + const struct filename_trans *ft = k;
  190 + unsigned long hash;
  191 + unsigned int byte_num;
  192 + unsigned char focus;
  193 +
  194 + hash = ft->stype ^ ft->ttype ^ ft->tclass;
  195 +
  196 + byte_num = 0;
  197 + while ((focus = ft->name[byte_num++]))
  198 + hash = partial_name_hash(focus, hash);
  199 + return hash & (h->size - 1);
  200 +}
  201 +
  202 +static int filenametr_cmp(struct hashtab *h, const void *k1, const void *k2)
  203 +{
  204 + const struct filename_trans *ft1 = k1;
  205 + const struct filename_trans *ft2 = k2;
  206 + int v;
  207 +
  208 + v = ft1->stype - ft2->stype;
  209 + if (v)
  210 + return v;
  211 +
  212 + v = ft1->ttype - ft2->ttype;
  213 + if (v)
  214 + return v;
  215 +
  216 + v = ft1->tclass - ft2->tclass;
  217 + if (v)
  218 + return v;
  219 +
  220 + return strcmp(ft1->name, ft2->name);
  221 +
  222 +}
  223 +
182 224 static u32 rangetr_hash(struct hashtab *h, const void *k)
183 225 {
184 226 const struct range_trans *key = k;
185 227  
186 228  
... ... @@ -231,15 +273,22 @@
231 273 if (rc)
232 274 goto out;
233 275  
  276 + p->filename_trans = hashtab_create(filenametr_hash, filenametr_cmp, (1 << 10));
  277 + if (!p->filename_trans)
  278 + goto out;
  279 +
234 280 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
235 281 if (!p->range_tr)
236 282 goto out;
237 283  
  284 + ebitmap_init(&p->filename_trans_ttypes);
238 285 ebitmap_init(&p->policycaps);
239 286 ebitmap_init(&p->permissive_map);
240 287  
241 288 return 0;
242 289 out:
  290 + hashtab_destroy(p->filename_trans);
  291 + hashtab_destroy(p->range_tr);
243 292 for (i = 0; i < SYM_NUM; i++)
244 293 hashtab_destroy(p->symtab[i].table);
245 294 return rc;
246 295  
247 296  
248 297  
249 298  
250 299  
251 300  
252 301  
... ... @@ -417,32 +466,26 @@
417 466 };
418 467  
419 468 #ifdef DEBUG_HASHES
420   -static void symtab_hash_eval(struct symtab *s)
  469 +static void hash_eval(struct hashtab *h, const char *hash_name)
421 470 {
422   - int i;
  471 + struct hashtab_info info;
423 472  
424   - for (i = 0; i < SYM_NUM; i++) {
425   - struct hashtab *h = s[i].table;
426   - struct hashtab_info info;
427   -
428   - hashtab_stat(h, &info);
429   - printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, "
430   - "longest chain length %d\n", symtab_name[i], h->nel,
431   - info.slots_used, h->size, info.max_chain_len);
432   - }
  473 + hashtab_stat(h, &info);
  474 + printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, "
  475 + "longest chain length %d\n", hash_name, h->nel,
  476 + info.slots_used, h->size, info.max_chain_len);
433 477 }
434 478  
435   -static void rangetr_hash_eval(struct hashtab *h)
  479 +static void symtab_hash_eval(struct symtab *s)
436 480 {
437   - struct hashtab_info info;
  481 + int i;
438 482  
439   - hashtab_stat(h, &info);
440   - printk(KERN_DEBUG "SELinux: rangetr: %d entries and %d/%d buckets used, "
441   - "longest chain length %d\n", h->nel,
442   - info.slots_used, h->size, info.max_chain_len);
  483 + for (i = 0; i < SYM_NUM; i++)
  484 + hash_eval(s[i].table, symtab_name[i]);
443 485 }
  486 +
444 487 #else
445   -static inline void rangetr_hash_eval(struct hashtab *h)
  488 +static inline void hash_eval(struct hashtab *h, char *hash_name)
446 489 {
447 490 }
448 491 #endif
... ... @@ -675,6 +718,16 @@
675 718 cat_destroy,
676 719 };
677 720  
  721 +static int filenametr_destroy(void *key, void *datum, void *p)
  722 +{
  723 + struct filename_trans *ft = key;
  724 + kfree(ft->name);
  725 + kfree(key);
  726 + kfree(datum);
  727 + cond_resched();
  728 + return 0;
  729 +}
  730 +
678 731 static int range_tr_destroy(void *key, void *datum, void *p)
679 732 {
680 733 struct mls_range *rt = datum;
... ... @@ -709,7 +762,6 @@
709 762 int i;
710 763 struct role_allow *ra, *lra = NULL;
711 764 struct role_trans *tr, *ltr = NULL;
712   - struct filename_trans *ft, *nft;
713 765  
714 766 for (i = 0; i < SYM_NUM; i++) {
715 767 cond_resched();
... ... @@ -773,6 +825,9 @@
773 825 }
774 826 kfree(lra);
775 827  
  828 + hashtab_map(p->filename_trans, filenametr_destroy, NULL);
  829 + hashtab_destroy(p->filename_trans);
  830 +
776 831 hashtab_map(p->range_tr, range_tr_destroy, NULL);
777 832 hashtab_destroy(p->range_tr);
778 833  
... ... @@ -788,14 +843,7 @@
788 843 flex_array_free(p->type_attr_map_array);
789 844 }
790 845  
791   - ft = p->filename_trans;
792   - while (ft) {
793   - nft = ft->next;
794   - kfree(ft->name);
795   - kfree(ft);
796   - ft = nft;
797   - }
798   -
  846 + ebitmap_destroy(&p->filename_trans_ttypes);
799 847 ebitmap_destroy(&p->policycaps);
800 848 ebitmap_destroy(&p->permissive_map);
801 849  
... ... @@ -1795,7 +1843,7 @@
1795 1843 rt = NULL;
1796 1844 r = NULL;
1797 1845 }
1798   - rangetr_hash_eval(p->range_tr);
  1846 + hash_eval(p->range_tr, "rangetr");
1799 1847 rc = 0;
1800 1848 out:
1801 1849 kfree(rt);
1802 1850  
... ... @@ -1805,9 +1853,10 @@
1805 1853  
1806 1854 static int filename_trans_read(struct policydb *p, void *fp)
1807 1855 {
1808   - struct filename_trans *ft, *last;
1809   - u32 nel, len;
  1856 + struct filename_trans *ft;
  1857 + struct filename_trans_datum *otype;
1810 1858 char *name;
  1859 + u32 nel, len;
1811 1860 __le32 buf[4];
1812 1861 int rc, i;
1813 1862  
1814 1863  
1815 1864  
1816 1865  
... ... @@ -1816,25 +1865,23 @@
1816 1865  
1817 1866 rc = next_entry(buf, fp, sizeof(u32));
1818 1867 if (rc)
1819   - goto out;
  1868 + return rc;
1820 1869 nel = le32_to_cpu(buf[0]);
1821 1870  
1822   - last = p->filename_trans;
1823   - while (last && last->next)
1824   - last = last->next;
1825   -
1826 1871 for (i = 0; i < nel; i++) {
  1872 + ft = NULL;
  1873 + otype = NULL;
  1874 + name = NULL;
  1875 +
1827 1876 rc = -ENOMEM;
1828 1877 ft = kzalloc(sizeof(*ft), GFP_KERNEL);
1829 1878 if (!ft)
1830 1879 goto out;
1831 1880  
1832   - /* add it to the tail of the list */
1833   - if (!last)
1834   - p->filename_trans = ft;
1835   - else
1836   - last->next = ft;
1837   - last = ft;
  1881 + rc = -ENOMEM;
  1882 + otype = kmalloc(sizeof(*otype), GFP_KERNEL);
  1883 + if (!otype)
  1884 + goto out;
1838 1885  
1839 1886 /* length of the path component string */
1840 1887 rc = next_entry(buf, fp, sizeof(u32));
1841 1888  
1842 1889  
... ... @@ -1862,10 +1909,22 @@
1862 1909 ft->stype = le32_to_cpu(buf[0]);
1863 1910 ft->ttype = le32_to_cpu(buf[1]);
1864 1911 ft->tclass = le32_to_cpu(buf[2]);
1865   - ft->otype = le32_to_cpu(buf[3]);
  1912 +
  1913 + otype->otype = le32_to_cpu(buf[3]);
  1914 +
  1915 + rc = ebitmap_set_bit(&p->filename_trans_ttypes, ft->ttype, 1);
  1916 + if (rc)
  1917 + goto out;
  1918 +
  1919 + hashtab_insert(p->filename_trans, ft, otype);
1866 1920 }
1867   - rc = 0;
  1921 + hash_eval(p->filename_trans, "filenametr");
  1922 + return 0;
1868 1923 out:
  1924 + kfree(ft);
  1925 + kfree(name);
  1926 + kfree(otype);
  1927 +
1869 1928 return rc;
1870 1929 }
1871 1930  
... ... @@ -2266,6 +2325,11 @@
2266 2325 p->symtab[i].nprim = nprim;
2267 2326 }
2268 2327  
  2328 + rc = -EINVAL;
  2329 + p->process_class = string_to_security_class(p, "process");
  2330 + if (!p->process_class)
  2331 + goto bad;
  2332 +
2269 2333 rc = avtab_read(&p->te_avtab, fp, p);
2270 2334 if (rc)
2271 2335 goto bad;
2272 2336  
... ... @@ -2298,8 +2362,17 @@
2298 2362 tr->role = le32_to_cpu(buf[0]);
2299 2363 tr->type = le32_to_cpu(buf[1]);
2300 2364 tr->new_role = le32_to_cpu(buf[2]);
  2365 + if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
  2366 + rc = next_entry(buf, fp, sizeof(u32));
  2367 + if (rc)
  2368 + goto bad;
  2369 + tr->tclass = le32_to_cpu(buf[0]);
  2370 + } else
  2371 + tr->tclass = p->process_class;
  2372 +
2301 2373 if (!policydb_role_isvalid(p, tr->role) ||
2302 2374 !policydb_type_isvalid(p, tr->type) ||
  2375 + !policydb_class_isvalid(p, tr->tclass) ||
2303 2376 !policydb_role_isvalid(p, tr->new_role))
2304 2377 goto bad;
2305 2378 ltr = tr;
... ... @@ -2341,11 +2414,6 @@
2341 2414 goto bad;
2342 2415  
2343 2416 rc = -EINVAL;
2344   - p->process_class = string_to_security_class(p, "process");
2345   - if (!p->process_class)
2346   - goto bad;
2347   -
2348   - rc = -EINVAL;
2349 2417 p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition");
2350 2418 p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition");
2351 2419 if (!p->process_trans_perms)
2352 2420  
... ... @@ -2517,8 +2585,9 @@
2517 2585 return 0;
2518 2586 }
2519 2587  
2520   -static int role_trans_write(struct role_trans *r, void *fp)
  2588 +static int role_trans_write(struct policydb *p, void *fp)
2521 2589 {
  2590 + struct role_trans *r = p->role_tr;
2522 2591 struct role_trans *tr;
2523 2592 u32 buf[3];
2524 2593 size_t nel;
... ... @@ -2538,6 +2607,12 @@
2538 2607 rc = put_entry(buf, sizeof(u32), 3, fp);
2539 2608 if (rc)
2540 2609 return rc;
  2610 + if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
  2611 + buf[0] = cpu_to_le32(tr->tclass);
  2612 + rc = put_entry(buf, sizeof(u32), 1, fp);
  2613 + if (rc)
  2614 + return rc;
  2615 + }
2541 2616 }
2542 2617  
2543 2618 return 0;
... ... @@ -3045,7 +3120,7 @@
3045 3120 return 0;
3046 3121 }
3047 3122  
3048   -static int range_count(void *key, void *data, void *ptr)
  3123 +static int hashtab_cnt(void *key, void *data, void *ptr)
3049 3124 {
3050 3125 int *cnt = ptr;
3051 3126 *cnt = *cnt + 1;
... ... @@ -3093,7 +3168,7 @@
3093 3168  
3094 3169 /* count the number of entries in the hashtab */
3095 3170 nel = 0;
3096   - rc = hashtab_map(p->range_tr, range_count, &nel);
  3171 + rc = hashtab_map(p->range_tr, hashtab_cnt, &nel);
3097 3172 if (rc)
3098 3173 return rc;
3099 3174  
3100 3175  
3101 3176  
3102 3177  
3103 3178  
3104 3179  
3105 3180  
3106 3181  
3107 3182  
3108 3183  
... ... @@ -3110,43 +3185,60 @@
3110 3185 return 0;
3111 3186 }
3112 3187  
3113   -static int filename_trans_write(struct policydb *p, void *fp)
  3188 +static int filename_write_helper(void *key, void *data, void *ptr)
3114 3189 {
3115   - struct filename_trans *ft;
3116   - u32 len, nel = 0;
3117 3190 __le32 buf[4];
  3191 + struct filename_trans *ft = key;
  3192 + struct filename_trans_datum *otype = data;
  3193 + void *fp = ptr;
3118 3194 int rc;
  3195 + u32 len;
3119 3196  
3120   - for (ft = p->filename_trans; ft; ft = ft->next)
3121   - nel++;
3122   -
3123   - buf[0] = cpu_to_le32(nel);
  3197 + len = strlen(ft->name);
  3198 + buf[0] = cpu_to_le32(len);
3124 3199 rc = put_entry(buf, sizeof(u32), 1, fp);
3125 3200 if (rc)
3126 3201 return rc;
3127 3202  
3128   - for (ft = p->filename_trans; ft; ft = ft->next) {
3129   - len = strlen(ft->name);
3130   - buf[0] = cpu_to_le32(len);
3131   - rc = put_entry(buf, sizeof(u32), 1, fp);
3132   - if (rc)
3133   - return rc;
  3203 + rc = put_entry(ft->name, sizeof(char), len, fp);
  3204 + if (rc)
  3205 + return rc;
3134 3206  
3135   - rc = put_entry(ft->name, sizeof(char), len, fp);
3136   - if (rc)
3137   - return rc;
  3207 + buf[0] = ft->stype;
  3208 + buf[1] = ft->ttype;
  3209 + buf[2] = ft->tclass;
  3210 + buf[3] = otype->otype;
3138 3211  
3139   - buf[0] = ft->stype;
3140   - buf[1] = ft->ttype;
3141   - buf[2] = ft->tclass;
3142   - buf[3] = ft->otype;
  3212 + rc = put_entry(buf, sizeof(u32), 4, fp);
  3213 + if (rc)
  3214 + return rc;
3143 3215  
3144   - rc = put_entry(buf, sizeof(u32), 4, fp);
3145   - if (rc)
3146   - return rc;
3147   - }
3148 3216 return 0;
3149 3217 }
  3218 +
  3219 +static int filename_trans_write(struct policydb *p, void *fp)
  3220 +{
  3221 + u32 nel;
  3222 + __le32 buf[1];
  3223 + int rc;
  3224 +
  3225 + nel = 0;
  3226 + rc = hashtab_map(p->filename_trans, hashtab_cnt, &nel);
  3227 + if (rc)
  3228 + return rc;
  3229 +
  3230 + buf[0] = cpu_to_le32(nel);
  3231 + rc = put_entry(buf, sizeof(u32), 1, fp);
  3232 + if (rc)
  3233 + return rc;
  3234 +
  3235 + rc = hashtab_map(p->filename_trans, filename_write_helper, fp);
  3236 + if (rc)
  3237 + return rc;
  3238 +
  3239 + return 0;
  3240 +}
  3241 +
3150 3242 /*
3151 3243 * Write the configuration data in a policy database
3152 3244 * structure to a policy database binary representation
... ... @@ -3249,7 +3341,7 @@
3249 3341 if (rc)
3250 3342 return rc;
3251 3343  
3252   - rc = role_trans_write(p->role_tr, fp);
  3344 + rc = role_trans_write(p, fp);
3253 3345 if (rc)
3254 3346 return rc;
3255 3347  
security/selinux/ss/policydb.h
... ... @@ -72,17 +72,20 @@
72 72  
73 73 struct role_trans {
74 74 u32 role; /* current role */
75   - u32 type; /* program executable type */
  75 + u32 type; /* program executable type, or new object type */
  76 + u32 tclass; /* process class, or new object class */
76 77 u32 new_role; /* new role */
77 78 struct role_trans *next;
78 79 };
79 80  
80 81 struct filename_trans {
81   - struct filename_trans *next;
82 82 u32 stype; /* current process */
83 83 u32 ttype; /* parent dir context */
84 84 u16 tclass; /* class of new object */
85 85 const char *name; /* last path component */
  86 +};
  87 +
  88 +struct filename_trans_datum {
86 89 u32 otype; /* expected of new object */
87 90 };
88 91  
... ... @@ -227,7 +230,10 @@
227 230 struct role_trans *role_tr;
228 231  
229 232 /* file transitions with the last path component */
230   - struct filename_trans *filename_trans;
  233 + /* quickly exclude lookups when parent ttype has no rules */
  234 + struct ebitmap filename_trans_ttypes;
  235 + /* actual set of filename_trans rules */
  236 + struct hashtab *filename_trans;
231 237  
232 238 /* bools indexed by (value - 1) */
233 239 struct cond_bool_datum **bool_val_to_struct;
security/selinux/ss/services.c
... ... @@ -1359,26 +1359,35 @@
1359 1359 }
1360 1360  
1361 1361 static void filename_compute_type(struct policydb *p, struct context *newcontext,
1362   - u32 scon, u32 tcon, u16 tclass,
1363   - const struct qstr *qstr)
  1362 + u32 stype, u32 ttype, u16 tclass,
  1363 + const char *objname)
1364 1364 {
1365   - struct filename_trans *ft;
1366   - for (ft = p->filename_trans; ft; ft = ft->next) {
1367   - if (ft->stype == scon &&
1368   - ft->ttype == tcon &&
1369   - ft->tclass == tclass &&
1370   - !strcmp(ft->name, qstr->name)) {
1371   - newcontext->type = ft->otype;
1372   - return;
1373   - }
1374   - }
  1365 + struct filename_trans ft;
  1366 + struct filename_trans_datum *otype;
  1367 +
  1368 + /*
  1369 + * Most filename trans rules are going to live in specific directories
  1370 + * like /dev or /var/run. This bitmap will quickly skip rule searches
  1371 + * if the ttype does not contain any rules.
  1372 + */
  1373 + if (!ebitmap_get_bit(&p->filename_trans_ttypes, ttype))
  1374 + return;
  1375 +
  1376 + ft.stype = stype;
  1377 + ft.ttype = ttype;
  1378 + ft.tclass = tclass;
  1379 + ft.name = objname;
  1380 +
  1381 + otype = hashtab_search(p->filename_trans, &ft);
  1382 + if (otype)
  1383 + newcontext->type = otype->otype;
1375 1384 }
1376 1385  
1377 1386 static int security_compute_sid(u32 ssid,
1378 1387 u32 tsid,
1379 1388 u16 orig_tclass,
1380 1389 u32 specified,
1381   - const struct qstr *qstr,
  1390 + const char *objname,
1382 1391 u32 *out_sid,
1383 1392 bool kern)
1384 1393 {
1385 1394  
1386 1395  
... ... @@ -1478,23 +1487,21 @@
1478 1487 newcontext.type = avdatum->data;
1479 1488 }
1480 1489  
1481   - /* if we have a qstr this is a file trans check so check those rules */
1482   - if (qstr)
  1490 + /* if we have a objname this is a file trans check so check those rules */
  1491 + if (objname)
1483 1492 filename_compute_type(&policydb, &newcontext, scontext->type,
1484   - tcontext->type, tclass, qstr);
  1493 + tcontext->type, tclass, objname);
1485 1494  
1486 1495 /* Check for class-specific changes. */
1487   - if (tclass == policydb.process_class) {
1488   - if (specified & AVTAB_TRANSITION) {
1489   - /* Look for a role transition rule. */
1490   - for (roletr = policydb.role_tr; roletr;
1491   - roletr = roletr->next) {
1492   - if (roletr->role == scontext->role &&
1493   - roletr->type == tcontext->type) {
1494   - /* Use the role transition rule. */
1495   - newcontext.role = roletr->new_role;
1496   - break;
1497   - }
  1496 + if (specified & AVTAB_TRANSITION) {
  1497 + /* Look for a role transition rule. */
  1498 + for (roletr = policydb.role_tr; roletr; roletr = roletr->next) {
  1499 + if ((roletr->role == scontext->role) &&
  1500 + (roletr->type == tcontext->type) &&
  1501 + (roletr->tclass == tclass)) {
  1502 + /* Use the role transition rule. */
  1503 + newcontext.role = roletr->new_role;
  1504 + break;
1498 1505 }
1499 1506 }
1500 1507 }
1501 1508  
1502 1509  
... ... @@ -1541,13 +1548,14 @@
1541 1548 const struct qstr *qstr, u32 *out_sid)
1542 1549 {
1543 1550 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1544   - qstr, out_sid, true);
  1551 + qstr ? qstr->name : NULL, out_sid, true);
1545 1552 }
1546 1553  
1547   -int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid)
  1554 +int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
  1555 + const char *objname, u32 *out_sid)
1548 1556 {
1549 1557 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1550   - NULL, out_sid, false);
  1558 + objname, out_sid, false);
1551 1559 }
1552 1560  
1553 1561 /**
... ... @@ -3190,7 +3198,7 @@
3190 3198 * @len: length of data in bytes
3191 3199 *
3192 3200 */
3193   -int security_read_policy(void **data, ssize_t *len)
  3201 +int security_read_policy(void **data, size_t *len)
3194 3202 {
3195 3203 int rc;
3196 3204 struct policy_file fp;
security/smack/smack.h
... ... @@ -316,22 +316,17 @@
316 316 static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a,
317 317 struct dentry *d)
318 318 {
319   - a->a.u.fs.path.dentry = d;
  319 + a->a.u.dentry = d;
320 320 }
321   -static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a,
322   - struct vfsmount *m)
323   -{
324   - a->a.u.fs.path.mnt = m;
325   -}
326 321 static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a,
327 322 struct inode *i)
328 323 {
329   - a->a.u.fs.inode = i;
  324 + a->a.u.inode = i;
330 325 }
331 326 static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a,
332 327 struct path p)
333 328 {
334   - a->a.u.fs.path = p;
  329 + a->a.u.path = p;
335 330 }
336 331 static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
337 332 struct sock *sk)
security/smack/smack_lsm.c
... ... @@ -383,7 +383,7 @@
383 383 int rc;
384 384 struct smk_audit_info ad;
385 385  
386   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
  386 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
387 387 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
388 388  
389 389 rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad);
... ... @@ -407,7 +407,7 @@
407 407 struct superblock_smack *sbp = path->mnt->mnt_sb->s_security;
408 408 struct smk_audit_info ad;
409 409  
410   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
  410 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
411 411 smk_ad_setfield_u_fs_path(&ad, *path);
412 412  
413 413 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
414 414  
415 415  
... ... @@ -425,11 +425,14 @@
425 425 {
426 426 struct superblock_smack *sbp;
427 427 struct smk_audit_info ad;
  428 + struct path path;
428 429  
429   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
430   - smk_ad_setfield_u_fs_path_dentry(&ad, mnt->mnt_root);
431   - smk_ad_setfield_u_fs_path_mnt(&ad, mnt);
  430 + path.dentry = mnt->mnt_root;
  431 + path.mnt = mnt;
432 432  
  433 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
  434 + smk_ad_setfield_u_fs_path(&ad, path);
  435 +
433 436 sbp = mnt->mnt_sb->s_security;
434 437 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
435 438 }
... ... @@ -563,7 +566,7 @@
563 566 struct smk_audit_info ad;
564 567 int rc;
565 568  
566   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
  569 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
567 570 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
568 571  
569 572 isp = smk_of_inode(old_dentry->d_inode);
... ... @@ -592,7 +595,7 @@
592 595 struct smk_audit_info ad;
593 596 int rc;
594 597  
595   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
  598 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
596 599 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
597 600  
598 601 /*
... ... @@ -623,7 +626,7 @@
623 626 struct smk_audit_info ad;
624 627 int rc;
625 628  
626   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
  629 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
627 630 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
628 631  
629 632 /*
... ... @@ -663,7 +666,7 @@
663 666 char *isp;
664 667 struct smk_audit_info ad;
665 668  
666   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
  669 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
667 670 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
668 671  
669 672 isp = smk_of_inode(old_dentry->d_inode);
... ... @@ -700,7 +703,7 @@
700 703 /* May be droppable after audit */
701 704 if (flags & IPERM_FLAG_RCU)
702 705 return -ECHILD;
703   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
  706 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
704 707 smk_ad_setfield_u_fs_inode(&ad, inode);
705 708 return smk_curacc(smk_of_inode(inode), mask, &ad);
706 709 }
... ... @@ -720,7 +723,7 @@
720 723 */
721 724 if (iattr->ia_valid & ATTR_FORCE)
722 725 return 0;
723   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
  726 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
724 727 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
725 728  
726 729 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
727 730  
... ... @@ -736,10 +739,13 @@
736 739 static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
737 740 {
738 741 struct smk_audit_info ad;
  742 + struct path path;
739 743  
740   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
741   - smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
742   - smk_ad_setfield_u_fs_path_mnt(&ad, mnt);
  744 + path.dentry = dentry;
  745 + path.mnt = mnt;
  746 +
  747 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
  748 + smk_ad_setfield_u_fs_path(&ad, path);
743 749 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
744 750 }
745 751  
... ... @@ -784,7 +790,7 @@
784 790 } else
785 791 rc = cap_inode_setxattr(dentry, name, value, size, flags);
786 792  
787   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
  793 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
788 794 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
789 795  
790 796 if (rc == 0)
... ... @@ -845,7 +851,7 @@
845 851 {
846 852 struct smk_audit_info ad;
847 853  
848   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
  854 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
849 855 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
850 856  
851 857 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
... ... @@ -877,7 +883,7 @@
877 883 } else
878 884 rc = cap_inode_removexattr(dentry, name);
879 885  
880   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
  886 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
881 887 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
882 888 if (rc == 0)
883 889 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
... ... @@ -1047,7 +1053,7 @@
1047 1053 int rc = 0;
1048 1054 struct smk_audit_info ad;
1049 1055  
1050   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
  1056 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1051 1057 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1052 1058  
1053 1059 if (_IOC_DIR(cmd) & _IOC_WRITE)
... ... @@ -1070,8 +1076,8 @@
1070 1076 {
1071 1077 struct smk_audit_info ad;
1072 1078  
1073   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
1074   - smk_ad_setfield_u_fs_path_dentry(&ad, file->f_path.dentry);
  1079 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
  1080 + smk_ad_setfield_u_fs_path(&ad, file->f_path);
1075 1081 return smk_curacc(file->f_security, MAY_WRITE, &ad);
1076 1082 }
1077 1083  
... ... @@ -1089,7 +1095,7 @@
1089 1095 struct smk_audit_info ad;
1090 1096 int rc;
1091 1097  
1092   - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
  1098 + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1093 1099 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1094 1100  
1095 1101 switch (cmd) {