Skip to content

Commit 63c88bc

Browse files
committed
compat/linux: return EBADF for O_PATH mmap() and xattr operations
This fixes LTP open13, which expects O_PATH mmap() and fgetxattr() to fail with EBADF, but FreeBSD returned EACCES for mmap() and EOPNOTSUPP for fgetxattr(). Apply the same EBADF handling to fsetxattr(), fremovexattr(), and flistxattr() so the xattr paths stay consistent. Signed-off-by: YAO, Xin <mr.yaoxin@outlook.com>
1 parent 40d59ee commit 63c88bc

2 files changed

Lines changed: 51 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: 47 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,19 @@ struct removexattr_args {
8486
int follow;
8587
};
8688

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

89104

@@ -132,12 +147,20 @@ listxattr(struct thread *td, struct listxattr_args *args)
132147
{
133148
char attrname[LINUX_XATTR_NAME_MAX + 1];
134149
char *data, *prefix, *key;
150+
cap_rights_t rights;
135151
struct uio auio;
136152
struct iovec aiov;
137153
unsigned char keylen;
138154
size_t sz, cnt, rs, prefixlen, pairlen;
139155
int attrnamespace, error;
140156

157+
if (args->path == NULL) {
158+
error = linux_xattr_check_fd(td, args->fd,
159+
cap_rights_init_one(&rights, CAP_EXTATTR_LIST));
160+
if (error != 0)
161+
return (error);
162+
}
163+
141164
if (args->size != 0)
142165
sz = min(LINUX_XATTR_LIST_MAX, args->size);
143166
else
@@ -253,8 +276,16 @@ static int
253276
removexattr(struct thread *td, struct removexattr_args *args)
254277
{
255278
char attrname[LINUX_XATTR_NAME_MAX + 1];
279+
cap_rights_t rights;
256280
int attrnamespace, error;
257281

282+
if (args->path == NULL) {
283+
error = linux_xattr_check_fd(td, args->fd,
284+
cap_rights_init_one(&rights, CAP_EXTATTR_DELETE));
285+
if (error != 0)
286+
return (error);
287+
}
288+
258289
error = xattr_to_extattr(args->name, &attrnamespace, attrname);
259290
if (error != 0)
260291
return (error);
@@ -310,8 +341,16 @@ static int
310341
getxattr(struct thread *td, struct getxattr_args *args)
311342
{
312343
char attrname[LINUX_XATTR_NAME_MAX + 1];
344+
cap_rights_t rights;
313345
int attrnamespace, error;
314346

347+
if (args->path == NULL) {
348+
error = linux_xattr_check_fd(td, args->fd,
349+
cap_rights_init_one(&rights, CAP_EXTATTR_GET));
350+
if (error != 0)
351+
return (error);
352+
}
353+
315354
error = xattr_to_extattr(args->name, &attrnamespace, attrname);
316355
if (error != 0)
317356
return (error);
@@ -373,8 +412,16 @@ static int
373412
setxattr(struct thread *td, struct setxattr_args *args)
374413
{
375414
char attrname[LINUX_XATTR_NAME_MAX + 1];
415+
cap_rights_t rights;
376416
int attrnamespace, error;
377417

418+
if (args->path == NULL) {
419+
error = linux_xattr_check_fd(td, args->fd,
420+
cap_rights_init_one(&rights, CAP_EXTATTR_SET));
421+
if (error != 0)
422+
return (error);
423+
}
424+
378425
if ((args->flags & ~(LINUX_XATTR_FLAGS)) != 0 ||
379426
args->flags == (LINUX_XATTR_FLAGS))
380427
return (EINVAL);

0 commit comments

Comments
 (0)