=========================================================================== linux/fs/xfs/xfs_attr.c =========================================================================== --- /usr/tmp/TmpDir.24546-0/linux/fs/xfs/xfs_attr.c_1.112 2003-12-12 15:56:46.000000000 +1100 +++ linux/fs/xfs/xfs_attr.c 2003-12-12 15:44:59.696535760 +1100 @@ -2651,6 +2651,16 @@ .attr_capable = attr_trusted_capable, }; +struct attrnames attr_secure = { + .attr_name = "security.", + .attr_namelen = sizeof("security.") - 1, + .attr_flag = ATTR_SECURE, + .attr_capable = (attrcapable_t)fs_noerr, + .attr_get = attr_generic_get, + .attr_set = attr_generic_set, + .attr_remove = attr_generic_remove, +}; + struct attrnames attr_user = { .attr_name = "user.", .attr_namelen = sizeof("user.") - 1, @@ -2661,4 +2671,4 @@ }; struct attrnames *attr_namespaces[] = - { &attr_system, &attr_trusted, &attr_user }; + { &attr_system, &attr_trusted, &attr_secure, &attr_user }; =========================================================================== linux/fs/xfs/xfs_attr.h =========================================================================== --- /usr/tmp/TmpDir.24546-0/linux/fs/xfs/xfs_attr.h_1.28 2003-12-12 15:56:46.000000000 +1100 +++ linux/fs/xfs/xfs_attr.h 2003-12-12 15:45:04.047874256 +1100 @@ -69,8 +69,9 @@ 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 @@ #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 */ =========================================================================== linux/fs/xfs/xfs_attr_leaf.c =========================================================================== --- /usr/tmp/TmpDir.24546-0/linux/fs/xfs/xfs_attr_leaf.c_1.75 2003-12-12 15:56:46.000000000 +1100 +++ linux/fs/xfs/xfs_attr_leaf.c 2003-12-12 15:45:07.675322800 +1100 @@ -159,6 +159,9 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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_ROOT) ? &attr_trusted : + ((sfe->flags & XFS_ATTR_SECURE) ? &attr_secure : + &attr_user); if (context->flags & ATTR_KERNOVAL) { ASSERT(context->flags & ATTR_KERNAMELS); context->count += namesp->attr_namelen + @@ -549,7 +564,8 @@ attrnames_t *namesp; namesp = (sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted : - &attr_user; + ((sfe->flags & XFS_ATTR_SECURE) ? &attr_secure : + &attr_user); if (cursor->hashval != INT_GET(sbp->hash, ARCH_CONVERT)) { cursor->hashval = INT_GET(sbp->hash, ARCH_CONVERT); @@ -668,7 +684,8 @@ 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 @@ + 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 @@ 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 @@ 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; @@ -2291,7 +2315,8 @@ continue; /* skip non-matching entries */ namesp = (entry->flags & XFS_ATTR_ROOT) ? &attr_trusted : - &attr_user; + ((entry->flags & XFS_ATTR_SECURE) ? &attr_secure : + &attr_user); if (entry->flags & XFS_ATTR_LOCAL) { name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); =========================================================================== linux/fs/xfs/xfs_attr_leaf.h =========================================================================== --- /usr/tmp/TmpDir.24546-0/linux/fs/xfs/xfs_attr_leaf.h_1.33 2003-12-12 15:56:46.000000000 +1100 +++ linux/fs/xfs/xfs_attr_leaf.h 2003-12-12 15:45:11.415754168 +1100 @@ -73,9 +73,9 @@ * 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 @@ 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 @@ */ #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) /* =========================================================================== linux/fs/xfs/xfsidbg.c =========================================================================== --- /usr/tmp/TmpDir.24546-0/linux/fs/xfs/xfsidbg.c_1.250 2003-12-12 15:56:46.000000000 +1100 +++ linux/fs/xfs/xfsidbg.c 2003-12-12 15:45:15.532128384 +1100 @@ -3178,7 +3178,7 @@ "DONTFOLLOW", /* 0x0001 */ "ROOT", /* 0x0002 */ "TRUSTED", /* 0x0004 */ - "?", /* 0x0008 */ + "SECURE", /* 0x0008 */ "CREATE", /* 0x0010 */ "REPLACE", /* 0x0020 */ "?", /* 0x0040 */ @@ -4791,9 +4791,12 @@ kdb_printf("LOCAL "); if (e->flags & XFS_ATTR_ROOT) kdb_printf("ROOT "); + if (e->flags & XFS_ATTR_SECURE) + kdb_printf("SECURE "); if (e->flags & XFS_ATTR_INCOMPLETE) kdb_printf("INCOMPLETE "); - k = ~(XFS_ATTR_LOCAL | XFS_ATTR_ROOT | XFS_ATTR_INCOMPLETE); + k = ~(XFS_ATTR_LOCAL | XFS_ATTR_ROOT | + XFS_ATTR_SECURE | XFS_ATTR_INCOMPLETE); if ((e->flags & k) != 0) kdb_printf("0x%x", e->flags & k); kdb_printf(">\n name \""); @@ -5652,13 +5655,16 @@ (uint_t)n->hashval, n->whichfork); if (n->flags & ATTR_ROOT) kdb_printf("ROOT "); + if (n->flags & ATTR_SECURE) + kdb_printf("SECURE "); if (n->flags & ATTR_CREATE) kdb_printf("CREATE "); if (n->flags & ATTR_REPLACE) kdb_printf("REPLACE "); if (n->flags & XFS_ATTR_INCOMPLETE) kdb_printf("INCOMPLETE "); - i = ~(ATTR_ROOT | ATTR_CREATE | ATTR_REPLACE | XFS_ATTR_INCOMPLETE); + i = ~(ATTR_ROOT | ATTR_SECURE | + ATTR_CREATE | ATTR_REPLACE | XFS_ATTR_INCOMPLETE); if ((n->flags & i) != 0) kdb_printf("0x%x", n->flags & i); kdb_printf(">\n");