ufs/extattr.h: Fix documentation of ea_name termination

The ea_name string is not nul-terminated.  Correct the documentation.

Because the subsequent field is padded to 8 bytes, and the padding is
zeroed, the ea_name string will appear to be nul-terminated whenever the
length isn't exactly one (mod eight).

This was introduced in r167010 (2007).

Additionally, mark the length fields as unsigned.  This particularly
matters for the single byte ea_namelength field, which can represent
extended attribute names up to 255 bytes long.

No functional change.

PR:		216127
Reported by:	dewayne at heuristicsystems.com.au
Reviewed by:	kib@
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D9206
This commit is contained in:
cem 2017-01-18 17:55:49 +00:00
parent 7de7dabf52
commit 4d542f9fe8
2 changed files with 17 additions and 50 deletions

View File

@ -28,7 +28,7 @@
.\" @(#)fs.5 8.2 (Berkeley) 4/19/94
.\" $FreeBSD$
.\"
.Dd April 23, 2016
.Dd January 16, 2017
.Dt FS 5
.Os
.Sh NAME
@ -388,18 +388,19 @@ For further information, see the include file
The format of an external attribute is defined by the extattr structure:
.Bd -literal
struct extattr {
int32_t ea_length; /* length of this attribute */
int8_t ea_namespace; /* name space of this attribute */
int8_t ea_contentpadlen; /* padding at end of attribute */
int8_t ea_namelength; /* length of attribute name */
char ea_name[1]; /* null-terminated attribute name */
uint32_t ea_length; /* length of this attribute */
uint8_t ea_namespace; /* name space of this attribute */
uint8_t ea_contentpadlen; /* bytes of padding at end of attribute */
uint8_t ea_namelength; /* length of attribute name */
char ea_name[1]; /* attribute name (NOT nul-terminated) */
/* padding, if any, to align attribute content to 8 byte boundary */
/* extended attribute content follows */
};
.Ed
.Pp
Several macros are defined to manipulate these structures.
Each macro takes a pointer to an extattr structure.
.Bl -tag -width ".Dv EXTATTR_SET_LENGTHS(eap, size)"
.Bl -tag -width ".Dv EXTATTR_CONTENT_SIZE(eap)"
.It Dv EXTATTR_NEXT(eap)
Returns a pointer to the next extended attribute following
.Fa eap .
@ -409,35 +410,19 @@ Returns a pointer to the extended attribute content referenced by
.It Dv EXTATTR_CONTENT_SIZE(eap)
Returns the size of the extended attribute content referenced by
.Fa eap .
.It Dv EXTATTR_SET_LENGTHS(eap, size)
Called with the size of the attribute content after initializing
the attribute name to calculate and set the
.Fa ea_length ,
.Fa ea_namelength ,
and
.Fa ea_contentpadlen
fields of the extended attribute structure.
.El
.Pp
The following code identifies an ACL:
.Bd -literal
if (eap->ea_namespace == EXTATTR_NAMESPACE_SYSTEM &&
!strcmp(eap->ea_name, POSIX1E_ACL_ACCESS_EXTATTR_NAME) {
eap->ea_namelength == sizeof(POSIX1E_ACL_ACCESS_EXTATTR_NAME) - 1 &&
strncmp(eap->ea_name, POSIX1E_ACL_ACCESS_EXTATTR_NAME,
sizeof(POSIX1E_ACL_ACCESS_EXTATTR_NAME) - 1) == 0) {
aclp = EXTATTR_CONTENT(eap);
acllen = EXTATTR_CONTENT_SIZE(eap);
...
}
.Ed
.Pp
The following code creates an extended attribute
containing a copy of a structure
.Fa mygif :
.Bd -literal
eap->ea_namespace = EXTATTR_NAMESPACE_USER;
strcpy(eap->ea_name, "filepic.gif");
EXTATTR_SET_LENGTHS(eap, sizeof(struct mygif));
memcpy(EXTATTR_CONTENT(eap), &mygif, sizeof(struct mygif));
.Ed
.Sh HISTORY
A super-block structure named filsys appeared in
.At v6 .

View File

@ -73,11 +73,12 @@ struct ufs_extattr_header {
* This structure defines the required fields of an extended-attribute header.
*/
struct extattr {
int32_t ea_length; /* length of this attribute */
int8_t ea_namespace; /* name space of this attribute */
int8_t ea_contentpadlen; /* bytes of padding at end of attribute */
int8_t ea_namelength; /* length of attribute name */
char ea_name[1]; /* null-terminated attribute name */
uint32_t ea_length; /* length of this attribute */
uint8_t ea_namespace; /* name space of this attribute */
uint8_t ea_contentpadlen; /* bytes of padding at end of attribute */
uint8_t ea_namelength; /* length of attribute name */
char ea_name[1]; /* attribute name (NOT nul-terminated) */
/* padding, if any, to align attribute content to 8 byte boundary */
/* extended attribute content follows */
};
@ -90,9 +91,6 @@ struct extattr {
* content referenced by eap.
* EXTATTR_CONTENT_SIZE(eap) returns the size of the extended attribute
* content referenced by eap.
* EXTATTR_SET_LENGTHS(eap, contentsize) called after initializing the
* attribute name to calculate and set the ea_length, ea_namelength,
* and ea_contentpadlen fields of the extended attribute structure.
*/
#define EXTATTR_NEXT(eap) \
((struct extattr *)(((void *)(eap)) + (eap)->ea_length))
@ -101,15 +99,6 @@ struct extattr {
((eap)->ea_length - EXTATTR_BASE_LENGTH(eap) - (eap)->ea_contentpadlen)
#define EXTATTR_BASE_LENGTH(eap) \
((sizeof(struct extattr) + (eap)->ea_namelength + 7) & ~7)
#define EXTATTR_SET_LENGTHS(eap, contentsize) do { \
KASSERT(((eap)->ea_name[0] != 0), \
("Must initialize name before setting lengths")); \
(eap)->ea_namelength = strlen((eap)->ea_name); \
(eap)->ea_contentpadlen = ((contentsize) % 8) ? \
8 - ((contentsize) % 8) : 0; \
(eap)->ea_length = EXTATTR_BASE_LENGTH(eap) + \
(contentsize) + (eap)->ea_contentpadlen; \
} while (0)
#ifdef _KERNEL
@ -149,13 +138,6 @@ int ufs_deleteextattr(struct vop_deleteextattr_args *ap);
int ufs_setextattr(struct vop_setextattr_args *ap);
void ufs_extattr_vnode_inactive(struct vnode *vp, struct thread *td);
#else
/* User-level definition of KASSERT for macros above */
#define KASSERT(cond, str) do { \
if (!(cond)) { printf("panic: "); printf(str); printf("\n"); exit(1); }\
} while (0)
#endif /* !_KERNEL */
#endif /* !_UFS_UFS_EXTATTR_H_ */