- 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
This commit is contained in:
manu 2014-08-10 03:22:33 +00:00
parent abe84671d3
commit ac7134332d
3 changed files with 73 additions and 25 deletions

View File

@ -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. * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@ -3323,6 +3323,10 @@ perfuse_node_getextattr(struct puffs_usermount *pu, puffs_cookie_t opc,
char *np; char *np;
int error; 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); node_ref(opc);
ps = puffs_getspecific(pu); ps = puffs_getspecific(pu);
attrname = perfuse_native_ns(attrns, attrname, fuse_attrname); attrname = perfuse_native_ns(attrns, attrname, fuse_attrname);
@ -3367,6 +3371,7 @@ perfuse_node_getextattr(struct puffs_usermount *pu, puffs_cookie_t opc,
if (resid != NULL) { if (resid != NULL) {
if (*resid < len) { if (*resid < len) {
error = ERANGE; error = ERANGE;
ps->ps_destroy_msg(pm);
goto out; goto out;
} }
@ -3396,6 +3401,10 @@ perfuse_node_setextattr(struct puffs_usermount *pu, puffs_cookie_t opc,
char *np; char *np;
int error; 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); node_ref(opc);
ps = puffs_getspecific(pu); ps = puffs_getspecific(pu);
attrname = perfuse_native_ns(attrns, attrname, fuse_attrname); attrname = perfuse_native_ns(attrns, attrname, fuse_attrname);
@ -3436,9 +3445,13 @@ perfuse_node_listextattr(struct puffs_usermount *pu, puffs_cookie_t opc,
struct fuse_getxattr_out *fgo; struct fuse_getxattr_out *fgo;
struct fuse_out_header *foh; struct fuse_out_header *foh;
char *np; char *np;
size_t len, puffs_len; size_t len, puffs_len, i, attrlen, outlen;
int error; 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); node_ref(opc);
ps = puffs_getspecific(pu); ps = puffs_getspecific(pu);
@ -3478,29 +3491,45 @@ perfuse_node_listextattr(struct puffs_usermount *pu, puffs_cookie_t opc,
np = (char *)(void *)(foh + 1); np = (char *)(void *)(foh + 1);
puffs_len = foh->len - sizeof(*foh); puffs_len = foh->len - sizeof(*foh);
if (attrs != NULL) { if (attrsize != 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;
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;
}
}
#endif /* PUFFS_EXTATTR_LIST_LENPREFIX */
(void)memcpy(attrs, np, puffs_len);
*resid -= puffs_len;
}
if (attrsize != NULL)
*attrsize = puffs_len; *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) {
(void)memcpy(attrs + outlen + 1,
np + i, attrlen);
*(attrs + outlen) = (uint8_t)attrlen;
} else
#endif /* PUFFS_EXTATTR_LIST_LENPREFIX */
(void)memcpy(attrs + outlen, np + i, attrlen + 1);
outlen += attrlen + 1;
}
*resid -= outlen;
}
ps->ps_destroy_msg(pm); ps->ps_destroy_msg(pm);
error = 0; error = 0;
@ -3520,6 +3549,10 @@ perfuse_node_deleteextattr(struct puffs_usermount *pu, puffs_cookie_t opc,
char *np; char *np;
int error; 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); node_ref(opc);
ps = puffs_getspecific(pu); ps = puffs_getspecific(pu);

View File

@ -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. * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@ -186,6 +186,7 @@ uint64_t perfuse_get_fh(puffs_cookie_t, int);
uint64_t perfuse_next_unique(struct puffs_usermount *); uint64_t perfuse_next_unique(struct puffs_usermount *);
char *perfuse_node_path(struct perfuse_state *, puffs_cookie_t); char *perfuse_node_path(struct perfuse_state *, puffs_cookie_t);
int perfuse_node_close_common(struct puffs_usermount *, puffs_cookie_t, int); 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 *); const char *perfuse_native_ns(const int, const char *, char *);
char *perfuse_fs_mount(int, ssize_t); char *perfuse_fs_mount(int, ssize_t);

View File

@ -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. * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
@ -215,6 +215,20 @@ perfuse_node_path(struct perfuse_state *ps, puffs_cookie_t opc)
return buf; 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 * const char *
perfuse_native_ns(const int attrnamespace, const char *attrname, perfuse_native_ns(const int attrnamespace, const char *attrname,
char *fuse_attrname) char *fuse_attrname)