mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
Further audit fixes/cleanups
This commit is contained in:
parent
fe02a75aa1
commit
60d2b63e42
6 changed files with 955 additions and 0 deletions
515
kernel-patches/for-mainline/mangle_on_audit-2.diff
Normal file
515
kernel-patches/for-mainline/mangle_on_audit-2.diff
Normal file
|
@ -0,0 +1,515 @@
|
|||
|
||||
* Remove the flags parameter of aa_audit_message -- it is always set to 0.
|
||||
|
||||
* Replace AA_REJECT_MSG() with direct calls to aa_audit_message().
|
||||
|
||||
* Stuff buffer2 in struct aa_audit together with name2; the two are always
|
||||
used together.
|
||||
|
||||
* Add the AA_MANGLE_NAME and AA_MANGLE_NAME2 bitflags which indicate with of
|
||||
the names in struct aa_audit need mangling.
|
||||
|
||||
* AA_AUDITTYPE__END is a dead definition.
|
||||
|
||||
* Add AA_CHECK_MANGLE flag for aa_get_name(), which makes sure that the
|
||||
allocated buffer leaves enough space for name mangling. This flag is
|
||||
only used when really necessary on the "interesting" code paths, and
|
||||
always in aa_register() because there it doesn't really matter, anyway.
|
||||
|
||||
* Further improve the mangle() comment: it is *possible* to use a string
|
||||
and a separate buffer, but that's not really intended, not necessary, and
|
||||
it might lead to really nasty bugs in the future, so don't document that
|
||||
possibility. Also clean up the const-ness there.
|
||||
|
||||
* Replace mangle_buffer(): fail aa_audit() with -ENAMETOOLONG for the usual
|
||||
pathnames (this will practically never trigger), and make sure that
|
||||
aa_register() and aa_register_find() will not lead to failues in the first
|
||||
place with AA_CHECK_MANGLE.
|
||||
|
||||
---
|
||||
security/apparmor/apparmor.h | 37 +++----
|
||||
security/apparmor/main.c | 205 +++++++++++++++++++++----------------------
|
||||
2 files changed, 120 insertions(+), 122 deletions(-)
|
||||
|
||||
--- a/security/apparmor/apparmor.h
|
||||
+++ b/security/apparmor/apparmor.h
|
||||
@@ -69,17 +69,10 @@ extern unsigned int apparmor_path_max;
|
||||
#define AA_INFO(gfp, fmt, args...) \
|
||||
do { \
|
||||
printk(KERN_INFO "AppArmor: " fmt "\n", ##args); \
|
||||
- aa_audit_message(NULL, (gfp), 0, fmt, ##args); \
|
||||
+ aa_audit_message(NULL, (gfp), fmt, ##args); \
|
||||
} while (0)
|
||||
#define AA_WARN(gfp, fmt, args...) \
|
||||
- aa_audit_message(NULL, (gfp), 0, fmt, ##args);
|
||||
-
|
||||
-#define AA_REJECT_MSG(p, gfp, fmt, args...) \
|
||||
- aa_audit_message((p), (gfp), 0, \
|
||||
- "REJECTING " fmt \
|
||||
- " (%d profile %s active %s)", ##args, \
|
||||
- current->pid, \
|
||||
- (p)->parent->name, (p)->name)
|
||||
+ aa_audit_message(NULL, (gfp), fmt, ##args);
|
||||
|
||||
#define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args)
|
||||
|
||||
@@ -165,26 +158,29 @@ struct aa_audit {
|
||||
int error_code;
|
||||
const char *name;
|
||||
char *buffer;
|
||||
- char *buffer2;
|
||||
union {
|
||||
int mask;
|
||||
int capability;
|
||||
- const char *name2;
|
||||
+ struct {
|
||||
+ const char *name2;
|
||||
+ char *buffer2;
|
||||
+ };
|
||||
struct iattr *iattr;
|
||||
va_list vaval;
|
||||
};
|
||||
};
|
||||
|
||||
/* audit types */
|
||||
-#define AA_AUDITTYPE_FILE 1
|
||||
-#define AA_AUDITTYPE_DIR 2
|
||||
-#define AA_AUDITTYPE_ATTR 3
|
||||
-#define AA_AUDITTYPE_XATTR 4
|
||||
-#define AA_AUDITTYPE_LINK 5
|
||||
+#define AA_MANGLE_NAME 32
|
||||
+#define AA_MANGLE_NAME2 64
|
||||
+#define AA_AUDITTYPE_FILE (1 | AA_MANGLE_NAME)
|
||||
+#define AA_AUDITTYPE_DIR (2 | AA_MANGLE_NAME)
|
||||
+#define AA_AUDITTYPE_ATTR (3 | AA_MANGLE_NAME)
|
||||
+#define AA_AUDITTYPE_XATTR (4 | AA_MANGLE_NAME)
|
||||
+#define AA_AUDITTYPE_LINK (5 | AA_MANGLE_NAME | AA_MANGLE_NAME2)
|
||||
#define AA_AUDITTYPE_CAP 6
|
||||
#define AA_AUDITTYPE_MSG 7
|
||||
#define AA_AUDITTYPE_SYSCALL 8
|
||||
-#define AA_AUDITTYPE__END 9
|
||||
|
||||
/* audit flags */
|
||||
#define AA_AUDITFLAG_AUDITSS_SYSCALL 1 /* log syscall context */
|
||||
@@ -198,7 +194,7 @@ struct aa_audit {
|
||||
#define HINT_PTRACE "ptrace"
|
||||
|
||||
#define LOG_HINT(p, gfp, hint, fmt, args...) \
|
||||
- aa_audit_message((p), (gfp), 0, \
|
||||
+ aa_audit_message((p), (gfp), \
|
||||
"LOGPROF-HINT " hint " " fmt \
|
||||
" (%d profile %s active %s)", ##args, \
|
||||
current->pid, \
|
||||
@@ -208,16 +204,17 @@ struct aa_audit {
|
||||
#define AA_CHECK_LEAF 1 /* this is the leaf lookup component */
|
||||
#define AA_CHECK_FD 2 /* coming from a file descriptor */
|
||||
#define AA_CHECK_DIR 4 /* file type is directory */
|
||||
+#define AA_CHECK_MANGLE 8 /* leave extra room for name mangling */
|
||||
|
||||
/* main.c */
|
||||
extern int alloc_null_complain_profile(void);
|
||||
extern void free_null_complain_profile(void);
|
||||
extern int attach_nullprofile(struct aa_profile *profile);
|
||||
-extern int aa_audit_message(struct aa_profile *profile, gfp_t gfp, int,
|
||||
+extern int aa_audit_message(struct aa_profile *profile, gfp_t gfp,
|
||||
const char *, ...);
|
||||
extern int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp,
|
||||
const char *);
|
||||
-extern int aa_audit(struct aa_profile *profile, const struct aa_audit *);
|
||||
+extern int aa_audit(struct aa_profile *profile, struct aa_audit *);
|
||||
|
||||
extern int aa_attr(struct aa_profile *profile, struct dentry *dentry,
|
||||
struct vfsmount *mnt, struct iattr *iattr);
|
||||
--- a/security/apparmor/main.c
|
||||
+++ b/security/apparmor/main.c
|
||||
@@ -105,17 +105,18 @@ static int aa_link_denied(struct aa_prof
|
||||
/**
|
||||
* mangle -- escape special characters in str
|
||||
* @str: string to escape
|
||||
- * @buffer: buffer possibly containing str
|
||||
+ * @buffer: buffer containing str
|
||||
*
|
||||
- * Escape special characters in @str, which may be contained in
|
||||
- * @buffer. If @str is contained in @buffer it is assumed it is at the
|
||||
- * end of @buffer and the string is relocated to the beginning of @buffer.
|
||||
- * If @str is not contained in @buffer, @buffer must be large enough that
|
||||
- * escaping all special characters in @str will not overwrite the end of
|
||||
- * the buffer.
|
||||
- * Returns a pointer to the escaped string, NULL upon failure.
|
||||
+ * Escape special characters in @str, which is contained in @buffer. @str must
|
||||
+ * be aligned to the end of the buffer, and the space between @buffer and @str
|
||||
+ * may be used for escaping.
|
||||
+ *
|
||||
+ * Returns @str if no escaping was necessary, a pointer to the beginning of the
|
||||
+ * escaped string, or NULL if there was not enough space in @buffer. When
|
||||
+ * called with a NULL buffer, the return value tells whether any escaping is
|
||||
+ * necessary.
|
||||
*/
|
||||
-static char *mangle(const char *str, char *buffer)
|
||||
+static const char *mangle(const char *str, char *buffer)
|
||||
{
|
||||
static const char c_escape[] = {
|
||||
['\a'] = 'a', ['\b'] = 'b',
|
||||
@@ -124,13 +125,14 @@ static char *mangle(const char *str, cha
|
||||
['\v'] = 'v',
|
||||
[' '] = ' ', ['\\'] = '\\',
|
||||
};
|
||||
- char *s, *t, c;
|
||||
+ const char *s;
|
||||
+ char *t, c;
|
||||
|
||||
#define mangle_escape(c) \
|
||||
unlikely((unsigned char)(c) < ARRAY_SIZE(c_escape) && \
|
||||
c_escape[(unsigned char)c])
|
||||
|
||||
- for (s = str; (c = *s) != '\0'; s++)
|
||||
+ for (s = (char *)str; (c = *s) != '\0'; s++)
|
||||
if (mangle_escape(c))
|
||||
goto escape;
|
||||
return str;
|
||||
@@ -150,32 +152,8 @@ escape:
|
||||
*t++ = '\0';
|
||||
|
||||
#undef mangle_escape
|
||||
- return buffer;
|
||||
-}
|
||||
|
||||
-
|
||||
-/**
|
||||
- * mangle -- escape special characters in str
|
||||
- * @str: string to escape
|
||||
- * @buffer: buffer possibly containing str
|
||||
- *
|
||||
- * escape special characters in @str, which is contained in @buffer, if
|
||||
- * @buffer is not large enough it will be reallocated.
|
||||
- * returns pointer to escaped string or NULL upon failure.
|
||||
- */
|
||||
-static char *mangle_buffer(const char *str, char **buffer)
|
||||
-{
|
||||
- char *b = mangle(str, *buffer);
|
||||
- if (!b) {
|
||||
- b = kmalloc(strlen(str) * 2 + 1, GFP_KERNEL);
|
||||
- if (b) {
|
||||
- mangle(str, b);
|
||||
- kfree(*buffer);
|
||||
- *buffer = b;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return b;
|
||||
+ return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,6 +183,12 @@ static char *aa_get_name(struct dentry *
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
name = d_namespace_path(dentry, mnt, buf, size - is_dir);
|
||||
+
|
||||
+ /* Make sure we have enough space for name mangling. */
|
||||
+ if (!IS_ERR(name) &&
|
||||
+ (check & AA_CHECK_MANGLE) && name - buf <= size / 2)
|
||||
+ name = ERR_PTR(-ENAMETOOLONG);
|
||||
+
|
||||
if (!IS_ERR(name)) {
|
||||
if (name[0] != '/') {
|
||||
/*
|
||||
@@ -262,6 +246,7 @@ static int aa_perm_dentry(struct aa_prof
|
||||
{
|
||||
int denied_mask, error;
|
||||
|
||||
+again:
|
||||
sa->buffer = NULL;
|
||||
sa->name = aa_get_name(dentry, mnt, &sa->buffer, check);
|
||||
|
||||
@@ -283,6 +268,11 @@ static int aa_perm_dentry(struct aa_prof
|
||||
error = aa_audit(profile, sa);
|
||||
|
||||
aa_put_name_buffer(sa->buffer);
|
||||
+ if (error == -ENAMETOOLONG) {
|
||||
+ BUG_ON(check & AA_CHECK_MANGLE);
|
||||
+ check |= AA_CHECK_MANGLE;
|
||||
+ goto again;
|
||||
+ }
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -370,8 +360,8 @@ void free_null_complain_profile(void)
|
||||
* @flags: audit flags
|
||||
* @fmt: varargs fmt
|
||||
*/
|
||||
-int aa_audit_message(struct aa_profile *profile, gfp_t gfp, int flags,
|
||||
- const char *fmt, ...)
|
||||
+int aa_audit_message(struct aa_profile *profile, gfp_t gfp, const char *fmt,
|
||||
+ ...)
|
||||
{
|
||||
int ret;
|
||||
struct aa_audit sa;
|
||||
@@ -379,7 +369,7 @@ int aa_audit_message(struct aa_profile *
|
||||
sa.type = AA_AUDITTYPE_MSG;
|
||||
sa.name = fmt;
|
||||
va_start(sa.vaval, fmt);
|
||||
- sa.flags = flags;
|
||||
+ sa.flags = 0;
|
||||
sa.gfp_mask = gfp;
|
||||
sa.error_code = 0;
|
||||
sa.result = 0; /* fake failure: force message to be logged */
|
||||
@@ -417,7 +407,7 @@ int aa_audit_syscallreject(struct aa_pro
|
||||
* @profile: profile to check against
|
||||
* @sa: audit event
|
||||
*/
|
||||
-int aa_audit(struct aa_profile *profile, const struct aa_audit *sa)
|
||||
+int aa_audit(struct aa_profile *profile, struct aa_audit *sa)
|
||||
{
|
||||
struct audit_buffer *ab = NULL;
|
||||
struct audit_context *audit_cxt;
|
||||
@@ -501,32 +491,42 @@ int aa_audit(struct aa_profile *profile,
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ if (sa->type & AA_MANGLE_NAME) {
|
||||
+ sa->name = mangle(sa->name, sa->buffer);
|
||||
+ if (!sa->name)
|
||||
+ return -ENAMETOOLONG;
|
||||
+ }
|
||||
+ if (sa->type & AA_MANGLE_NAME2) {
|
||||
+ sa->name2 = mangle(sa->name2, sa->buffer2);
|
||||
+ if (!sa->name2)
|
||||
+ return -ENAMETOOLONG;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
/* log operation */
|
||||
|
||||
audit_log_format(ab, "%s ", logcls); /* REJECTING/ALLOWING/etc */
|
||||
|
||||
- switch(sa->type) {
|
||||
- case AA_AUDITTYPE_FILE: {
|
||||
+#define NOFLAGS(x) ((x) & ~(AA_MANGLE_NAME | AA_MANGLE_NAME2))
|
||||
+
|
||||
+ switch(NOFLAGS(sa->type)) {
|
||||
+ case NOFLAGS(AA_AUDITTYPE_FILE): {
|
||||
int perm = audit ? sa->mask : sa->error_code;
|
||||
- char *mangled_name = mangle_buffer(sa->name, &sa->buffer);
|
||||
- if (!mangled_name) {
|
||||
- opspec_error = -ENOMEM;
|
||||
- break;
|
||||
- }
|
||||
+
|
||||
audit_log_format(ab, "%s%s%s%s%s access to %s ",
|
||||
perm & AA_EXEC_MMAP ? "m" : "",
|
||||
perm & MAY_READ ? "r" : "",
|
||||
perm & MAY_WRITE ? "w" : "",
|
||||
perm & MAY_EXEC ? "x" : "",
|
||||
perm & AA_MAY_LINK ? "l" : "",
|
||||
- mangled_name);
|
||||
+ sa->name);
|
||||
opspec_error = -EPERM;
|
||||
break;
|
||||
}
|
||||
- case AA_AUDITTYPE_DIR:
|
||||
+ case NOFLAGS(AA_AUDITTYPE_DIR):
|
||||
audit_log_format(ab, "%s on %s ", sa->name2, sa->name);
|
||||
break;
|
||||
- case AA_AUDITTYPE_ATTR: {
|
||||
+ case NOFLAGS(AA_AUDITTYPE_ATTR): {
|
||||
struct iattr *iattr = sa->iattr;
|
||||
|
||||
audit_log_format(ab,
|
||||
@@ -543,25 +543,19 @@ int aa_audit(struct aa_profile *profile,
|
||||
sa->name);
|
||||
break;
|
||||
}
|
||||
- case AA_AUDITTYPE_XATTR:
|
||||
+ case NOFLAGS(AA_AUDITTYPE_XATTR):
|
||||
audit_log_format(ab, "%s on %s ", sa->name2, sa->name);
|
||||
break;
|
||||
- case AA_AUDITTYPE_LINK: {
|
||||
- char *link_name = mangle_buffer(sa->name, &sa->buffer);
|
||||
- char *target_name = mangle_buffer(sa->name2, sa->buffer2);
|
||||
- if (link_name && target_name)
|
||||
- audit_log_format(ab, "link access from %s to %s ",
|
||||
- link_name, target_name);
|
||||
- else
|
||||
- opspec_error = -ENOMEM;
|
||||
+ case NOFLAGS(AA_AUDITTYPE_LINK):
|
||||
+ audit_log_format(ab, "link access from %s to %s ", sa->name,
|
||||
+ sa->name2);
|
||||
break;
|
||||
- }
|
||||
- case AA_AUDITTYPE_CAP:
|
||||
+ case NOFLAGS(AA_AUDITTYPE_CAP):
|
||||
audit_log_format(ab, "access to capability '%s' ",
|
||||
capability_names[sa->capability]);
|
||||
opspec_error = -EPERM;
|
||||
break;
|
||||
- case AA_AUDITTYPE_SYSCALL:
|
||||
+ case NOFLAGS(AA_AUDITTYPE_SYSCALL):
|
||||
audit_log_format(ab, "access to syscall '%s' ", sa->name);
|
||||
opspec_error = -EPERM;
|
||||
break;
|
||||
@@ -570,6 +564,8 @@ int aa_audit(struct aa_profile *profile,
|
||||
return error;
|
||||
}
|
||||
|
||||
+#undef NOFLAGS
|
||||
+
|
||||
audit_log_format(ab, "(%d profile %s active %s)",
|
||||
current->pid, profile->parent->name, profile->name);
|
||||
|
||||
@@ -789,12 +785,14 @@ int aa_link(struct aa_profile *profile,
|
||||
struct dentry *link, struct vfsmount *link_mnt,
|
||||
struct dentry *target, struct vfsmount *target_mnt)
|
||||
{
|
||||
- int denied_mask = -EPERM, error;
|
||||
+ int denied_mask = -EPERM, error, check = 0;
|
||||
struct aa_audit sa;
|
||||
|
||||
- sa.buffer = sa.buffer2 = NULL;
|
||||
- sa.name = aa_get_name(link, link_mnt, &sa.buffer, 0);
|
||||
- sa.name2 = aa_get_name(target, target_mnt, &sa.buffer2, 0);
|
||||
+again:
|
||||
+ sa.buffer = NULL;
|
||||
+ sa.name = aa_get_name(link, link_mnt, &sa.buffer, check);
|
||||
+ sa.buffer2 = NULL;
|
||||
+ sa.name2 = aa_get_name(target, target_mnt, &sa.buffer2, check);
|
||||
|
||||
if (IS_ERR(sa.name)) {
|
||||
denied_mask = PTR_ERR(sa.name);
|
||||
@@ -818,6 +816,11 @@ int aa_link(struct aa_profile *profile,
|
||||
|
||||
aa_put_name_buffer(sa.buffer);
|
||||
aa_put_name_buffer(sa.buffer2);
|
||||
+ if (error == -ENAMETOOLONG) {
|
||||
+ BUG_ON(check & AA_CHECK_MANGLE);
|
||||
+ check |= AA_CHECK_MANGLE;
|
||||
+ goto again;
|
||||
+ }
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -876,7 +879,7 @@ repeat:
|
||||
}
|
||||
|
||||
static struct aa_profile *
|
||||
-aa_register_find(struct aa_profile *profile, const char *name, char **buffer,
|
||||
+aa_register_find(struct aa_profile *profile, const char *name, char *buffer,
|
||||
int mandatory, int complain)
|
||||
{
|
||||
struct aa_profile *new_profile;
|
||||
@@ -887,26 +890,19 @@ aa_register_find(struct aa_profile *prof
|
||||
AA_DEBUG("%s: setting profile %s\n",
|
||||
__FUNCTION__, new_profile->name);
|
||||
} else if (mandatory && profile) {
|
||||
+ name = mangle(name, buffer);
|
||||
if (complain) {
|
||||
- char *mangled_name, *b = NULL;
|
||||
- mangled_name = mangle_buffer(name, &b);
|
||||
- if (!mangled_name)
|
||||
- return ERR_PTR(-ENOMEM);
|
||||
LOG_HINT(profile, GFP_KERNEL, HINT_MANDPROF,
|
||||
- "image '%s'", mangled_name);
|
||||
- kfree(b);
|
||||
+ "image '%s'", name);
|
||||
profile = aa_dup_profile(null_complain_profile);
|
||||
} else {
|
||||
- char *b = mangle_buffer(name, buffer);
|
||||
- if (b) {
|
||||
- AA_REJECT_MSG(profile, GFP_KERNEL,
|
||||
- "exec(2) of image '%s'. Profile "
|
||||
- "mandatory and not found.",
|
||||
- b);
|
||||
- return ERR_PTR(-EPERM);
|
||||
- } else {
|
||||
- return ERR_PTR(-ENOMEM);
|
||||
- }
|
||||
+ aa_audit_message(profile, GFP_KERNEL, "REJECTING "
|
||||
+ "exec(2) of image '%s'. Profile "
|
||||
+ "mandatory and not found. "
|
||||
+ "(%d profile %s active %s)",
|
||||
+ name, current->pid,
|
||||
+ profile->parent->name, profile->name);
|
||||
+ return ERR_PTR(-EPERM);
|
||||
}
|
||||
} else {
|
||||
/* Only way we can get into this code is if task
|
||||
@@ -928,14 +924,16 @@ aa_register_find(struct aa_profile *prof
|
||||
*/
|
||||
int aa_register(struct linux_binprm *bprm)
|
||||
{
|
||||
- char *filename, *buffer = NULL;
|
||||
+ const char *filename;
|
||||
+ char *buffer = NULL;
|
||||
struct file *filp = bprm->file;
|
||||
struct aa_profile *profile, *old_profile, *new_profile = NULL;
|
||||
int exec_mode = AA_EXEC_UNSAFE, complain = 0;
|
||||
|
||||
AA_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
- filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer, 0);
|
||||
+ filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer,
|
||||
+ AA_CHECK_MANGLE);
|
||||
if (IS_ERR(filename)) {
|
||||
AA_ERROR("%s: Failed to get filename", __FUNCTION__);
|
||||
return -ENOENT;
|
||||
@@ -975,7 +973,7 @@ repeat:
|
||||
filename);
|
||||
new_profile = aa_register_find(profile,
|
||||
filename,
|
||||
- &buffer, 1,
|
||||
+ buffer, 1,
|
||||
complain);
|
||||
break;
|
||||
|
||||
@@ -1000,20 +998,18 @@ repeat:
|
||||
new_profile = aa_dup_profile(null_complain_profile);
|
||||
exec_mode |= AA_EXEC_UNSAFE;
|
||||
} else {
|
||||
- const char *name = mangle_buffer(filename, &buffer);
|
||||
- if (name) {
|
||||
- AA_REJECT_MSG(profile, GFP_KERNEL,
|
||||
- "exec(2) of image '%s'. Unable "
|
||||
- "to determine exec qualifier.",
|
||||
- name);
|
||||
- new_profile = ERR_PTR(-EPERM);
|
||||
- } else {
|
||||
- new_profile = ERR_PTR(-ENOMEM);
|
||||
- }
|
||||
+ filename = mangle(filename, buffer);
|
||||
+ aa_audit_message(profile, GFP_KERNEL, "REJECTING "
|
||||
+ "exec(2) of image '%s'. Unable to "
|
||||
+ "determine exec qualifier. "
|
||||
+ "(%d profile %s active %s)",
|
||||
+ filename, current->pid,
|
||||
+ profile->parent->name, profile->name);
|
||||
+ new_profile = ERR_PTR(-EPERM);
|
||||
}
|
||||
} else {
|
||||
/* Unconfined task, load profile if it exists */
|
||||
- new_profile = aa_register_find(NULL, filename, &buffer, 0, 0);
|
||||
+ new_profile = aa_register_find(NULL, filename, buffer, 0, 0);
|
||||
if (new_profile == NULL)
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -1027,11 +1023,16 @@ repeat:
|
||||
aa_put_profile(profile);
|
||||
if (PTR_ERR(old_profile) == -ESTALE)
|
||||
goto repeat;
|
||||
- if (PTR_ERR(old_profile) == -EPERM)
|
||||
- AA_REJECT_MSG(profile, GFP_KERNEL,
|
||||
- "exec(2) of image '%s'. "
|
||||
- "Unable to change profile, ptraced by %d.",
|
||||
- filename, current->parent->pid);
|
||||
+ if (PTR_ERR(old_profile) == -EPERM) {
|
||||
+ filename = mangle(filename, buffer);
|
||||
+ aa_audit_message(profile, GFP_KERNEL,
|
||||
+ "REJECTING exec(2) of image '%s'. "
|
||||
+ "Unable to change profile, ptraced by "
|
||||
+ "%d. (%d profile %s active %s)",
|
||||
+ filename, current->parent->pid,
|
||||
+ current->pid,
|
||||
+ profile->parent->name, profile->name);
|
||||
+ }
|
||||
new_profile = old_profile;
|
||||
goto cleanup;
|
||||
}
|
184
kernel-patches/for-mainline/mangle_on_audit-3.diff
Normal file
184
kernel-patches/for-mainline/mangle_on_audit-3.diff
Normal file
|
@ -0,0 +1,184 @@
|
|||
* Rip out AA_WARN() and replace it with direct calls to aa_audit_message().
|
||||
|
||||
---
|
||||
security/apparmor/apparmor.h | 2 -
|
||||
security/apparmor/apparmorfs.c | 8 +++----
|
||||
security/apparmor/lsm.c | 18 +++++++----------
|
||||
security/apparmor/main.c | 8 +++----
|
||||
security/apparmor/module_interface.c | 10 ++++-----
|
||||
security/apparmor/procattr.c | 37 ++++++++++++++++-------------------
|
||||
6 files changed, 38 insertions(+), 45 deletions(-)
|
||||
|
||||
--- a/security/apparmor/apparmor.h
|
||||
+++ b/security/apparmor/apparmor.h
|
||||
@@ -71,8 +71,6 @@ extern unsigned int apparmor_path_max;
|
||||
printk(KERN_INFO "AppArmor: " fmt "\n", ##args); \
|
||||
aa_audit_message(NULL, (gfp), fmt, ##args); \
|
||||
} while (0)
|
||||
-#define AA_WARN(gfp, fmt, args...) \
|
||||
- aa_audit_message(NULL, (gfp), fmt, ##args);
|
||||
|
||||
#define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args)
|
||||
|
||||
--- a/security/apparmor/apparmorfs.c
|
||||
+++ b/security/apparmor/apparmorfs.c
|
||||
@@ -38,10 +38,10 @@ static char *aa_simple_write_to_buffer(c
|
||||
*/
|
||||
profile = aa_get_profile(current);
|
||||
if (profile) {
|
||||
- AA_WARN(GFP_KERNEL, "REJECTING access to profile %s (%d "
|
||||
- "profile %s active %s)",
|
||||
- msg, current->pid,
|
||||
- profile->parent->name, profile->name);
|
||||
+ aa_audit_message(NULL, GFP_KERNEL, "REJECTING access to "
|
||||
+ "profile %s (%d profile %s active %s)",
|
||||
+ msg, current->pid, profile->parent->name,
|
||||
+ profile->name);
|
||||
aa_put_profile(profile);
|
||||
|
||||
data = ERR_PTR(-EPERM);
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -126,9 +126,9 @@ static int apparmor_ptrace(struct task_s
|
||||
child_cxt = aa_task_context(child);
|
||||
child_profile = child_cxt ? child_cxt->profile : NULL;
|
||||
if (cxt && (parent->nsproxy != child->nsproxy)) {
|
||||
- AA_WARN(GFP_ATOMIC,
|
||||
- "REJECTING ptrace across namespace of %d by %d",
|
||||
- parent->pid, child->pid);
|
||||
+ aa_audit_message(NULL, GFP_ATOMIC, "REJECTING ptrace across "
|
||||
+ "namespace of %d by %d",
|
||||
+ parent->pid, child->pid);
|
||||
error = -EPERM;
|
||||
} else {
|
||||
error = aa_may_ptrace(cxt, child_profile);
|
||||
@@ -622,13 +622,11 @@ static int apparmor_setprocattr(struct t
|
||||
profile = aa_get_profile(current);
|
||||
if (profile) {
|
||||
aa_put_profile(profile);
|
||||
- AA_WARN(GFP_KERNEL,
|
||||
- "Attempt by confined task %d "
|
||||
- "[user %d] to assign profile to task %s(%d)",
|
||||
- current->pid,
|
||||
- current->uid,
|
||||
- task->comm,
|
||||
- task->pid);
|
||||
+ aa_audit_message(NULL, GFP_KERNEL, "Attempt by "
|
||||
+ "confined task %d [user %d] to assign "
|
||||
+ "profile to task %s(%d)",
|
||||
+ current->pid, current->uid,
|
||||
+ task->comm, task->pid);
|
||||
return -EACCES;
|
||||
}
|
||||
error = aa_setprocattr_setprofile(task, args);
|
||||
--- a/security/apparmor/main.c
|
||||
+++ b/security/apparmor/main.c
|
||||
@@ -1024,7 +1024,6 @@ repeat:
|
||||
if (PTR_ERR(old_profile) == -ESTALE)
|
||||
goto repeat;
|
||||
if (PTR_ERR(old_profile) == -EPERM) {
|
||||
- filename = mangle(filename, buffer);
|
||||
aa_audit_message(profile, GFP_KERNEL,
|
||||
"REJECTING exec(2) of image '%s'. "
|
||||
"Unable to change profile, ptraced by "
|
||||
@@ -1191,9 +1190,10 @@ int aa_change_hat(const char *hat_name,
|
||||
|
||||
/* Dump out above debugging in WARN mode if we are in AUDIT mode */
|
||||
if (APPARMOR_AUDIT(aa_task_context(current))) {
|
||||
- AA_WARN(GFP_KERNEL, "change_hat %s, 0x%llx (pid %d)",
|
||||
- hat_name ? hat_name : "NULL",
|
||||
- hat_magic, current->pid);
|
||||
+ aa_audit_message(NULL, GFP_KERNEL, "change_hat %s, 0x%llx "
|
||||
+ "(pid %d)",
|
||||
+ hat_name ? hat_name : "NULL", hat_magic,
|
||||
+ current->pid);
|
||||
}
|
||||
|
||||
new_cxt = aa_alloc_task_context(GFP_KERNEL);
|
||||
--- a/security/apparmor/module_interface.c
|
||||
+++ b/security/apparmor/module_interface.c
|
||||
@@ -304,8 +304,8 @@ static struct aa_profile *aa_unpack_prof
|
||||
return profile;
|
||||
|
||||
fail:
|
||||
- AA_WARN(GFP_KERNEL, "Invalid profile %s",
|
||||
- profile && profile->name ? profile->name : "unknown");
|
||||
+ aa_audit_message(NULL, GFP_KERNEL, "Invalid profile %s",
|
||||
+ profile && profile->name ? profile->name : "unknown");
|
||||
|
||||
if (profile)
|
||||
free_aa_profile(profile);
|
||||
@@ -345,14 +345,14 @@ static int aa_verify_header(struct aa_ex
|
||||
{
|
||||
/* get the interface version */
|
||||
if (!aa_is_u32(e, &e->version, "version")) {
|
||||
- AA_WARN(GFP_KERNEL, "Interface version missing");
|
||||
+ aa_audit_message(NULL, GFP_KERNEL, "Interface version missing");
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
/* check that the interface version is currently supported */
|
||||
if (e->version != 3) {
|
||||
- AA_WARN(GFP_KERNEL,
|
||||
- "Unsupported interface version (%d)", e->version);
|
||||
+ aa_audit_message(NULL, GFP_KERNEL, "Unsupported interface "
|
||||
+ "version (%d)", e->version);
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
return 0;
|
||||
--- a/security/apparmor/procattr.c
|
||||
+++ b/security/apparmor/procattr.c
|
||||
@@ -91,10 +91,10 @@ repeat:
|
||||
else {
|
||||
new_profile = aa_find_profile(args);
|
||||
if (!new_profile) {
|
||||
- AA_WARN(GFP_KERNEL,
|
||||
- "Unable to switch task %d to profile"
|
||||
- "'%s'. No such profile.",
|
||||
- task->pid, args);
|
||||
+ aa_audit_message(NULL, GFP_KERNEL, "Unable to switch "
|
||||
+ "task %d to profile '%s'. No such "
|
||||
+ "profile.",
|
||||
+ task->pid, args);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -112,25 +112,22 @@ repeat:
|
||||
}
|
||||
|
||||
if (new_profile) {
|
||||
- AA_WARN(GFP_KERNEL,
|
||||
- "Switching task %d profile %s "
|
||||
- "active %s to new profile %s",
|
||||
- task->pid,
|
||||
- old_profile ? old_profile->parent->name :
|
||||
- "unconfined",
|
||||
- old_profile ? old_profile->name : "unconfined",
|
||||
- args);
|
||||
+ aa_audit_message(NULL, GFP_KERNEL, "Switching task %d profile "
|
||||
+ "%s active %s to new profile %s",
|
||||
+ task->pid, old_profile ?
|
||||
+ old_profile->parent->name : "unconfined",
|
||||
+ old_profile ? old_profile->name : "unconfined",
|
||||
+ args);
|
||||
} else {
|
||||
if (old_profile) {
|
||||
- AA_WARN(GFP_KERNEL,
|
||||
- "Unconfining task %d profile %s active %s",
|
||||
- task->pid,
|
||||
- old_profile->parent->name,
|
||||
- old_profile->name);
|
||||
+ aa_audit_message(NULL, GFP_KERNEL, "Unconfining task "
|
||||
+ "%d profile %s active %s",
|
||||
+ task->pid, old_profile->parent->name,
|
||||
+ old_profile->name);
|
||||
} else {
|
||||
- AA_WARN(GFP_KERNEL,
|
||||
- "task %d is already unconfined",
|
||||
- task->pid);
|
||||
+ aa_audit_message(NULL, GFP_KERNEL, "task %d is already "
|
||||
+ "unconfined",
|
||||
+ task->pid);
|
||||
}
|
||||
}
|
||||
|
65
kernel-patches/for-mainline/mangle_on_audit-4.diff
Normal file
65
kernel-patches/for-mainline/mangle_on_audit-4.diff
Normal file
|
@ -0,0 +1,65 @@
|
|||
* Rip out AA_INFO() and replace it with a static function where it's used.
|
||||
|
||||
---
|
||||
security/apparmor/apparmor.h | 5 -----
|
||||
security/apparmor/lsm.c | 17 ++++++++++++-----
|
||||
2 files changed, 12 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/security/apparmor/apparmor.h
|
||||
+++ b/security/apparmor/apparmor.h
|
||||
@@ -66,11 +66,6 @@ extern unsigned int apparmor_path_max;
|
||||
if (apparmor_debug) \
|
||||
printk(KERN_DEBUG "AppArmor: " fmt, ##args); \
|
||||
} while (0)
|
||||
-#define AA_INFO(gfp, fmt, args...) \
|
||||
- do { \
|
||||
- printk(KERN_INFO "AppArmor: " fmt "\n", ##args); \
|
||||
- aa_audit_message(NULL, (gfp), fmt, ##args); \
|
||||
- } while (0)
|
||||
|
||||
#define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args)
|
||||
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -694,10 +694,15 @@ struct security_operations apparmor_ops
|
||||
.setprocattr = apparmor_setprocattr,
|
||||
};
|
||||
|
||||
+static void info_message(const char *str)
|
||||
+{
|
||||
+ printk(KERN_INFO "AppArmor: %s", str);
|
||||
+ aa_audit_message(NULL, GFP_KERNEL, "%s", str);
|
||||
+}
|
||||
+
|
||||
static int __init apparmor_init(void)
|
||||
{
|
||||
int error;
|
||||
- const char *complainmsg = ": complainmode enabled";
|
||||
|
||||
if ((error = create_apparmorfs())) {
|
||||
AA_ERROR("Unable to activate AppArmor filesystem\n");
|
||||
@@ -714,8 +719,10 @@ static int __init apparmor_init(void)
|
||||
goto register_security_out;
|
||||
}
|
||||
|
||||
- AA_INFO(GFP_KERNEL, "AppArmor initialized%s",
|
||||
- apparmor_complain ? complainmsg : "");
|
||||
+ if (apparmor_complain)
|
||||
+ info_message("AppArmor initialized: complainmode enabled");
|
||||
+ else
|
||||
+ info_message("AppArmor initialized");
|
||||
|
||||
return error;
|
||||
|
||||
@@ -766,9 +773,9 @@ static void __exit apparmor_exit(void)
|
||||
mutex_unlock(&aa_interface_lock);
|
||||
|
||||
if (unregister_security(&apparmor_ops))
|
||||
- AA_INFO(GFP_KERNEL, "Unable to properly unregister AppArmor");
|
||||
+ info_message("Unable to properly unregister AppArmor");
|
||||
|
||||
- AA_INFO(GFP_KERNEL, "AppArmor protection removed");
|
||||
+ info_message("AppArmor protection removed");
|
||||
}
|
||||
|
||||
module_init(apparmor_init);
|
72
kernel-patches/for-mainline/mangle_on_audit-5.diff
Normal file
72
kernel-patches/for-mainline/mangle_on_audit-5.diff
Normal file
|
@ -0,0 +1,72 @@
|
|||
* Rip out the completely unnecessary HINT_ macros.
|
||||
|
||||
---
|
||||
security/apparmor/apparmor.h | 6 ------
|
||||
security/apparmor/lsm.c | 2 +-
|
||||
security/apparmor/main.c | 8 ++++----
|
||||
3 files changed, 5 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/security/apparmor/apparmor.h
|
||||
+++ b/security/apparmor/apparmor.h
|
||||
@@ -180,12 +180,6 @@ struct aa_audit {
|
||||
#define AA_AUDITFLAG_LOGERR 2 /* log operations that failed due to
|
||||
non permission errors */
|
||||
|
||||
-#define HINT_UNKNOWN_HAT "unknown_hat"
|
||||
-#define HINT_FORK "fork"
|
||||
-#define HINT_MANDPROF "missing_mandatory_profile"
|
||||
-#define HINT_CHGPROF "changing_profile"
|
||||
-#define HINT_PTRACE "ptrace"
|
||||
-
|
||||
#define LOG_HINT(p, gfp, hint, fmt, args...) \
|
||||
aa_audit_message((p), (gfp), \
|
||||
"LOGPROF-HINT " hint " " fmt \
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -133,7 +133,7 @@ static int apparmor_ptrace(struct task_s
|
||||
} else {
|
||||
error = aa_may_ptrace(cxt, child_profile);
|
||||
if (cxt && PROFILE_COMPLAIN(cxt->profile)) {
|
||||
- LOG_HINT(cxt->profile, GFP_ATOMIC, HINT_PTRACE,
|
||||
+ LOG_HINT(cxt->profile, GFP_ATOMIC, "ptrace",
|
||||
"pid=%d child=%d\n",
|
||||
current->pid, child->pid);
|
||||
}
|
||||
--- a/security/apparmor/main.c
|
||||
+++ b/security/apparmor/main.c
|
||||
@@ -869,7 +869,7 @@ repeat:
|
||||
|
||||
if (APPARMOR_COMPLAIN(child_cxt) &&
|
||||
profile == null_complain_profile)
|
||||
- LOG_HINT(profile, GFP_KERNEL, HINT_FORK,
|
||||
+ LOG_HINT(profile, GFP_KERNEL, "fork",
|
||||
"child=%d", child->pid);
|
||||
aa_put_profile(profile);
|
||||
} else
|
||||
@@ -892,7 +892,7 @@ aa_register_find(struct aa_profile *prof
|
||||
} else if (mandatory && profile) {
|
||||
name = mangle(name, buffer);
|
||||
if (complain) {
|
||||
- LOG_HINT(profile, GFP_KERNEL, HINT_MANDPROF,
|
||||
+ LOG_HINT(profile, GFP_KERNEL, "missing_mandatory_profile",
|
||||
"image '%s'", name);
|
||||
profile = aa_dup_profile(null_complain_profile);
|
||||
} else {
|
||||
@@ -1056,7 +1056,7 @@ repeat:
|
||||
}
|
||||
|
||||
if (complain && new_profile == null_complain_profile)
|
||||
- LOG_HINT(new_profile, GFP_ATOMIC, HINT_CHGPROF,
|
||||
+ LOG_HINT(new_profile, GFP_ATOMIC, "changing_profile",
|
||||
"");
|
||||
|
||||
cleanup:
|
||||
@@ -1144,7 +1144,7 @@ static int do_change_hat(const char *hat
|
||||
struct aa_profile *profile = cxt->profile;
|
||||
|
||||
if (APPARMOR_COMPLAIN(cxt)) {
|
||||
- LOG_HINT(profile, GFP_ATOMIC, HINT_UNKNOWN_HAT,
|
||||
+ LOG_HINT(profile, GFP_ATOMIC, "unknown_hat",
|
||||
"%s", hat_name);
|
||||
} else {
|
||||
AA_DEBUG("%s: Unknown hatname '%s'. "
|
114
kernel-patches/for-mainline/mangle_on_audit-6.diff
Normal file
114
kernel-patches/for-mainline/mangle_on_audit-6.diff
Normal file
|
@ -0,0 +1,114 @@
|
|||
* Rip out LOG_HINT() and replace it with direct calls to aa_audit_message().
|
||||
|
||||
* Annotate aa_audit_message() as a printf-style function so that we'll get
|
||||
argument type checking.
|
||||
|
||||
---
|
||||
security/apparmor/apparmor.h | 10 ++--------
|
||||
security/apparmor/lsm.c | 9 ++++++---
|
||||
security/apparmor/main.c | 29 ++++++++++++++++++++---------
|
||||
3 files changed, 28 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/security/apparmor/apparmor.h
|
||||
+++ b/security/apparmor/apparmor.h
|
||||
@@ -180,13 +180,6 @@ struct aa_audit {
|
||||
#define AA_AUDITFLAG_LOGERR 2 /* log operations that failed due to
|
||||
non permission errors */
|
||||
|
||||
-#define LOG_HINT(p, gfp, hint, fmt, args...) \
|
||||
- aa_audit_message((p), (gfp), \
|
||||
- "LOGPROF-HINT " hint " " fmt \
|
||||
- " (%d profile %s active %s)", ##args, \
|
||||
- current->pid, \
|
||||
- (p)->parent->name, (p)->name)
|
||||
-
|
||||
/* Flags for the permission check functions */
|
||||
#define AA_CHECK_LEAF 1 /* this is the leaf lookup component */
|
||||
#define AA_CHECK_FD 2 /* coming from a file descriptor */
|
||||
@@ -198,7 +191,8 @@ extern int alloc_null_complain_profile(v
|
||||
extern void free_null_complain_profile(void);
|
||||
extern int attach_nullprofile(struct aa_profile *profile);
|
||||
extern int aa_audit_message(struct aa_profile *profile, gfp_t gfp,
|
||||
- const char *, ...);
|
||||
+ const char *, ...)
|
||||
+ __attribute__ ((format (printf, 3, 4)));
|
||||
extern int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp,
|
||||
const char *);
|
||||
extern int aa_audit(struct aa_profile *profile, struct aa_audit *);
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -133,9 +133,12 @@ static int apparmor_ptrace(struct task_s
|
||||
} else {
|
||||
error = aa_may_ptrace(cxt, child_profile);
|
||||
if (cxt && PROFILE_COMPLAIN(cxt->profile)) {
|
||||
- LOG_HINT(cxt->profile, GFP_ATOMIC, "ptrace",
|
||||
- "pid=%d child=%d\n",
|
||||
- current->pid, child->pid);
|
||||
+ aa_audit_message(cxt->profile, GFP_ATOMIC,
|
||||
+ "LOGPROF-HINT ptrace pid=%d child=%d "
|
||||
+ "(%d profile %s active %s)",
|
||||
+ current->pid, child->pid, current->pid,
|
||||
+ cxt->profile->parent->name,
|
||||
+ cxt->profile->name);
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
--- a/security/apparmor/main.c
|
||||
+++ b/security/apparmor/main.c
|
||||
@@ -869,8 +869,11 @@ repeat:
|
||||
|
||||
if (APPARMOR_COMPLAIN(child_cxt) &&
|
||||
profile == null_complain_profile)
|
||||
- LOG_HINT(profile, GFP_KERNEL, "fork",
|
||||
- "child=%d", child->pid);
|
||||
+ aa_audit_message(profile, GFP_KERNEL,
|
||||
+ "LOGPROF-HINT fork child=%d "
|
||||
+ "(%d profile %s active %s)",
|
||||
+ child->pid, current->pid,
|
||||
+ profile->parent->name, profile->name);
|
||||
aa_put_profile(profile);
|
||||
} else
|
||||
aa_free_task_context(child_cxt);
|
||||
@@ -892,8 +895,11 @@ aa_register_find(struct aa_profile *prof
|
||||
} else if (mandatory && profile) {
|
||||
name = mangle(name, buffer);
|
||||
if (complain) {
|
||||
- LOG_HINT(profile, GFP_KERNEL, "missing_mandatory_profile",
|
||||
- "image '%s'", name);
|
||||
+ aa_audit_message(profile, GFP_KERNEL, "LOGPROF-HINT "
|
||||
+ "missing_mandatory_profile image '%s' "
|
||||
+ "(%d profile %s active %s)",
|
||||
+ name, current->pid,
|
||||
+ profile->parent->name, profile->name);
|
||||
profile = aa_dup_profile(null_complain_profile);
|
||||
} else {
|
||||
aa_audit_message(profile, GFP_KERNEL, "REJECTING "
|
||||
@@ -1056,9 +1062,11 @@ repeat:
|
||||
}
|
||||
|
||||
if (complain && new_profile == null_complain_profile)
|
||||
- LOG_HINT(new_profile, GFP_ATOMIC, "changing_profile",
|
||||
- "");
|
||||
-
|
||||
+ aa_audit_message(new_profile, GFP_ATOMIC,
|
||||
+ "LOGPROF-HINT changing_profile "
|
||||
+ "(%d profile %s active %s)",
|
||||
+ current->pid,
|
||||
+ new_profile->parent->name, new_profile->name);
|
||||
cleanup:
|
||||
aa_put_name_buffer(buffer);
|
||||
if (IS_ERR(new_profile))
|
||||
@@ -1144,8 +1152,11 @@ static int do_change_hat(const char *hat
|
||||
struct aa_profile *profile = cxt->profile;
|
||||
|
||||
if (APPARMOR_COMPLAIN(cxt)) {
|
||||
- LOG_HINT(profile, GFP_ATOMIC, "unknown_hat",
|
||||
- "%s", hat_name);
|
||||
+ aa_audit_message(profile, GFP_ATOMIC,
|
||||
+ "LOGPROF-HINT unknown_hat %s "
|
||||
+ "(%d profile %s active %s)",
|
||||
+ hat_name, current->pid,
|
||||
+ profile->parent->name, profile->name);
|
||||
} else {
|
||||
AA_DEBUG("%s: Unknown hatname '%s'. "
|
||||
"Changing to NULL profile "
|
|
@ -43,6 +43,11 @@ apparmor-intree.diff
|
|||
apparmor-del-comm.diff
|
||||
comment_cleanup.diff
|
||||
mangle_on_audit.diff
|
||||
mangle_on_audit-2.diff
|
||||
mangle_on_audit-3.diff
|
||||
mangle_on_audit-4.diff
|
||||
mangle_on_audit-5.diff
|
||||
mangle_on_audit-6.diff
|
||||
do_path_lookup-nameidata.diff
|
||||
sys_fchdir-nameidata.diff
|
||||
file_permission-nameidata.diff
|
||||
|
|
Loading…
Add table
Reference in a new issue