Commit 88e67f3b8898c5ea81d2916dd5b8bc9c0c35ba13

Authored by David Howells
Committed by James Morris
1 parent 6cc88bc45c

CRED: Make inode_has_perm() and file_has_perm() take a cred pointer

Make inode_has_perm() and file_has_perm() take a cred pointer rather than a
task pointer.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: James Morris <jmorris@namei.org>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>

Showing 1 changed file with 92 additions and 48 deletions Side-by-side Diff

security/selinux/hooks.c
... ... @@ -173,16 +173,25 @@
173 173 }
174 174  
175 175 /*
  176 + * get the security ID of a set of credentials
  177 + */
  178 +static inline u32 cred_sid(const struct cred *cred)
  179 +{
  180 + const struct task_security_struct *tsec;
  181 +
  182 + tsec = cred->security;
  183 + return tsec->sid;
  184 +}
  185 +
  186 +/*
176 187 * get the security ID of a task
177 188 */
178 189 static inline u32 task_sid(const struct task_struct *task)
179 190 {
180   - const struct task_security_struct *tsec;
181 191 u32 sid;
182 192  
183 193 rcu_read_lock();
184   - tsec = __task_cred(task)->security;
185   - sid = tsec->sid;
  194 + sid = cred_sid(__task_cred(task));
186 195 rcu_read_unlock();
187 196 return sid;
188 197 }
... ... @@ -197,6 +206,8 @@
197 206 return tsec->sid;
198 207 }
199 208  
  209 +/* Allocate and free functions for each kind of security blob. */
  210 +
200 211 static int inode_alloc_security(struct inode *inode)
201 212 {
202 213 struct inode_security_struct *isec;
... ... @@ -1368,7 +1379,7 @@
1368 1379 }
1369 1380  
1370 1381 /*
1371   - * Check permission betweeen a pair of tasks, e.g. signal checks,
  1382 + * Check permission between a pair of tasks, e.g. signal checks,
1372 1383 * fork check, ptrace check, etc.
1373 1384 * tsk1 is the actor and tsk2 is the target
1374 1385 */
... ... @@ -1437,7 +1448,7 @@
1437 1448 /* Check whether a task has a particular permission to an inode.
1438 1449 The 'adp' parameter is optional and allows other audit
1439 1450 data to be passed (e.g. the dentry). */
1440   -static int inode_has_perm(struct task_struct *tsk,
  1451 +static int inode_has_perm(const struct cred *cred,
1441 1452 struct inode *inode,
1442 1453 u32 perms,
1443 1454 struct avc_audit_data *adp)
... ... @@ -1449,7 +1460,7 @@
1449 1460 if (unlikely(IS_PRIVATE(inode)))
1450 1461 return 0;
1451 1462  
1452   - sid = task_sid(tsk);
  1463 + sid = cred_sid(cred);
1453 1464 isec = inode->i_security;
1454 1465  
1455 1466 if (!adp) {
1456 1467  
1457 1468  
... ... @@ -1464,17 +1475,18 @@
1464 1475 /* Same as inode_has_perm, but pass explicit audit data containing
1465 1476 the dentry to help the auditing code to more easily generate the
1466 1477 pathname if needed. */
1467   -static inline int dentry_has_perm(struct task_struct *tsk,
  1478 +static inline int dentry_has_perm(const struct cred *cred,
1468 1479 struct vfsmount *mnt,
1469 1480 struct dentry *dentry,
1470 1481 u32 av)
1471 1482 {
1472 1483 struct inode *inode = dentry->d_inode;
1473 1484 struct avc_audit_data ad;
  1485 +
1474 1486 AVC_AUDIT_DATA_INIT(&ad, FS);
1475 1487 ad.u.fs.path.mnt = mnt;
1476 1488 ad.u.fs.path.dentry = dentry;
1477   - return inode_has_perm(tsk, inode, av, &ad);
  1489 + return inode_has_perm(cred, inode, av, &ad);
1478 1490 }
1479 1491  
1480 1492 /* Check whether a task can use an open file descriptor to
1481 1493  
... ... @@ -1485,14 +1497,14 @@
1485 1497 has the same SID as the process. If av is zero, then
1486 1498 access to the file is not checked, e.g. for cases
1487 1499 where only the descriptor is affected like seek. */
1488   -static int file_has_perm(struct task_struct *tsk,
1489   - struct file *file,
1490   - u32 av)
  1500 +static int file_has_perm(const struct cred *cred,
  1501 + struct file *file,
  1502 + u32 av)
1491 1503 {
1492 1504 struct file_security_struct *fsec = file->f_security;
1493 1505 struct inode *inode = file->f_path.dentry->d_inode;
1494 1506 struct avc_audit_data ad;
1495   - u32 sid = task_sid(tsk);
  1507 + u32 sid = cred_sid(cred);
1496 1508 int rc;
1497 1509  
1498 1510 AVC_AUDIT_DATA_INIT(&ad, FS);
1499 1511  
1500 1512  
1501 1513  
... ... @@ -1504,14 +1516,16 @@
1504 1516 FD__USE,
1505 1517 &ad);
1506 1518 if (rc)
1507   - return rc;
  1519 + goto out;
1508 1520 }
1509 1521  
1510 1522 /* av is zero if only checking access to the descriptor. */
  1523 + rc = 0;
1511 1524 if (av)
1512   - return inode_has_perm(tsk, inode, av, &ad);
  1525 + rc = inode_has_perm(cred, inode, av, &ad);
1513 1526  
1514   - return 0;
  1527 +out:
  1528 + return rc;
1515 1529 }
1516 1530  
1517 1531 /* Check whether a task can create a file. */
1518 1532  
... ... @@ -1670,13 +1684,13 @@
1670 1684 }
1671 1685  
1672 1686 /* Check whether a task can perform a filesystem operation. */
1673   -static int superblock_has_perm(struct task_struct *tsk,
  1687 +static int superblock_has_perm(const struct cred *cred,
1674 1688 struct super_block *sb,
1675 1689 u32 perms,
1676 1690 struct avc_audit_data *ad)
1677 1691 {
1678 1692 struct superblock_security_struct *sbsec;
1679   - u32 sid = task_sid(tsk);
  1693 + u32 sid = cred_sid(cred);
1680 1694  
1681 1695 sbsec = sb->s_security;
1682 1696 return avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad);
... ... @@ -1919,6 +1933,7 @@
1919 1933  
1920 1934 static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
1921 1935 {
  1936 + const struct cred *cred = current_cred();
1922 1937 int rc = 0;
1923 1938  
1924 1939 if (!sb)
1925 1940  
... ... @@ -1930,14 +1945,12 @@
1930 1945 case Q_QUOTAOFF:
1931 1946 case Q_SETINFO:
1932 1947 case Q_SETQUOTA:
1933   - rc = superblock_has_perm(current, sb, FILESYSTEM__QUOTAMOD,
1934   - NULL);
  1948 + rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAMOD, NULL);
1935 1949 break;
1936 1950 case Q_GETFMT:
1937 1951 case Q_GETINFO:
1938 1952 case Q_GETQUOTA:
1939   - rc = superblock_has_perm(current, sb, FILESYSTEM__QUOTAGET,
1940   - NULL);
  1953 + rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAGET, NULL);
1941 1954 break;
1942 1955 default:
1943 1956 rc = 0; /* let the kernel handle invalid cmds */
... ... @@ -1948,7 +1961,9 @@
1948 1961  
1949 1962 static int selinux_quota_on(struct dentry *dentry)
1950 1963 {
1951   - return dentry_has_perm(current, NULL, dentry, FILE__QUOTAON);
  1964 + const struct cred *cred = current_cred();
  1965 +
  1966 + return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON);
1952 1967 }
1953 1968  
1954 1969 static int selinux_syslog(int type)
... ... @@ -2137,6 +2152,7 @@
2137 2152 /* Derived from fs/exec.c:flush_old_files. */
2138 2153 static inline void flush_unauthorized_files(struct files_struct *files)
2139 2154 {
  2155 + const struct cred *cred = current_cred();
2140 2156 struct avc_audit_data ad;
2141 2157 struct file *file, *devnull = NULL;
2142 2158 struct tty_struct *tty;
... ... @@ -2157,7 +2173,7 @@
2157 2173 interested in the inode-based check here. */
2158 2174 file = list_first_entry(&tty->tty_files, struct file, f_u.fu_list);
2159 2175 inode = file->f_path.dentry->d_inode;
2160   - if (inode_has_perm(current, inode,
  2176 + if (inode_has_perm(cred, inode,
2161 2177 FILE__READ | FILE__WRITE, NULL)) {
2162 2178 drop_tty = 1;
2163 2179 }
... ... @@ -2192,7 +2208,7 @@
2192 2208 file = fget(i);
2193 2209 if (!file)
2194 2210 continue;
2195   - if (file_has_perm(current,
  2211 + if (file_has_perm(cred,
2196 2212 file,
2197 2213 file_to_av(file))) {
2198 2214 sys_close(i);
... ... @@ -2465,6 +2481,7 @@
2465 2481  
2466 2482 static int selinux_sb_kern_mount(struct super_block *sb, void *data)
2467 2483 {
  2484 + const struct cred *cred = current_cred();
2468 2485 struct avc_audit_data ad;
2469 2486 int rc;
2470 2487  
2471 2488  
2472 2489  
... ... @@ -2474,16 +2491,17 @@
2474 2491  
2475 2492 AVC_AUDIT_DATA_INIT(&ad, FS);
2476 2493 ad.u.fs.path.dentry = sb->s_root;
2477   - return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad);
  2494 + return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
2478 2495 }
2479 2496  
2480 2497 static int selinux_sb_statfs(struct dentry *dentry)
2481 2498 {
  2499 + const struct cred *cred = current_cred();
2482 2500 struct avc_audit_data ad;
2483 2501  
2484 2502 AVC_AUDIT_DATA_INIT(&ad, FS);
2485 2503 ad.u.fs.path.dentry = dentry->d_sb->s_root;
2486   - return superblock_has_perm(current, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
  2504 + return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
2487 2505 }
2488 2506  
2489 2507 static int selinux_mount(char *dev_name,
... ... @@ -2492,6 +2510,7 @@
2492 2510 unsigned long flags,
2493 2511 void *data)
2494 2512 {
  2513 + const struct cred *cred = current_cred();
2495 2514 int rc;
2496 2515  
2497 2516 rc = secondary_ops->sb_mount(dev_name, path, type, flags, data);
2498 2517  
2499 2518  
2500 2519  
... ... @@ -2499,22 +2518,23 @@
2499 2518 return rc;
2500 2519  
2501 2520 if (flags & MS_REMOUNT)
2502   - return superblock_has_perm(current, path->mnt->mnt_sb,
  2521 + return superblock_has_perm(cred, path->mnt->mnt_sb,
2503 2522 FILESYSTEM__REMOUNT, NULL);
2504 2523 else
2505   - return dentry_has_perm(current, path->mnt, path->dentry,
  2524 + return dentry_has_perm(cred, path->mnt, path->dentry,
2506 2525 FILE__MOUNTON);
2507 2526 }
2508 2527  
2509 2528 static int selinux_umount(struct vfsmount *mnt, int flags)
2510 2529 {
  2530 + const struct cred *cred = current_cred();
2511 2531 int rc;
2512 2532  
2513 2533 rc = secondary_ops->sb_umount(mnt, flags);
2514 2534 if (rc)
2515 2535 return rc;
2516 2536  
2517   - return superblock_has_perm(current, mnt->mnt_sb,
  2537 + return superblock_has_perm(cred, mnt->mnt_sb,
2518 2538 FILESYSTEM__UNMOUNT, NULL);
2519 2539 }
2520 2540  
2521 2541  
2522 2542  
2523 2543  
... ... @@ -2652,21 +2672,25 @@
2652 2672  
2653 2673 static int selinux_inode_readlink(struct dentry *dentry)
2654 2674 {
2655   - return dentry_has_perm(current, NULL, dentry, FILE__READ);
  2675 + const struct cred *cred = current_cred();
  2676 +
  2677 + return dentry_has_perm(cred, NULL, dentry, FILE__READ);
2656 2678 }
2657 2679  
2658 2680 static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
2659 2681 {
  2682 + const struct cred *cred = current_cred();
2660 2683 int rc;
2661 2684  
2662 2685 rc = secondary_ops->inode_follow_link(dentry, nameidata);
2663 2686 if (rc)
2664 2687 return rc;
2665   - return dentry_has_perm(current, NULL, dentry, FILE__READ);
  2688 + return dentry_has_perm(cred, NULL, dentry, FILE__READ);
2666 2689 }
2667 2690  
2668 2691 static int selinux_inode_permission(struct inode *inode, int mask)
2669 2692 {
  2693 + const struct cred *cred = current_cred();
2670 2694 int rc;
2671 2695  
2672 2696 rc = secondary_ops->inode_permission(inode, mask);
2673 2697  
... ... @@ -2678,12 +2702,13 @@
2678 2702 return 0;
2679 2703 }
2680 2704  
2681   - return inode_has_perm(current, inode,
  2705 + return inode_has_perm(cred, inode,
2682 2706 file_mask_to_av(inode->i_mode, mask), NULL);
2683 2707 }
2684 2708  
2685 2709 static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2686 2710 {
  2711 + const struct cred *cred = current_cred();
2687 2712 int rc;
2688 2713  
2689 2714 rc = secondary_ops->inode_setattr(dentry, iattr);
2690 2715  
2691 2716  
2692 2717  
... ... @@ -2695,18 +2720,22 @@
2695 2720  
2696 2721 if (iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
2697 2722 ATTR_ATIME_SET | ATTR_MTIME_SET))
2698   - return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
  2723 + return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR);
2699 2724  
2700   - return dentry_has_perm(current, NULL, dentry, FILE__WRITE);
  2725 + return dentry_has_perm(cred, NULL, dentry, FILE__WRITE);
2701 2726 }
2702 2727  
2703 2728 static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
2704 2729 {
2705   - return dentry_has_perm(current, mnt, dentry, FILE__GETATTR);
  2730 + const struct cred *cred = current_cred();
  2731 +
  2732 + return dentry_has_perm(cred, mnt, dentry, FILE__GETATTR);
2706 2733 }
2707 2734  
2708 2735 static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
2709 2736 {
  2737 + const struct cred *cred = current_cred();
  2738 +
2710 2739 if (!strncmp(name, XATTR_SECURITY_PREFIX,
2711 2740 sizeof XATTR_SECURITY_PREFIX - 1)) {
2712 2741 if (!strcmp(name, XATTR_NAME_CAPS)) {
... ... @@ -2721,7 +2750,7 @@
2721 2750  
2722 2751 /* Not an attribute we recognize, so just check the
2723 2752 ordinary setattr permission. */
2724   - return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
  2753 + return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR);
2725 2754 }
2726 2755  
2727 2756 static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2728 2757  
... ... @@ -2806,12 +2835,16 @@
2806 2835  
2807 2836 static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
2808 2837 {
2809   - return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
  2838 + const struct cred *cred = current_cred();
  2839 +
  2840 + return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR);
2810 2841 }
2811 2842  
2812 2843 static int selinux_inode_listxattr(struct dentry *dentry)
2813 2844 {
2814   - return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
  2845 + const struct cred *cred = current_cred();
  2846 +
  2847 + return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR);
2815 2848 }
2816 2849  
2817 2850 static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
... ... @@ -2915,6 +2948,7 @@
2915 2948  
2916 2949 static int selinux_revalidate_file_permission(struct file *file, int mask)
2917 2950 {
  2951 + const struct cred *cred = current_cred();
2918 2952 int rc;
2919 2953 struct inode *inode = file->f_path.dentry->d_inode;
2920 2954  
... ... @@ -2927,7 +2961,7 @@
2927 2961 if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
2928 2962 mask |= MAY_APPEND;
2929 2963  
2930   - rc = file_has_perm(current, file,
  2964 + rc = file_has_perm(cred, file,
2931 2965 file_mask_to_av(inode->i_mode, mask));
2932 2966 if (rc)
2933 2967 return rc;
... ... @@ -2967,6 +3001,7 @@
2967 3001 static int selinux_file_ioctl(struct file *file, unsigned int cmd,
2968 3002 unsigned long arg)
2969 3003 {
  3004 + const struct cred *cred = current_cred();
2970 3005 u32 av = 0;
2971 3006  
2972 3007 if (_IOC_DIR(cmd) & _IOC_WRITE)
2973 3008  
... ... @@ -2976,11 +3011,13 @@
2976 3011 if (!av)
2977 3012 av = FILE__IOCTL;
2978 3013  
2979   - return file_has_perm(current, file, av);
  3014 + return file_has_perm(cred, file, av);
2980 3015 }
2981 3016  
2982 3017 static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
2983 3018 {
  3019 + const struct cred *cred = current_cred();
  3020 +
2984 3021 #ifndef CONFIG_PPC32
2985 3022 if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) {
2986 3023 /*
... ... @@ -3005,7 +3042,7 @@
3005 3042 if (prot & PROT_EXEC)
3006 3043 av |= FILE__EXECUTE;
3007 3044  
3008   - return file_has_perm(current, file, av);
  3045 + return file_has_perm(cred, file, av);
3009 3046 }
3010 3047 return 0;
3011 3048 }
... ... @@ -3034,6 +3071,7 @@
3034 3071 unsigned long reqprot,
3035 3072 unsigned long prot)
3036 3073 {
  3074 + const struct cred *cred = current_cred();
3037 3075 int rc;
3038 3076  
3039 3077 rc = secondary_ops->file_mprotect(vma, reqprot, prot);
... ... @@ -3062,7 +3100,7 @@
3062 3100 * modified content. This typically should only
3063 3101 * occur for text relocations.
3064 3102 */
3065   - rc = file_has_perm(current, vma->vm_file,
  3103 + rc = file_has_perm(cred, vma->vm_file,
3066 3104 FILE__EXECMOD);
3067 3105 }
3068 3106 if (rc)
3069 3107  
... ... @@ -3075,12 +3113,15 @@
3075 3113  
3076 3114 static int selinux_file_lock(struct file *file, unsigned int cmd)
3077 3115 {
3078   - return file_has_perm(current, file, FILE__LOCK);
  3116 + const struct cred *cred = current_cred();
  3117 +
  3118 + return file_has_perm(cred, file, FILE__LOCK);
3079 3119 }
3080 3120  
3081 3121 static int selinux_file_fcntl(struct file *file, unsigned int cmd,
3082 3122 unsigned long arg)
3083 3123 {
  3124 + const struct cred *cred = current_cred();
3084 3125 int err = 0;
3085 3126  
3086 3127 switch (cmd) {
... ... @@ -3091,7 +3132,7 @@
3091 3132 }
3092 3133  
3093 3134 if ((file->f_flags & O_APPEND) && !(arg & O_APPEND)) {
3094   - err = file_has_perm(current, file, FILE__WRITE);
  3135 + err = file_has_perm(cred, file, FILE__WRITE);
3095 3136 break;
3096 3137 }
3097 3138 /* fall through */
... ... @@ -3101,7 +3142,7 @@
3101 3142 case F_GETOWN:
3102 3143 case F_GETSIG:
3103 3144 /* Just check FD__USE permission */
3104   - err = file_has_perm(current, file, 0);
  3145 + err = file_has_perm(cred, file, 0);
3105 3146 break;
3106 3147 case F_GETLK:
3107 3148 case F_SETLK:
... ... @@ -3115,7 +3156,7 @@
3115 3156 err = -EINVAL;
3116 3157 break;
3117 3158 }
3118   - err = file_has_perm(current, file, FILE__LOCK);
  3159 + err = file_has_perm(cred, file, FILE__LOCK);
3119 3160 break;
3120 3161 }
3121 3162  
3122 3163  
... ... @@ -3156,11 +3197,14 @@
3156 3197  
3157 3198 static int selinux_file_receive(struct file *file)
3158 3199 {
3159   - return file_has_perm(current, file, file_to_av(file));
  3200 + const struct cred *cred = current_cred();
  3201 +
  3202 + return file_has_perm(cred, file, file_to_av(file));
3160 3203 }
3161 3204  
3162 3205 static int selinux_dentry_open(struct file *file)
3163 3206 {
  3207 + const struct cred *cred = current_cred();
3164 3208 struct file_security_struct *fsec;
3165 3209 struct inode *inode;
3166 3210 struct inode_security_struct *isec;
... ... @@ -3184,7 +3228,7 @@
3184 3228 * new inode label or new policy.
3185 3229 * This check is not redundant - do not remove.
3186 3230 */
3187   - return inode_has_perm(current, inode, open_file_to_av(file), NULL);
  3231 + return inode_has_perm(cred, inode, open_file_to_av(file), NULL);
3188 3232 }
3189 3233  
3190 3234 /* task security operations */