Skip to content

Commit ef45c3e

Browse files
committed
compat/linux: return EBADF for LTP open13 O_PATH operations
Before this change, LTP open13 failed on O_PATH mmap() and fgetxattr() operations, returning EACCES and EOPNOTSUPP instead of the expected EBADF. After this change, EBADF returned as Linux expected Signed-off-by: YAO, Xin <mr.yaoxin@outlook.com>
1 parent 40d59ee commit ef45c3e

2 files changed

Lines changed: 39 additions & 0 deletions

File tree

sys/compat/linux/linux_mmap.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ static int
6363
linux_mmap_check_fp(struct file *fp, int flags, int prot, int maxprot)
6464
{
6565

66+
/* Linux returns EBADF if mmap() is called on an O_PATH file descriptor */
67+
if (fp->f_ops == &path_fileops)
68+
return (EBADF);
69+
6670
/* Linux mmap() just fails for O_WRONLY files */
6771
if ((fp->f_flag & FREAD) == 0)
6872
return (EACCES);

sys/compat/linux/linux_xattr.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
*/
2727

2828
#include <sys/param.h>
29+
#include <sys/capsicum.h>
2930
#include <sys/extattr.h>
3031
#include <sys/fcntl.h>
32+
#include <sys/file.h>
3133
#include <sys/namei.h>
3234
#include <sys/proc.h>
3335
#include <sys/syscallsubr.h>
@@ -84,6 +86,21 @@ struct removexattr_args {
8486
int follow;
8587
};
8688

89+
static int
90+
linux_xattr_check_fd(struct thread *td, int fd)
91+
{
92+
struct file *fp;
93+
cap_rights_t rights;
94+
int error;
95+
96+
error = getvnode(td, fd, cap_rights_init_one(&rights, CAP_EXTATTR_GET),
97+
&fp);
98+
if (error != 0)
99+
return (error);
100+
fdrop(fp, td);
101+
return (0);
102+
}
103+
87104
static char *extattr_namespace_names[] = EXTATTR_NAMESPACE_NAMES;
88105

89106

@@ -255,6 +272,12 @@ removexattr(struct thread *td, struct removexattr_args *args)
255272
char attrname[LINUX_XATTR_NAME_MAX + 1];
256273
int attrnamespace, error;
257274

275+
if (args->path == NULL) {
276+
error = linux_xattr_check_fd(td, args->fd);
277+
if (error != 0)
278+
return (error);
279+
}
280+
258281
error = xattr_to_extattr(args->name, &attrnamespace, attrname);
259282
if (error != 0)
260283
return (error);
@@ -312,6 +335,12 @@ getxattr(struct thread *td, struct getxattr_args *args)
312335
char attrname[LINUX_XATTR_NAME_MAX + 1];
313336
int attrnamespace, error;
314337

338+
if (args->path == NULL) {
339+
error = linux_xattr_check_fd(td, args->fd);
340+
if (error != 0)
341+
return (error);
342+
}
343+
315344
error = xattr_to_extattr(args->name, &attrnamespace, attrname);
316345
if (error != 0)
317346
return (error);
@@ -375,6 +404,12 @@ setxattr(struct thread *td, struct setxattr_args *args)
375404
char attrname[LINUX_XATTR_NAME_MAX + 1];
376405
int attrnamespace, error;
377406

407+
if (args->path == NULL) {
408+
error = linux_xattr_check_fd(td, args->fd);
409+
if (error != 0)
410+
return (error);
411+
}
412+
378413
if ((args->flags & ~(LINUX_XATTR_FLAGS)) != 0 ||
379414
args->flags == (LINUX_XATTR_FLAGS))
380415
return (EINVAL);

0 commit comments

Comments
 (0)