Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libperfuse - Make sure non root users cannot access syst...



details:   https://anonhg.NetBSD.org/src/rev/aae6812980bb
branches:  trunk
changeset: 331373:aae6812980bb
user:      manu <manu%NetBSD.org@localhost>
date:      Sun Aug 10 03:22:33 2014 +0000

description:
- Make sure non root users cannot access system namespace attributes
- honour namespace specification when listing attributes
- Also fix message memory leak introduced by previous commit

diffstat:

 lib/libperfuse/ops.c          |  73 +++++++++++++++++++++++++++++++-----------
 lib/libperfuse/perfuse_priv.h |   3 +-
 lib/libperfuse/subr.c         |  16 ++++++++-
 3 files changed, 70 insertions(+), 22 deletions(-)

diffs (176 lines):

diff -r 493acfdabc2c -r aae6812980bb lib/libperfuse/ops.c
--- a/lib/libperfuse/ops.c      Sat Aug 09 22:10:35 2014 +0000
+++ b/lib/libperfuse/ops.c      Sun Aug 10 03:22:33 2014 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: ops.c,v 1.65 2014/08/09 19:06:50 manu Exp $ */
+/*  $NetBSD: ops.c,v 1.66 2014/08/10 03:22:33 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -3323,6 +3323,10 @@
        char *np;
        int error;
 
+       /* system namespace attrs are not accessible to non root users */
+       if (attrns == EXTATTR_NAMESPACE_SYSTEM && !puffs_cred_isjuggernaut(pcr))
+               return EPERM;
+
        node_ref(opc);
        ps = puffs_getspecific(pu);
        attrname = perfuse_native_ns(attrns, attrname, fuse_attrname);
@@ -3367,6 +3371,7 @@
        if (resid != NULL) {
                if (*resid < len) {
                        error = ERANGE;
+                       ps->ps_destroy_msg(pm);
                        goto out;
                }
 
@@ -3396,6 +3401,10 @@
        char *np;
        int error;
        
+       /* system namespace attrs are not accessible to non root users */
+       if (attrns == EXTATTR_NAMESPACE_SYSTEM && !puffs_cred_isjuggernaut(pcr))
+               return EPERM;
+
        node_ref(opc);
        ps = puffs_getspecific(pu);
        attrname = perfuse_native_ns(attrns, attrname, fuse_attrname);
@@ -3436,9 +3445,13 @@
        struct fuse_getxattr_out *fgo;
        struct fuse_out_header *foh;
        char *np;
-       size_t len, puffs_len;
+       size_t len, puffs_len, i, attrlen, outlen;
        int error;
        
+       /* system namespace attrs are not accessible to non root users */
+       if (attrns == EXTATTR_NAMESPACE_SYSTEM && !puffs_cred_isjuggernaut(pcr))
+               return EPERM;
+
        node_ref(opc);
 
        ps = puffs_getspecific(pu);
@@ -3478,29 +3491,45 @@
        np = (char *)(void *)(foh + 1);
        puffs_len = foh->len - sizeof(*foh);
 
+       if (attrsize != NULL)
+               *attrsize = puffs_len;
+
        if (attrs != NULL) {
+               if (*resid < puffs_len) {
+                       error = ERANGE;
+                       ps->ps_destroy_msg(pm);
+                       goto out;
+               }
+
+               outlen = 0;
+       
+               for (i = 0; i < puffs_len; i += attrlen + 1) {
+                       attrlen = strlen(np + i);
+
+                       /*
+                        * Filter attributes per namespace
+                        */
+                       if (!perfuse_ns_match(attrns, np + i))
+                               continue;
+
 #ifdef PUFFS_EXTATTR_LIST_LENPREFIX
-               /* 
-                * Convert the FUSE reply to length prefixed strings
-                * if this is what the kernel wants.
-                */
-               if (flag & PUFFS_EXTATTR_LIST_LENPREFIX) {
-                       size_t i, attrlen;
-
-                       for (i = 0; i < puffs_len; i += attrlen + 1) {
-                               attrlen = strlen(np + i);
-                               (void)memmove(np + i + 1, np + i, attrlen);
-                               *(np + i) = (uint8_t)attrlen;
-                       }       
-               }
+                       /* 
+                        * Convert the FUSE reply to length prefixed strings
+                        * if this is what the kernel wants.
+                        */
+                       if (flag & PUFFS_EXTATTR_LIST_LENPREFIX) {
+                               (void)memcpy(attrs + outlen + 1,
+                                            np + i, attrlen);
+                               *(attrs + outlen) = (uint8_t)attrlen;
+                       } else 
 #endif /* PUFFS_EXTATTR_LIST_LENPREFIX */
-               (void)memcpy(attrs, np, puffs_len);
-               *resid -= puffs_len;
+                       (void)memcpy(attrs + outlen, np + i, attrlen + 1);
+                       outlen += attrlen + 1;
+               }       
+
+               *resid -= outlen;
        }
 
-       if (attrsize != NULL) 
-               *attrsize = puffs_len;
-
        ps->ps_destroy_msg(pm);
        error = 0;
 
@@ -3520,6 +3549,10 @@
        char *np;
        int error;
        
+       /* system namespace attrs are not accessible to non root users */
+       if (attrns == EXTATTR_NAMESPACE_SYSTEM && !puffs_cred_isjuggernaut(pcr))
+               return EPERM;
+
        node_ref(opc);
 
        ps = puffs_getspecific(pu);
diff -r 493acfdabc2c -r aae6812980bb lib/libperfuse/perfuse_priv.h
--- a/lib/libperfuse/perfuse_priv.h     Sat Aug 09 22:10:35 2014 +0000
+++ b/lib/libperfuse/perfuse_priv.h     Sun Aug 10 03:22:33 2014 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: perfuse_priv.h,v 1.31 2012/07/21 05:49:42 manu Exp $ */
+/*  $NetBSD: perfuse_priv.h,v 1.32 2014/08/10 03:22:33 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -186,6 +186,7 @@
 uint64_t perfuse_next_unique(struct puffs_usermount *);
 char *perfuse_node_path(struct perfuse_state *, puffs_cookie_t);
 int perfuse_node_close_common(struct puffs_usermount *, puffs_cookie_t, int);
+int perfuse_ns_match(const int, const char *);
 const char *perfuse_native_ns(const int, const char *, char *);
 
 char *perfuse_fs_mount(int, ssize_t);
diff -r 493acfdabc2c -r aae6812980bb lib/libperfuse/subr.c
--- a/lib/libperfuse/subr.c     Sat Aug 09 22:10:35 2014 +0000
+++ b/lib/libperfuse/subr.c     Sun Aug 10 03:22:33 2014 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: subr.c,v 1.19 2012/07/21 05:49:42 manu Exp $ */
+/*  $NetBSD: subr.c,v 1.20 2014/08/10 03:22:33 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@@ -215,6 +215,20 @@
        return buf;
 }
 
+int
+perfuse_ns_match(const int attrnamespace, const char *attrname)
+{
+       const char *system_ns[] = { "system.", "trusted.", "security", NULL };
+       int i;
+
+        for (i = 0; system_ns[i]; i++) {
+                if (strncmp(attrname, system_ns[i], strlen(system_ns[i])) == 0)
+                       return (attrnamespace == EXTATTR_NAMESPACE_SYSTEM);
+        }
+
+       return (attrnamespace == EXTATTR_NAMESPACE_USER);
+}
+
 const char *
 perfuse_native_ns(const int attrnamespace, const char *attrname,
        char *fuse_attrname)



Home | Main Index | Thread Index | Old Index