Skip to content

Commit 7791809

Browse files
committed
linuxulator: improve getxattr() error handling
- Return ERANGE for short getxattr buffers: when the caller provides a buffer smaller than the xattr value, linux_getxattr() and linux_lgetxattr() should set the return value to the full size of the attribute and return ERANGE, matching Linux behavior. This fixes the LTP getxattr01 test. - Return ENODATA for getxattr on unsupported file types: for file types that do not support extended attributes (fifo, char device, block device, UNIX domain socket), the FreeBSD VFS layer returns EOPNOTSUPP via vop_eopnotsupp(). Map this to ENOATTR so that the Linux errno translation produces ENODATA (61), matching Linux behavior. This fixes the LTP getxattr02 test. Signed-off-by: YAO, Xin <mr.yaoxin@outlook.com>
1 parent 28d85db commit 7791809

1 file changed

Lines changed: 17 additions & 1 deletion

File tree

sys/compat/linux/linux_xattr.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,18 +310,34 @@ static int
310310
getxattr(struct thread *td, struct getxattr_args *args)
311311
{
312312
char attrname[LINUX_XATTR_NAME_MAX + 1];
313+
ssize_t size;
313314
int attrnamespace, error;
314315

315316
error = xattr_to_extattr(args->name, &attrnamespace, attrname);
316317
if (error != 0)
317318
return (error);
319+
if (args->path != NULL)
320+
error = kern_extattr_get_path(td, args->path, attrnamespace,
321+
attrname, NULL, 0, args->follow, UIO_USERSPACE);
322+
else
323+
error = kern_extattr_get_fd(td, args->fd, attrnamespace,
324+
attrname, NULL, 0);
325+
if (error != 0)
326+
goto out;
327+
if (args->value == NULL || args->size == 0)
328+
return (0);
329+
size = td->td_retval[0];
330+
if (size > args->size)
331+
return (ERANGE);
318332
if (args->path != NULL)
319333
error = kern_extattr_get_path(td, args->path, attrnamespace,
320334
attrname, args->value, args->size, args->follow, UIO_USERSPACE);
321335
else
322336
error = kern_extattr_get_fd(td, args->fd, attrnamespace,
323337
attrname, args->value, args->size);
324-
return (error == EPERM ? ENOATTR : error);
338+
339+
out:
340+
return (error == EPERM || error == EOPNOTSUPP ? ENOATTR : error);
325341
}
326342

327343
int

0 commit comments

Comments
 (0)