- 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:
parent
abe84671d3
commit
ac7134332d
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue