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;