[PATCH 13/13] AppArmor: add support for generic perm query again current profile
John Johansen
john.johansen at canonical.com
Thu Aug 11 05:02:47 UTC 2011
The generic perm query replaces the remove perm_ipc. Also while only the
current task may set its security context, allow any task with sufficient
perms to query if the security context could be set.
Signed-off-by: John Johansen <john.johansen at canonical.com>
---
security/apparmor/file.c | 2 +-
security/apparmor/include/file.h | 2 ++
security/apparmor/include/procattr.h | 1 +
security/apparmor/lsm.c | 12 ++++++++----
security/apparmor/procattr.c | 34 ++++++++++++++++++++++++++++++++++
5 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 7312db7..2692333 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -155,7 +155,7 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
*
* Returns: new permission mapping
*/
-static u32 map_old_perms(u32 old)
+u32 map_old_perms(u32 old)
{
u32 new = old & 0xf;
if (old & MAY_READ)
diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
index ab8c6d8..632fdfb 100644
--- a/security/apparmor/include/file.h
+++ b/security/apparmor/include/file.h
@@ -186,6 +186,8 @@ static inline void aa_free_file_rules(struct aa_file_rules *rules)
aa_free_domain_entries(&rules->trans);
}
+u32 map_old_perms(u32 old);
+
#define ACC_FMODE(x) (("\000\004\002\006"[(x)&O_ACCMODE]) | (((x) << 1) & 0x40))
/* from namei.c */
diff --git a/security/apparmor/include/procattr.h b/security/apparmor/include/procattr.h
index 6bd5f33..224ffea 100644
--- a/security/apparmor/include/procattr.h
+++ b/security/apparmor/include/procattr.h
@@ -21,5 +21,6 @@
int aa_getprocattr(struct aa_profile *profile, char **string);
int aa_setprocattr_changehat(char *args, size_t size, int test);
int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test);
+int aa_setprocattr_perm(char *fqname, size_t size);
#endif /* __AA_PROCATTR_H */
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 93dea4d..29f6378 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -559,10 +559,6 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
args[size] = '\0';
}
- /* task can only write its own attributes */
- if (current != task)
- return -EACCES;
-
args = value;
args = strim(args);
command = strsep(&args, " ");
@@ -575,17 +571,25 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
arg_size = size - (args - (char *) value);
if (strcmp(name, "current") == 0) {
if (strcmp(command, "changehat") == 0) {
+ /* task can only write its own attributes */
+ if (current != task)
+ return -EACCES;
error = aa_setprocattr_changehat(args, arg_size,
!AA_DO_TEST);
} else if (strcmp(command, "permhat") == 0) {
error = aa_setprocattr_changehat(args, arg_size,
AA_DO_TEST);
} else if (strcmp(command, "changeprofile") == 0) {
+ /* task can only write its own attributes */
+ if (current != task)
+ return -EACCES;
error = aa_setprocattr_changeprofile(args, !AA_ONEXEC,
!AA_DO_TEST);
} else if (strcmp(command, "permprofile") == 0) {
error = aa_setprocattr_changeprofile(args, !AA_ONEXEC,
AA_DO_TEST);
+ } else if (strcmp(command, "perm") == 0) {
+ error = aa_setprocattr_perm(args, arg_size);
} else {
struct common_audit_data sa;
COMMON_AUDIT_DATA_INIT(&sa, NONE);
diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c
index 344970a..4ca37bc 100644
--- a/security/apparmor/procattr.c
+++ b/security/apparmor/procattr.c
@@ -162,3 +162,37 @@ int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test)
name = aa_split_fqname(fqname, &ns_name);
return aa_change_profile(ns_name, name, onexec, test);
}
+
+/**
+ * aa_setprocattr_perm - generic perm test can be used to determine transition
+ * @args: args from writting to /proc/<pid>/attr/current (NOT NULL)
+ * @size: size of the args
+ */
+int aa_setprocattr_perm(char *args, size_t size)
+{
+ struct aa_profile *profile;
+ char *permstr, *val = args;
+ u32 mask, perms;
+ unsigned int state;
+
+ if (!args)
+ return -EINVAL;
+ permstr = strsep(&val, " ");
+ if (!val)
+ return -EINVAL;
+ mask = simple_strtoul(permstr, NULL, 0);
+ size -= val - args;
+
+ profile = aa_current_profile();
+ if (profile->policy) {
+ state = aa_dfa_match_len(profile->policy, profile->policy_start,
+ args, size);
+ perms = map_old_perms(dfa_user_allow(profile->policy, state));
+ } else
+ perms = 0;
+
+ if (mask & ~perms)
+ return -EACCES;
+
+ return 0;
+}
--
1.7.5.4
More information about the kernel-team
mailing list