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;

Reply via email to