[PATCH 12/38] vfs: Pass key and value into LSM and FS and provide a helper parser [ver #10]

From: David Howells
Date: Fri Jul 27 2018 - 13:32:49 EST


Note: I've put some test code in the AFS filesystem that needs taking back
out.
---

security/apparmor/lsm.c | 33 +++++++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 9a5915dffbdc..c52a87b0447d 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -553,15 +553,35 @@ static void apparmor_fs_context_free(struct fs_context *fc)
* to pass them to the DFA evaluator *after* mount point parameters, which
* means deferring the entire check to the sb_mountpoint hook.
*/
-static int apparmor_fs_context_parse_option(struct fs_context *fc, char *opt, size_t len)
+static int apparmor_fs_context_parse_option(struct fs_context *fc, const char *key,
+ enum fs_value_type v_type,
+ void *value, size_t v_len)
{
struct apparmor_fs_context *afc = fc->security;
- size_t space = 0;
+ size_t space = 0, k_len = strlen(key), len = k_len;
char *p, *q;

if (afc->saved_size > 0)
space = 1;

+ switch (v_type) {
+ case fs_value_is_string:
+ len += 1 + v_len;
+ break;
+ case fs_value_is_path:
+ case fs_value_is_path_empty: {
+ struct filename *f = value;
+ value = (char *)f->name;
+ v_len = strlen(f->name);
+ len += 1 + v_len;
+ break;
+ }
+ default:
+ value = NULL;
+ v_len = 0;
+ break;
+ }
+
p = krealloc(afc->saved_options, afc->saved_size + space + len + 1, GFP_KERNEL);
if (!p)
return -ENOMEM;
@@ -569,8 +589,13 @@ static int apparmor_fs_context_parse_option(struct fs_context *fc, char *opt, si
q = p + afc->saved_size;
if (q != p)
*q++ = ' ';
- memcpy(q, opt, len);
- q += len;
+ memcpy(q, key, k_len);
+ q += k_len;
+ if (value) {
+ *q++ = '=';
+ memcpy(q, value, v_len);
+ q += v_len;
+ }
*q = 0;

afc->saved_options = p;