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
)
28 if (!flag
|| (flag
==AT_EACCESS
&& getuid()==geteuid() && getgid()==getegid()))
29 return syscall(SYS_faccessat
, fd
, filename
, amode
, flag
);
31 if (flag
!= AT_EACCESS
)
32 return __syscall_ret(-EINVAL
);
40 if (pipe2(p
, O_CLOEXEC
)) return __syscall_ret(-EBUSY
);
41 struct ctx c
= { .fd
= fd
, .filename
= filename
, .amode
= amode
, .p
= p
[1] };
43 __block_all_sigs(&set
);
45 pid
= __clone(checker
, stack
+sizeof stack
, 0, &c
);
46 __syscall(SYS_close
, p
[1]);
48 if (pid
<0 || __syscall(SYS_read
, p
[0], &ret
, sizeof ret
) != sizeof(ret
))
50 __syscall(SYS_close
, p
[0]);
51 __syscall(SYS_wait4
, pid
, &status
, __WCLONE
, 0);
55 return __syscall_ret(ret
);