diff options
-rw-r--r-- | security/selinux/hooks.c | 140 |
1 files changed, 92 insertions, 48 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 3f3de565c242..cc6e5a3f10cc 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -173,16 +173,25 @@ static int cred_alloc_security(struct cred *cred) | |||
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 | * get the security ID of a task | 187 | * get the security ID of a task |
177 | */ | 188 | */ |
178 | static inline u32 task_sid(const struct task_struct *task) | 189 | static inline u32 task_sid(const struct task_struct *task) |
179 | { | 190 | { |
180 | const struct task_security_struct *tsec; | ||
181 | u32 sid; | 191 | u32 sid; |
182 | 192 | ||
183 | rcu_read_lock(); | 193 | rcu_read_lock(); |
184 | tsec = __task_cred(task)->security; | 194 | sid = cred_sid(__task_cred(task)); |
185 | sid = tsec->sid; | ||
186 | rcu_read_unlock(); | 195 | rcu_read_unlock(); |
187 | return sid; | 196 | return sid; |
188 | } | 197 | } |
@@ -197,6 +206,8 @@ static inline u32 current_sid(void) | |||
197 | return tsec->sid; | 206 | return tsec->sid; |
198 | } | 207 | } |
199 | 208 | ||
209 | /* Allocate and free functions for each kind of security blob. */ | ||
210 | |||
200 | static int inode_alloc_security(struct inode *inode) | 211 | static int inode_alloc_security(struct inode *inode) |
201 | { | 212 | { |
202 | struct inode_security_struct *isec; | 213 | struct inode_security_struct *isec; |
@@ -1368,7 +1379,7 @@ static inline u32 signal_to_av(int sig) | |||
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 | * fork check, ptrace check, etc. | 1383 | * fork check, ptrace check, etc. |
1373 | * tsk1 is the actor and tsk2 is the target | 1384 | * tsk1 is the actor and tsk2 is the target |
1374 | */ | 1385 | */ |
@@ -1437,7 +1448,7 @@ static int task_has_system(struct task_struct *tsk, | |||
1437 | /* Check whether a task has a particular permission to an inode. | 1448 | /* Check whether a task has a particular permission to an inode. |
1438 | The 'adp' parameter is optional and allows other audit | 1449 | The 'adp' parameter is optional and allows other audit |
1439 | data to be passed (e.g. the dentry). */ | 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 | struct inode *inode, | 1452 | struct inode *inode, |
1442 | u32 perms, | 1453 | u32 perms, |
1443 | struct avc_audit_data *adp) | 1454 | struct avc_audit_data *adp) |
@@ -1449,7 +1460,7 @@ static int inode_has_perm(struct task_struct *tsk, | |||
1449 | if (unlikely(IS_PRIVATE(inode))) | 1460 | if (unlikely(IS_PRIVATE(inode))) |
1450 | return 0; | 1461 | return 0; |
1451 | 1462 | ||
1452 | sid = task_sid(tsk); | 1463 | sid = cred_sid(cred); |
1453 | isec = inode->i_security; | 1464 | isec = inode->i_security; |
1454 | 1465 | ||
1455 | if (!adp) { | 1466 | if (!adp) { |
@@ -1464,17 +1475,18 @@ static int inode_has_perm(struct task_struct *tsk, | |||
1464 | /* Same as inode_has_perm, but pass explicit audit data containing | 1475 | /* Same as inode_has_perm, but pass explicit audit data containing |
1465 | the dentry to help the auditing code to more easily generate the | 1476 | the dentry to help the auditing code to more easily generate the |
1466 | pathname if needed. */ | 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 | struct vfsmount *mnt, | 1479 | struct vfsmount *mnt, |
1469 | struct dentry *dentry, | 1480 | struct dentry *dentry, |
1470 | u32 av) | 1481 | u32 av) |
1471 | { | 1482 | { |
1472 | struct inode *inode = dentry->d_inode; | 1483 | struct inode *inode = dentry->d_inode; |
1473 | struct avc_audit_data ad; | 1484 | struct avc_audit_data ad; |
1485 | |||
1474 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1486 | AVC_AUDIT_DATA_INIT(&ad, FS); |
1475 | ad.u.fs.path.mnt = mnt; | 1487 | ad.u.fs.path.mnt = mnt; |
1476 | ad.u.fs.path.dentry = dentry; | 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 | /* Check whether a task can use an open file descriptor to | 1492 | /* Check whether a task can use an open file descriptor to |
@@ -1485,14 +1497,14 @@ static inline int dentry_has_perm(struct task_struct *tsk, | |||
1485 | has the same SID as the process. If av is zero, then | 1497 | has the same SID as the process. If av is zero, then |
1486 | access to the file is not checked, e.g. for cases | 1498 | access to the file is not checked, e.g. for cases |
1487 | where only the descriptor is affected like seek. */ | 1499 | where only the descriptor is affected like seek. */ |
1488 | static int file_has_perm(struct task_struct *tsk, | 1500 | static int file_has_perm(const struct cred *cred, |
1489 | struct file *file, | 1501 | struct file *file, |
1490 | u32 av) | 1502 | u32 av) |
1491 | { | 1503 | { |
1492 | struct file_security_struct *fsec = file->f_security; | 1504 | struct file_security_struct *fsec = file->f_security; |
1493 | struct inode *inode = file->f_path.dentry->d_inode; | 1505 | struct inode *inode = file->f_path.dentry->d_inode; |
1494 | struct avc_audit_data ad; | 1506 | struct avc_audit_data ad; |
1495 | u32 sid = task_sid(tsk); | 1507 | u32 sid = cred_sid(cred); |
1496 | int rc; | 1508 | int rc; |
1497 | 1509 | ||
1498 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1510 | AVC_AUDIT_DATA_INIT(&ad, FS); |
@@ -1504,14 +1516,16 @@ static int file_has_perm(struct task_struct *tsk, | |||
1504 | FD__USE, | 1516 | FD__USE, |
1505 | &ad); | 1517 | &ad); |
1506 | if (rc) | 1518 | if (rc) |
1507 | return rc; | 1519 | goto out; |
1508 | } | 1520 | } |
1509 | 1521 | ||
1510 | /* av is zero if only checking access to the descriptor. */ | 1522 | /* av is zero if only checking access to the descriptor. */ |
1523 | rc = 0; | ||
1511 | if (av) | 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 | /* Check whether a task can create a file. */ | 1531 | /* Check whether a task can create a file. */ |
@@ -1670,13 +1684,13 @@ static inline int may_rename(struct inode *old_dir, | |||
1670 | } | 1684 | } |
1671 | 1685 | ||
1672 | /* Check whether a task can perform a filesystem operation. */ | 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 | struct super_block *sb, | 1688 | struct super_block *sb, |
1675 | u32 perms, | 1689 | u32 perms, |
1676 | struct avc_audit_data *ad) | 1690 | struct avc_audit_data *ad) |
1677 | { | 1691 | { |
1678 | struct superblock_security_struct *sbsec; | 1692 | struct superblock_security_struct *sbsec; |
1679 | u32 sid = task_sid(tsk); | 1693 | u32 sid = cred_sid(cred); |
1680 | 1694 | ||
1681 | sbsec = sb->s_security; | 1695 | sbsec = sb->s_security; |
1682 | return avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad); | 1696 | return avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad); |
@@ -1919,6 +1933,7 @@ static int selinux_sysctl(ctl_table *table, int op) | |||
1919 | 1933 | ||
1920 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) | 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 | int rc = 0; | 1937 | int rc = 0; |
1923 | 1938 | ||
1924 | if (!sb) | 1939 | if (!sb) |
@@ -1930,14 +1945,12 @@ static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) | |||
1930 | case Q_QUOTAOFF: | 1945 | case Q_QUOTAOFF: |
1931 | case Q_SETINFO: | 1946 | case Q_SETINFO: |
1932 | case Q_SETQUOTA: | 1947 | case Q_SETQUOTA: |
1933 | rc = superblock_has_perm(current, sb, FILESYSTEM__QUOTAMOD, | 1948 | rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAMOD, NULL); |
1934 | NULL); | ||
1935 | break; | 1949 | break; |
1936 | case Q_GETFMT: | 1950 | case Q_GETFMT: |
1937 | case Q_GETINFO: | 1951 | case Q_GETINFO: |
1938 | case Q_GETQUOTA: | 1952 | case Q_GETQUOTA: |
1939 | rc = superblock_has_perm(current, sb, FILESYSTEM__QUOTAGET, | 1953 | rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAGET, NULL); |
1940 | NULL); | ||
1941 | break; | 1954 | break; |
1942 | default: | 1955 | default: |
1943 | rc = 0; /* let the kernel handle invalid cmds */ | 1956 | rc = 0; /* let the kernel handle invalid cmds */ |
@@ -1948,7 +1961,9 @@ static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) | |||
1948 | 1961 | ||
1949 | static int selinux_quota_on(struct dentry *dentry) | 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 | static int selinux_syslog(int type) | 1969 | static int selinux_syslog(int type) |
@@ -2137,6 +2152,7 @@ extern struct dentry *selinux_null; | |||
2137 | /* Derived from fs/exec.c:flush_old_files. */ | 2152 | /* Derived from fs/exec.c:flush_old_files. */ |
2138 | static inline void flush_unauthorized_files(struct files_struct *files) | 2153 | static inline void flush_unauthorized_files(struct files_struct *files) |
2139 | { | 2154 | { |
2155 | const struct cred *cred = current_cred(); | ||
2140 | struct avc_audit_data ad; | 2156 | struct avc_audit_data ad; |
2141 | struct file *file, *devnull = NULL; | 2157 | struct file *file, *devnull = NULL; |
2142 | struct tty_struct *tty; | 2158 | struct tty_struct *tty; |
@@ -2157,7 +2173,7 @@ static inline void flush_unauthorized_files(struct files_struct *files) | |||
2157 | interested in the inode-based check here. */ | 2173 | interested in the inode-based check here. */ |
2158 | file = list_first_entry(&tty->tty_files, struct file, f_u.fu_list); | 2174 | file = list_first_entry(&tty->tty_files, struct file, f_u.fu_list); |
2159 | inode = file->f_path.dentry->d_inode; | 2175 | inode = file->f_path.dentry->d_inode; |
2160 | if (inode_has_perm(current, inode, | 2176 | if (inode_has_perm(cred, inode, |
2161 | FILE__READ | FILE__WRITE, NULL)) { | 2177 | FILE__READ | FILE__WRITE, NULL)) { |
2162 | drop_tty = 1; | 2178 | drop_tty = 1; |
2163 | } | 2179 | } |
@@ -2192,7 +2208,7 @@ static inline void flush_unauthorized_files(struct files_struct *files) | |||
2192 | file = fget(i); | 2208 | file = fget(i); |
2193 | if (!file) | 2209 | if (!file) |
2194 | continue; | 2210 | continue; |
2195 | if (file_has_perm(current, | 2211 | if (file_has_perm(cred, |
2196 | file, | 2212 | file, |
2197 | file_to_av(file))) { | 2213 | file_to_av(file))) { |
2198 | sys_close(i); | 2214 | sys_close(i); |
@@ -2465,6 +2481,7 @@ out: | |||
2465 | 2481 | ||
2466 | static int selinux_sb_kern_mount(struct super_block *sb, void *data) | 2482 | static int selinux_sb_kern_mount(struct super_block *sb, void *data) |
2467 | { | 2483 | { |
2484 | const struct cred *cred = current_cred(); | ||
2468 | struct avc_audit_data ad; | 2485 | struct avc_audit_data ad; |
2469 | int rc; | 2486 | int rc; |
2470 | 2487 | ||
@@ -2474,16 +2491,17 @@ static int selinux_sb_kern_mount(struct super_block *sb, void *data) | |||
2474 | 2491 | ||
2475 | AVC_AUDIT_DATA_INIT(&ad, FS); | 2492 | AVC_AUDIT_DATA_INIT(&ad, FS); |
2476 | ad.u.fs.path.dentry = sb->s_root; | 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 | static int selinux_sb_statfs(struct dentry *dentry) | 2497 | static int selinux_sb_statfs(struct dentry *dentry) |
2481 | { | 2498 | { |
2499 | const struct cred *cred = current_cred(); | ||
2482 | struct avc_audit_data ad; | 2500 | struct avc_audit_data ad; |
2483 | 2501 | ||
2484 | AVC_AUDIT_DATA_INIT(&ad, FS); | 2502 | AVC_AUDIT_DATA_INIT(&ad, FS); |
2485 | ad.u.fs.path.dentry = dentry->d_sb->s_root; | 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 | static int selinux_mount(char *dev_name, | 2507 | static int selinux_mount(char *dev_name, |
@@ -2492,6 +2510,7 @@ static int selinux_mount(char *dev_name, | |||
2492 | unsigned long flags, | 2510 | unsigned long flags, |
2493 | void *data) | 2511 | void *data) |
2494 | { | 2512 | { |
2513 | const struct cred *cred = current_cred(); | ||
2495 | int rc; | 2514 | int rc; |
2496 | 2515 | ||
2497 | rc = secondary_ops->sb_mount(dev_name, path, type, flags, data); | 2516 | rc = secondary_ops->sb_mount(dev_name, path, type, flags, data); |
@@ -2499,22 +2518,23 @@ static int selinux_mount(char *dev_name, | |||
2499 | return rc; | 2518 | return rc; |
2500 | 2519 | ||
2501 | if (flags & MS_REMOUNT) | 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 | FILESYSTEM__REMOUNT, NULL); | 2522 | FILESYSTEM__REMOUNT, NULL); |
2504 | else | 2523 | else |
2505 | return dentry_has_perm(current, path->mnt, path->dentry, | 2524 | return dentry_has_perm(cred, path->mnt, path->dentry, |
2506 | FILE__MOUNTON); | 2525 | FILE__MOUNTON); |
2507 | } | 2526 | } |
2508 | 2527 | ||
2509 | static int selinux_umount(struct vfsmount *mnt, int flags) | 2528 | static int selinux_umount(struct vfsmount *mnt, int flags) |
2510 | { | 2529 | { |
2530 | const struct cred *cred = current_cred(); | ||
2511 | int rc; | 2531 | int rc; |
2512 | 2532 | ||
2513 | rc = secondary_ops->sb_umount(mnt, flags); | 2533 | rc = secondary_ops->sb_umount(mnt, flags); |
2514 | if (rc) | 2534 | if (rc) |
2515 | return rc; | 2535 | return rc; |
2516 | 2536 | ||
2517 | return superblock_has_perm(current, mnt->mnt_sb, | 2537 | return superblock_has_perm(cred, mnt->mnt_sb, |
2518 | FILESYSTEM__UNMOUNT, NULL); | 2538 | FILESYSTEM__UNMOUNT, NULL); |
2519 | } | 2539 | } |
2520 | 2540 | ||
@@ -2652,21 +2672,25 @@ static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dent | |||
2652 | 2672 | ||
2653 | static int selinux_inode_readlink(struct dentry *dentry) | 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 | static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata) | 2680 | static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata) |
2659 | { | 2681 | { |
2682 | const struct cred *cred = current_cred(); | ||
2660 | int rc; | 2683 | int rc; |
2661 | 2684 | ||
2662 | rc = secondary_ops->inode_follow_link(dentry, nameidata); | 2685 | rc = secondary_ops->inode_follow_link(dentry, nameidata); |
2663 | if (rc) | 2686 | if (rc) |
2664 | return rc; | 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 | static int selinux_inode_permission(struct inode *inode, int mask) | 2691 | static int selinux_inode_permission(struct inode *inode, int mask) |
2669 | { | 2692 | { |
2693 | const struct cred *cred = current_cred(); | ||
2670 | int rc; | 2694 | int rc; |
2671 | 2695 | ||
2672 | rc = secondary_ops->inode_permission(inode, mask); | 2696 | rc = secondary_ops->inode_permission(inode, mask); |
@@ -2678,12 +2702,13 @@ static int selinux_inode_permission(struct inode *inode, int mask) | |||
2678 | return 0; | 2702 | return 0; |
2679 | } | 2703 | } |
2680 | 2704 | ||
2681 | return inode_has_perm(current, inode, | 2705 | return inode_has_perm(cred, inode, |
2682 | file_mask_to_av(inode->i_mode, mask), NULL); | 2706 | file_mask_to_av(inode->i_mode, mask), NULL); |
2683 | } | 2707 | } |
2684 | 2708 | ||
2685 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | 2709 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) |
2686 | { | 2710 | { |
2711 | const struct cred *cred = current_cred(); | ||
2687 | int rc; | 2712 | int rc; |
2688 | 2713 | ||
2689 | rc = secondary_ops->inode_setattr(dentry, iattr); | 2714 | rc = secondary_ops->inode_setattr(dentry, iattr); |
@@ -2695,18 +2720,22 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | |||
2695 | 2720 | ||
2696 | if (iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | | 2721 | if (iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | |
2697 | ATTR_ATIME_SET | ATTR_MTIME_SET)) | 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 | static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) | 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 | static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) | 2735 | static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) |
2709 | { | 2736 | { |
2737 | const struct cred *cred = current_cred(); | ||
2738 | |||
2710 | if (!strncmp(name, XATTR_SECURITY_PREFIX, | 2739 | if (!strncmp(name, XATTR_SECURITY_PREFIX, |
2711 | sizeof XATTR_SECURITY_PREFIX - 1)) { | 2740 | sizeof XATTR_SECURITY_PREFIX - 1)) { |
2712 | if (!strcmp(name, XATTR_NAME_CAPS)) { | 2741 | if (!strcmp(name, XATTR_NAME_CAPS)) { |
@@ -2721,7 +2750,7 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) | |||
2721 | 2750 | ||
2722 | /* Not an attribute we recognize, so just check the | 2751 | /* Not an attribute we recognize, so just check the |
2723 | ordinary setattr permission. */ | 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 | static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | 2756 | static int selinux_inode_setxattr(struct dentry *dentry, const char *name, |
@@ -2806,12 +2835,16 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, | |||
2806 | 2835 | ||
2807 | static int selinux_inode_getxattr(struct dentry *dentry, const char *name) | 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 | static int selinux_inode_listxattr(struct dentry *dentry) | 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 | static int selinux_inode_removexattr(struct dentry *dentry, const char *name) | 2850 | static int selinux_inode_removexattr(struct dentry *dentry, const char *name) |
@@ -2915,6 +2948,7 @@ static void selinux_inode_getsecid(const struct inode *inode, u32 *secid) | |||
2915 | 2948 | ||
2916 | static int selinux_revalidate_file_permission(struct file *file, int mask) | 2949 | static int selinux_revalidate_file_permission(struct file *file, int mask) |
2917 | { | 2950 | { |
2951 | const struct cred *cred = current_cred(); | ||
2918 | int rc; | 2952 | int rc; |
2919 | struct inode *inode = file->f_path.dentry->d_inode; | 2953 | struct inode *inode = file->f_path.dentry->d_inode; |
2920 | 2954 | ||
@@ -2927,7 +2961,7 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) | |||
2927 | if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) | 2961 | if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) |
2928 | mask |= MAY_APPEND; | 2962 | mask |= MAY_APPEND; |
2929 | 2963 | ||
2930 | rc = file_has_perm(current, file, | 2964 | rc = file_has_perm(cred, file, |
2931 | file_mask_to_av(inode->i_mode, mask)); | 2965 | file_mask_to_av(inode->i_mode, mask)); |
2932 | if (rc) | 2966 | if (rc) |
2933 | return rc; | 2967 | return rc; |
@@ -2967,6 +3001,7 @@ static void selinux_file_free_security(struct file *file) | |||
2967 | static int selinux_file_ioctl(struct file *file, unsigned int cmd, | 3001 | static int selinux_file_ioctl(struct file *file, unsigned int cmd, |
2968 | unsigned long arg) | 3002 | unsigned long arg) |
2969 | { | 3003 | { |
3004 | const struct cred *cred = current_cred(); | ||
2970 | u32 av = 0; | 3005 | u32 av = 0; |
2971 | 3006 | ||
2972 | if (_IOC_DIR(cmd) & _IOC_WRITE) | 3007 | if (_IOC_DIR(cmd) & _IOC_WRITE) |
@@ -2976,11 +3011,13 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, | |||
2976 | if (!av) | 3011 | if (!av) |
2977 | av = FILE__IOCTL; | 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 | static int file_map_prot_check(struct file *file, unsigned long prot, int shared) | 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 | #ifndef CONFIG_PPC32 | 3021 | #ifndef CONFIG_PPC32 |
2985 | if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) { | 3022 | if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) { |
2986 | /* | 3023 | /* |
@@ -3005,7 +3042,7 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared | |||
3005 | if (prot & PROT_EXEC) | 3042 | if (prot & PROT_EXEC) |
3006 | av |= FILE__EXECUTE; | 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 | return 0; | 3047 | return 0; |
3011 | } | 3048 | } |
@@ -3034,6 +3071,7 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, | |||
3034 | unsigned long reqprot, | 3071 | unsigned long reqprot, |
3035 | unsigned long prot) | 3072 | unsigned long prot) |
3036 | { | 3073 | { |
3074 | const struct cred *cred = current_cred(); | ||
3037 | int rc; | 3075 | int rc; |
3038 | 3076 | ||
3039 | rc = secondary_ops->file_mprotect(vma, reqprot, prot); | 3077 | rc = secondary_ops->file_mprotect(vma, reqprot, prot); |
@@ -3062,7 +3100,7 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, | |||
3062 | * modified content. This typically should only | 3100 | * modified content. This typically should only |
3063 | * occur for text relocations. | 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 | FILE__EXECMOD); | 3104 | FILE__EXECMOD); |
3067 | } | 3105 | } |
3068 | if (rc) | 3106 | if (rc) |
@@ -3075,12 +3113,15 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, | |||
3075 | 3113 | ||
3076 | static int selinux_file_lock(struct file *file, unsigned int cmd) | 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 | static int selinux_file_fcntl(struct file *file, unsigned int cmd, | 3121 | static int selinux_file_fcntl(struct file *file, unsigned int cmd, |
3082 | unsigned long arg) | 3122 | unsigned long arg) |
3083 | { | 3123 | { |
3124 | const struct cred *cred = current_cred(); | ||
3084 | int err = 0; | 3125 | int err = 0; |
3085 | 3126 | ||
3086 | switch (cmd) { | 3127 | switch (cmd) { |
@@ -3091,7 +3132,7 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd, | |||
3091 | } | 3132 | } |
3092 | 3133 | ||
3093 | if ((file->f_flags & O_APPEND) && !(arg & O_APPEND)) { | 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 | break; | 3136 | break; |
3096 | } | 3137 | } |
3097 | /* fall through */ | 3138 | /* fall through */ |
@@ -3101,7 +3142,7 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd, | |||
3101 | case F_GETOWN: | 3142 | case F_GETOWN: |
3102 | case F_GETSIG: | 3143 | case F_GETSIG: |
3103 | /* Just check FD__USE permission */ | 3144 | /* Just check FD__USE permission */ |
3104 | err = file_has_perm(current, file, 0); | 3145 | err = file_has_perm(cred, file, 0); |
3105 | break; | 3146 | break; |
3106 | case F_GETLK: | 3147 | case F_GETLK: |
3107 | case F_SETLK: | 3148 | case F_SETLK: |
@@ -3115,7 +3156,7 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd, | |||
3115 | err = -EINVAL; | 3156 | err = -EINVAL; |
3116 | break; | 3157 | break; |
3117 | } | 3158 | } |
3118 | err = file_has_perm(current, file, FILE__LOCK); | 3159 | err = file_has_perm(cred, file, FILE__LOCK); |
3119 | break; | 3160 | break; |
3120 | } | 3161 | } |
3121 | 3162 | ||
@@ -3156,11 +3197,14 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk, | |||
3156 | 3197 | ||
3157 | static int selinux_file_receive(struct file *file) | 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 | static int selinux_dentry_open(struct file *file) | 3205 | static int selinux_dentry_open(struct file *file) |
3163 | { | 3206 | { |
3207 | const struct cred *cred = current_cred(); | ||
3164 | struct file_security_struct *fsec; | 3208 | struct file_security_struct *fsec; |
3165 | struct inode *inode; | 3209 | struct inode *inode; |
3166 | struct inode_security_struct *isec; | 3210 | struct inode_security_struct *isec; |
@@ -3184,7 +3228,7 @@ static int selinux_dentry_open(struct file *file) | |||
3184 | * new inode label or new policy. | 3228 | * new inode label or new policy. |
3185 | * This check is not redundant - do not remove. | 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 | /* task security operations */ | 3234 | /* task security operations */ |