diff options
author | Eric Paris <eparis@redhat.com> | 2012-01-03 12:25:14 -0500 |
---|---|---|
committer | Eric Paris <eparis@redhat.com> | 2012-01-05 18:52:53 -0500 |
commit | 6a9de49115d5ff9871d953af1a5c8249e1585731 (patch) | |
tree | eee3700ccc2ce26c566bfe99129e646fac9f983e /security/selinux | |
parent | 2653812e14f4e16688ec8247d7fd290bdbbc4747 (diff) |
capabilities: remove the task from capable LSM hook entirely
The capabilities framework is based around credentials, not necessarily the
current task. Yet we still passed the current task down into LSMs from the
security_capable() LSM hook as if it was a meaningful portion of the security
decision. This patch removes the 'generic' passing of current and instead
forces individual LSMs to use current explicitly if they think it is
appropriate. In our case those LSMs are SELinux and AppArmor.
I believe the AppArmor use of current is incorrect, but that is wholely
unrelated to this patch. This patch does not change what AppArmor does, it
just makes it clear in the AppArmor code that it is doing it.
The SELinux code still uses current in it's audit message, which may also be
wrong and needs further investigation. Again this is NOT a change, it may
have always been wrong, this patch just makes it clear what is happening.
Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/hooks.c | 23 |
1 files changed, 10 insertions, 13 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index e545b9f67072..c9605c4a2e08 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1414,8 +1414,7 @@ static int current_has_perm(const struct task_struct *tsk, | |||
1414 | #endif | 1414 | #endif |
1415 | 1415 | ||
1416 | /* Check whether a task is allowed to use a capability. */ | 1416 | /* Check whether a task is allowed to use a capability. */ |
1417 | static int task_has_capability(struct task_struct *tsk, | 1417 | static int cred_has_capability(const struct cred *cred, |
1418 | const struct cred *cred, | ||
1419 | int cap, int audit) | 1418 | int cap, int audit) |
1420 | { | 1419 | { |
1421 | struct common_audit_data ad; | 1420 | struct common_audit_data ad; |
@@ -1426,7 +1425,7 @@ static int task_has_capability(struct task_struct *tsk, | |||
1426 | int rc; | 1425 | int rc; |
1427 | 1426 | ||
1428 | COMMON_AUDIT_DATA_INIT(&ad, CAP); | 1427 | COMMON_AUDIT_DATA_INIT(&ad, CAP); |
1429 | ad.tsk = tsk; | 1428 | ad.tsk = current; |
1430 | ad.u.cap = cap; | 1429 | ad.u.cap = cap; |
1431 | 1430 | ||
1432 | switch (CAP_TO_INDEX(cap)) { | 1431 | switch (CAP_TO_INDEX(cap)) { |
@@ -1867,16 +1866,16 @@ static int selinux_capset(struct cred *new, const struct cred *old, | |||
1867 | * the CAP_SETUID and CAP_SETGID capabilities using the capable hook. | 1866 | * the CAP_SETUID and CAP_SETGID capabilities using the capable hook. |
1868 | */ | 1867 | */ |
1869 | 1868 | ||
1870 | static int selinux_capable(struct task_struct *tsk, const struct cred *cred, | 1869 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, |
1871 | struct user_namespace *ns, int cap, int audit) | 1870 | int cap, int audit) |
1872 | { | 1871 | { |
1873 | int rc; | 1872 | int rc; |
1874 | 1873 | ||
1875 | rc = cap_capable(tsk, cred, ns, cap, audit); | 1874 | rc = cap_capable(cred, ns, cap, audit); |
1876 | if (rc) | 1875 | if (rc) |
1877 | return rc; | 1876 | return rc; |
1878 | 1877 | ||
1879 | return task_has_capability(tsk, cred, cap, audit); | 1878 | return cred_has_capability(cred, cap, audit); |
1880 | } | 1879 | } |
1881 | 1880 | ||
1882 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) | 1881 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) |
@@ -1953,8 +1952,7 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
1953 | { | 1952 | { |
1954 | int rc, cap_sys_admin = 0; | 1953 | int rc, cap_sys_admin = 0; |
1955 | 1954 | ||
1956 | rc = selinux_capable(current, current_cred(), | 1955 | rc = selinux_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN, |
1957 | &init_user_ns, CAP_SYS_ADMIN, | ||
1958 | SECURITY_CAP_NOAUDIT); | 1956 | SECURITY_CAP_NOAUDIT); |
1959 | if (rc == 0) | 1957 | if (rc == 0) |
1960 | cap_sys_admin = 1; | 1958 | cap_sys_admin = 1; |
@@ -2858,8 +2856,7 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name | |||
2858 | * and lack of permission just means that we fall back to the | 2856 | * and lack of permission just means that we fall back to the |
2859 | * in-core context value, not a denial. | 2857 | * in-core context value, not a denial. |
2860 | */ | 2858 | */ |
2861 | error = selinux_capable(current, current_cred(), | 2859 | error = selinux_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN, |
2862 | &init_user_ns, CAP_MAC_ADMIN, | ||
2863 | SECURITY_CAP_NOAUDIT); | 2860 | SECURITY_CAP_NOAUDIT); |
2864 | if (!error) | 2861 | if (!error) |
2865 | error = security_sid_to_context_force(isec->sid, &context, | 2862 | error = security_sid_to_context_force(isec->sid, &context, |
@@ -2992,8 +2989,8 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, | |||
2992 | 2989 | ||
2993 | case KDSKBENT: | 2990 | case KDSKBENT: |
2994 | case KDSKBSENT: | 2991 | case KDSKBSENT: |
2995 | error = task_has_capability(current, cred, CAP_SYS_TTY_CONFIG, | 2992 | error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, |
2996 | SECURITY_CAP_AUDIT); | 2993 | SECURITY_CAP_AUDIT); |
2997 | break; | 2994 | break; |
2998 | 2995 | ||
2999 | /* default case assumes that the command will go | 2996 | /* default case assumes that the command will go |