mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-05 08:45:22 +00:00
76 lines
1.7 KiB
Diff
76 lines
1.7 KiB
Diff
---
|
|
security/apparmor/main.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 49 insertions(+)
|
|
|
|
--- a/security/apparmor/main.c
|
|
+++ b/security/apparmor/main.c
|
|
@@ -103,6 +103,51 @@ static int aa_link_denied(struct aa_prof
|
|
}
|
|
|
|
/**
|
|
+ * mangle -- escape special characters in str
|
|
+ * @str: string to escape
|
|
+ * @buffer: buffer containing str
|
|
+ *
|
|
+ * Escape special characters in @str, which must be contained in
|
|
+ * @buffer. The string grows towards @buffer. Returns a pointer
|
|
+ * to the quoted string, or ERR_PTR(-ENAMETOOLONG) upon failure.
|
|
+ */
|
|
+static char *mangle(char *str, char *buffer)
|
|
+{
|
|
+ static const char c_escape[] = {
|
|
+ ['\a'] = 'a', ['\b'] = 'b',
|
|
+ ['\f'] = 'f', ['\n'] = 'n',
|
|
+ ['\r'] = 'r', ['\t'] = 't',
|
|
+ ['\v'] = 'v',
|
|
+ [' '] = ' ', ['\\'] = '\\',
|
|
+ };
|
|
+ char *s, *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++)
|
|
+ if (mangle_escape(c))
|
|
+ goto escape;
|
|
+ return str;
|
|
+
|
|
+escape:
|
|
+ for (s = str, t = buffer; (c = *s) != '\0'; s++) {
|
|
+ if (mangle_escape(c)) {
|
|
+ if (t == s)
|
|
+ return NULL;
|
|
+ *t++ = '\\';
|
|
+ *t++ = c_escape[(unsigned char)c];
|
|
+ } else
|
|
+ *t++ = c;
|
|
+ }
|
|
+ *t++ = '\0';
|
|
+
|
|
+#undef mangle_escape
|
|
+ return buffer;
|
|
+}
|
|
+
|
|
+/**
|
|
* aa_get_name - compute the pathname of a file
|
|
* @dentry: dentry of the file
|
|
* @mnt: vfsmount of the file
|
|
@@ -148,12 +193,16 @@ static char *aa_get_name(struct dentry *
|
|
buf[size - 1] = '\0';
|
|
}
|
|
|
|
+ name = mangle(name, buf);
|
|
+ if (!name)
|
|
+ goto grow_buffer;
|
|
*buffer = buf;
|
|
return name;
|
|
}
|
|
if (PTR_ERR(name) != -ENAMETOOLONG)
|
|
return name;
|
|
|
|
+grow_buffer:
|
|
kfree(buf);
|
|
size <<= 1;
|
|
if (size > apparmor_path_max)
|