5 #include "pthread_impl.h"
14 static int checker(void *p
)
18 if (__syscall(SYS_setregid
, __syscall(SYS_getegid
), -1)
19 || __syscall(SYS_setreuid
, __syscall(SYS_geteuid
), -1))
20 __syscall(SYS_exit
, 1);
21 ret
= __syscall(SYS_faccessat
, c
->fd
, c
->filename
, c
->amode
, 0);
22 __syscall(SYS_write
, c
->p
, &ret
, sizeof ret
);
26 int faccessat(int fd
, const char *filename
, int amode
, int flag
)
29 int ret
= __syscall(SYS_faccessat2
, fd
, filename
, amode
, flag
);
30 if (ret
!= -ENOSYS
) return __syscall_ret(ret
);
33 if (flag
& ~AT_EACCESS
)
34 return __syscall_ret(-EINVAL
);
36 if (!flag
|| (getuid()==geteuid() && getgid()==getegid()))
37 return syscall(SYS_faccessat
, fd
, filename
, amode
);
45 if (pipe2(p
, O_CLOEXEC
)) return __syscall_ret(-EBUSY
);
46 struct ctx c
= { .fd
= fd
, .filename
= filename
, .amode
= amode
, .p
= p
[1] };
48 __block_all_sigs(&set
);
50 pid
= __clone(checker
, stack
+sizeof stack
, 0, &c
);
51 __syscall(SYS_close
, p
[1]);
53 if (pid
<0 || __syscall(SYS_read
, p
[0], &ret
, sizeof ret
) != sizeof(ret
))
55 __syscall(SYS_close
, p
[0]);
56 __sys_wait4(pid
, &status
, __WCLONE
, 0);
60 return __syscall_ret(ret
);