Module Name:    src
Committed By:   manu
Date:           Sun Aug 10 03:22:33 UTC 2014

Modified Files:
        src/lib/libperfuse: ops.c perfuse_priv.h subr.c

Log Message:
- 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


To generate a diff of this commit:
cvs rdiff -u -r1.65 -r1.66 src/lib/libperfuse/ops.c
cvs rdiff -u -r1.31 -r1.32 src/lib/libperfuse/perfuse_priv.h
cvs rdiff -u -r1.19 -r1.20 src/lib/libperfuse/subr.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libperfuse/ops.c
diff -u src/lib/libperfuse/ops.c:1.65 src/lib/libperfuse/ops.c:1.66
--- src/lib/libperfuse/ops.c:1.65	Sat Aug  9 19:06:50 2014
+++ src/lib/libperfuse/ops.c	Sun Aug 10 03:22:33 2014
@@ -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 @@ perfuse_node_getextattr(struct puffs_use
 	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 @@ perfuse_node_getextattr(struct puffs_use
 	if (resid != NULL) {
 		if (*resid < len) {
 			error = ERANGE;
+			ps->ps_destroy_msg(pm);
 			goto out;
 		}
 
@@ -3396,6 +3401,10 @@ perfuse_node_setextattr(struct puffs_use
 	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 @@ perfuse_node_listextattr(struct puffs_us
 	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,28 +3491,44 @@ perfuse_node_listextattr(struct puffs_us
 	np = (char *)(void *)(foh + 1);
 	puffs_len = foh->len - sizeof(*foh);
 
-	if (attrs != NULL) {
-#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;
+	if (attrsize != NULL)
+		*attrsize = puffs_len;
 
-			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;
-			}	
+	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) {
+				(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;
+		}	
 
-	if (attrsize != NULL) 
-		*attrsize = puffs_len;
+		*resid -= outlen;
+	}
 
 	ps->ps_destroy_msg(pm);
 	error = 0;
@@ -3520,6 +3549,10 @@ perfuse_node_deleteextattr(struct puffs_
 	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);

Index: src/lib/libperfuse/perfuse_priv.h
diff -u src/lib/libperfuse/perfuse_priv.h:1.31 src/lib/libperfuse/perfuse_priv.h:1.32
--- src/lib/libperfuse/perfuse_priv.h:1.31	Sat Jul 21 05:49:42 2012
+++ src/lib/libperfuse/perfuse_priv.h	Sun Aug 10 03:22:33 2014
@@ -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_get_fh(puffs_cookie_t, 
 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);

Index: src/lib/libperfuse/subr.c
diff -u src/lib/libperfuse/subr.c:1.19 src/lib/libperfuse/subr.c:1.20
--- src/lib/libperfuse/subr.c:1.19	Sat Jul 21 05:49:42 2012
+++ src/lib/libperfuse/subr.c	Sun Aug 10 03:22:33 2014
@@ -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 @@ perfuse_node_path(struct perfuse_state *
 	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)

Reply via email to