From bd997c62b77d1a72ac39e8b7e3595585db342589 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Sat, 31 Jan 2004 12:25:16 +1100 Subject: [PATCH] [XFS] Add the security extended attributes namespace. SGI Modid: xfs-linux:xfs-kern:165638a --- fs/xfs/linux/xfs_super.h | 9 ++++++++ fs/xfs/xfs_attr.c | 20 +++++++++++++++++- fs/xfs/xfs_attr.h | 4 +++- fs/xfs/xfs_attr_leaf.c | 45 +++++++++++++++++++++++++++++++--------- fs/xfs/xfs_attr_leaf.h | 8 ++++--- 5 files changed, 71 insertions(+), 15 deletions(-) diff --git a/fs/xfs/linux/xfs_super.h b/fs/xfs/linux/xfs_super.h index d2238a9f6db54..2716ad9296fb8 100644 --- a/fs/xfs/linux/xfs_super.h +++ b/fs/xfs/linux/xfs_super.h @@ -60,6 +60,14 @@ # define set_posix_acl_flag(sb) do { } while (0) #endif +#ifdef CONFIG_XFS_SECURITY +# define XFS_SECURITY_STRING "security attrs, " +# define ENOSECURITY 0 +#else +# define XFS_SECURITY_STRING +# define ENOSECURITY EOPNOTSUPP +#endif + #ifdef CONFIG_XFS_RT # define XFS_REALTIME_STRING "realtime, " #else @@ -89,6 +97,7 @@ #endif #define XFS_BUILD_OPTIONS XFS_ACL_STRING \ + XFS_SECURITY_STRING \ XFS_REALTIME_STRING \ XFS_BIGFS_STRING \ XFS_TRACE_STRING \ diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 088cb2321ee22..898de3642fec6 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c @@ -2587,6 +2587,14 @@ attr_trusted_capable( return 0; } +STATIC int +attr_secure_capable( + struct vnode *vp, + cred_t *cred) +{ + return -ENOSECURITY; +} + STATIC int attr_system_set( struct vnode *vp, char *name, void *data, size_t size, int xflags) @@ -2650,6 +2658,16 @@ struct attrnames attr_trusted = { .attr_capable = attr_trusted_capable, }; +struct attrnames attr_secure = { + .attr_name = "security.", + .attr_namelen = sizeof("security.") - 1, + .attr_flag = ATTR_SECURE, + .attr_get = attr_generic_get, + .attr_set = attr_generic_set, + .attr_remove = attr_generic_remove, + .attr_capable = attr_secure_capable, +}; + struct attrnames attr_user = { .attr_name = "user.", .attr_namelen = sizeof("user.") - 1, @@ -2660,4 +2678,4 @@ struct attrnames attr_user = { }; struct attrnames *attr_namespaces[] = - { &attr_system, &attr_trusted, &attr_user }; + { &attr_system, &attr_trusted, &attr_secure, &attr_user }; diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h index a7e05c6719177..c83011f9706d8 100644 --- a/fs/xfs/xfs_attr.h +++ b/fs/xfs/xfs_attr.h @@ -69,8 +69,9 @@ typedef struct attrnames { attrcapable_t attr_capable; } attrnames_t; -#define ATTR_NAMECOUNT 3 +#define ATTR_NAMECOUNT 4 extern struct attrnames attr_user; +extern struct attrnames attr_secure; extern struct attrnames attr_system; extern struct attrnames attr_trusted; extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; @@ -86,6 +87,7 @@ extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *); #define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */ #define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */ #define ATTR_TRUST 0x0004 /* -- unused, from IRIX -- */ +#define ATTR_SECURE 0x0008 /* use attrs in security namespace */ #define ATTR_CREATE 0x0010 /* pure create: fail if attr already exists */ #define ATTR_REPLACE 0x0020 /* pure set: fail if attr does not exist */ #define ATTR_SYSTEM 0x0100 /* use attrs in system (pseudo) namespace */ diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 06e386f3539ab..22f38db4ee9ae 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c @@ -159,6 +159,9 @@ xfs_attr_shortform_add(xfs_da_args_t *args) continue; if (memcmp(args->name, sfe->nameval, args->namelen) != 0) continue; + if (((args->flags & ATTR_SECURE) != 0) != + ((sfe->flags & XFS_ATTR_SECURE) != 0)) + continue; if (((args->flags & ATTR_ROOT) != 0) != ((sfe->flags & XFS_ATTR_ROOT) != 0)) continue; @@ -173,7 +176,8 @@ xfs_attr_shortform_add(xfs_da_args_t *args) sfe->namelen = args->namelen; INT_SET(sfe->valuelen, ARCH_CONVERT, args->valuelen); - sfe->flags = (args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0; + sfe->flags = (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE : + ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0); memcpy(sfe->nameval, args->name, args->namelen); memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen); INT_MOD(sf->hdr.count, ARCH_CONVERT, 1); @@ -209,6 +213,9 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) continue; if (memcmp(sfe->nameval, args->name, args->namelen) != 0) continue; + if (((args->flags & ATTR_SECURE) != 0) != + ((sfe->flags & XFS_ATTR_SECURE) != 0)) + continue; if (((args->flags & ATTR_ROOT) != 0) != ((sfe->flags & XFS_ATTR_ROOT) != 0)) continue; @@ -253,6 +260,9 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args) continue; if (memcmp(args->name, sfe->nameval, args->namelen) != 0) continue; + if (((args->flags & ATTR_SECURE) != 0) != + ((sfe->flags & XFS_ATTR_SECURE) != 0)) + continue; if (((args->flags & ATTR_ROOT) != 0) != ((sfe->flags & XFS_ATTR_ROOT) != 0)) continue; @@ -281,6 +291,9 @@ xfs_attr_shortform_getvalue(xfs_da_args_t *args) continue; if (memcmp(args->name, sfe->nameval, args->namelen) != 0) continue; + if (((args->flags & ATTR_SECURE) != 0) != + ((sfe->flags & XFS_ATTR_SECURE) != 0)) + continue; if (((args->flags & ATTR_ROOT) != 0) != ((sfe->flags & XFS_ATTR_ROOT) != 0)) continue; @@ -369,7 +382,8 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) nargs.valuelen = INT_GET(sfe->valuelen, ARCH_CONVERT); nargs.hashval = xfs_da_hashname((char *)sfe->nameval, sfe->namelen); - nargs.flags = (sfe->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0; + nargs.flags = (sfe->flags & XFS_ATTR_SECURE) ? ATTR_SECURE : + ((sfe->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0); error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */ ASSERT(error == ENOATTR); error = xfs_attr_leaf_add(bp, &nargs); @@ -446,14 +460,15 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) { attrnames_t *namesp; - namesp = (sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted : - &attr_user; if (((context->flags & ATTR_ROOT) != 0) != ((sfe->flags & XFS_ATTR_ROOT) != 0) && !(context->flags & ATTR_KERNFULLS)) { sfe = XFS_ATTR_SF_NEXTENTRY(sfe); continue; } + namesp = (sfe->flags & XFS_ATTR_SECURE) ? &attr_secure: + ((sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted : + &attr_user); if (context->flags & ATTR_KERNOVAL) { ASSERT(context->flags & ATTR_KERNAMELS); context->count += namesp->attr_namelen + @@ -548,8 +563,9 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) for ( ; i < nsbuf; i++, sbp++) { attrnames_t *namesp; - namesp = (sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted : - &attr_user; + namesp = (sfe->flags & XFS_ATTR_SECURE) ? &attr_secure : + ((sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted : + &attr_user); if (cursor->hashval != INT_GET(sbp->hash, ARCH_CONVERT)) { cursor->hashval = INT_GET(sbp->hash, ARCH_CONVERT); @@ -668,7 +684,8 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args) nargs.value = (char *)&name_loc->nameval[nargs.namelen]; nargs.valuelen = INT_GET(name_loc->valuelen, ARCH_CONVERT); nargs.hashval = INT_GET(entry->hashval, ARCH_CONVERT); - nargs.flags = (entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0; + nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE : + ((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0); xfs_attr_shortform_add(&nargs); } error = 0; @@ -963,7 +980,8 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) + INT_GET(map->size, ARCH_CONVERT)); INT_SET(entry->hashval, ARCH_CONVERT, args->hashval); entry->flags = tmp ? XFS_ATTR_LOCAL : 0; - entry->flags |= (args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0; + entry->flags |= (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE : + ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0); if (args->rename) { entry->flags |= XFS_ATTR_INCOMPLETE; if ((args->blkno2 == args->blkno) && @@ -1881,6 +1899,9 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) if (memcmp(args->name, (char *)name_loc->nameval, args->namelen) != 0) continue; + if (((args->flags & ATTR_SECURE) != 0) != + ((entry->flags & XFS_ATTR_SECURE) != 0)) + continue; if (((args->flags & ATTR_ROOT) != 0) != ((entry->flags & XFS_ATTR_ROOT) != 0)) continue; @@ -1893,6 +1914,9 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) if (memcmp(args->name, (char *)name_rmt->name, args->namelen) != 0) continue; + if (((args->flags & ATTR_SECURE) != 0) != + ((entry->flags & XFS_ATTR_SECURE) != 0)) + continue; if (((args->flags & ATTR_ROOT) != 0) != ((entry->flags & XFS_ATTR_ROOT) != 0)) continue; @@ -2290,8 +2314,9 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) !(context->flags & ATTR_KERNFULLS)) continue; /* skip non-matching entries */ - namesp = (entry->flags & XFS_ATTR_ROOT) ? &attr_trusted : - &attr_user; + namesp = (entry->flags & XFS_ATTR_SECURE) ? &attr_secure : + ((entry->flags & XFS_ATTR_ROOT) ? &attr_trusted : + &attr_user); if (entry->flags & XFS_ATTR_LOCAL) { name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h index 8f2b36c7356ce..97bac75c6064a 100644 --- a/fs/xfs/xfs_attr_leaf.h +++ b/fs/xfs/xfs_attr_leaf.h @@ -73,9 +73,9 @@ struct xfs_trans; * to work "forw"ard. If none matches, continue with the "forw"ard leaf * nodes until the hash key changes or the attribute name is found. * - * We store the fact that an attribute is a ROOT versus USER attribute in + * We store the fact that an attribute is a ROOT/USER/SECURE attribute in * the leaf_entry. The namespaces are independent only because we also look - * at the root/user bit when we are looking for a matching attribute name. + * at the namespace bit when we are looking for a matching attribute name. * * We also store a "incomplete" bit in the leaf_entry. It shows that an * attribute is in the middle of being created and should not be shown to @@ -102,7 +102,7 @@ typedef struct xfs_attr_leafblock { struct xfs_attr_leaf_entry { /* sorted on key, not name */ xfs_dahash_t hashval; /* hash value of name */ __uint16_t nameidx; /* index into buffer of name/value */ - __uint8_t flags; /* LOCAL, ROOT and INCOMPLETE flags */ + __uint8_t flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */ __uint8_t pad2; /* unused pad byte */ } entries[1]; /* variable sized array */ struct xfs_attr_leaf_name_local { @@ -130,9 +130,11 @@ typedef struct xfs_attr_leaf_name_remote xfs_attr_leaf_name_remote_t; */ #define XFS_ATTR_LOCAL_BIT 0 /* attr is stored locally */ #define XFS_ATTR_ROOT_BIT 1 /* limit access to trusted attrs */ +#define XFS_ATTR_SECURE_BIT 2 /* limit access to secure attrs */ #define XFS_ATTR_INCOMPLETE_BIT 7 /* attr in middle of create/delete */ #define XFS_ATTR_LOCAL (1 << XFS_ATTR_LOCAL_BIT) #define XFS_ATTR_ROOT (1 << XFS_ATTR_ROOT_BIT) +#define XFS_ATTR_SECURE (1 << XFS_ATTR_SECURE_BIT) #define XFS_ATTR_INCOMPLETE (1 << XFS_ATTR_INCOMPLETE_BIT) /* -- 2.53.0