351857 confusing error message about valid command line option
392331 Spurious lock not held error from inside pthread_cond_timedwait
400793 pthread_rwlock_timedwrlock false positive
+433873 openat2 syscall unimplemented on Linux
444110 priv/guest_ppc_toIR.c:36198:31: warning: duplicated 'if' condition.
444488 Use glibc.pthread.stack_cache_size tunable
444568 drd/tests/pth_barrier_thr_cr fails on Fedora 38
// Linux-specific (new in Linux 5.9)
DECL_TEMPLATE(linux, sys_close_range);
+DECL_TEMPLATE(linux, sys_openat2);
// Linux-specific (new in Linux 5.14)
DECL_TEMPLATE(linux, sys_memfd_secret);
GENX_(__NR_clone3, sys_ni_syscall), // 435
LINXY(__NR_close_range, sys_close_range), // 436
+ LINXY(__NR_openat2, sys_openat2), // 437
LINX_(__NR_faccessat2, sys_faccessat2), // 439
ML_(record_fd_close)(fd);
}
+
+#define VKI_O_DIRECTORY 00200000
+#define VKI___O_TMPFILE 020000000
+#define VKI_O_TMPFILE (VKI___O_TMPFILE | VKI_O_DIRECTORY)
+
+// long syscall(SYS_openat2, int dirfd, const char *pathname,
+// struct open_how *how, size_t size);
+PRE(sys_openat2)
+{
+ HChar name[30]; // large enough
+ SysRes sres;
+ struct vki_open_how * how;
+
+ PRINT("sys_openat2 ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %ld )",
+ SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, SARG4);
+ PRE_REG_READ4(long, "openat2",
+ int, dfd, const char *, filename, struct vki_open_how *, how, vki_size_t, size);
+
+ PRE_MEM_RASCIIZ( "openat2(filename)", ARG2 );
+ PRE_MEM_READ( "openat2(how)", ARG3, sizeof(struct vki_open_how));
+
+ /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
+ filename is relative to cwd. When comparing dfd against AT_FDCWD,
+ be sure only to compare the bottom 32 bits. */
+ if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
+ && *(Char *)(Addr)ARG2 != '/'
+ && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
+ && !ML_(fd_allowed)(ARG1, "openat2", tid, False))
+ SET_STATUS_Failure( VKI_EBADF );
+
+ how = (struct vki_open_how *)ARG3;
+
+ if (how && ML_(safe_to_deref) (how, sizeof(struct vki_open_how))) {
+ if (how->vki_mode) {
+ if (!(how->vki_flags & ((vki_uint64_t)VKI_O_CREAT | VKI_O_TMPFILE))) {
+ SET_STATUS_Failure( VKI_EINVAL );
+ }
+ }
+ if (how->vki_resolve & ~((vki_uint64_t)VKI_RESOLVE_NO_XDEV |
+ VKI_RESOLVE_NO_MAGICLINKS |
+ VKI_RESOLVE_NO_SYMLINKS |
+ VKI_RESOLVE_BENEATH |
+ VKI_RESOLVE_IN_ROOT |
+ VKI_RESOLVE_CACHED)) {
+ SET_STATUS_Failure( VKI_EINVAL );
+ }
+ }
+
+ /* Handle the case where the open is of /proc/self/cmdline or
+ /proc/<pid>/cmdline, and just give it a copy of the fd for the
+ fake file we cooked up at startup (in m_main). Also, seek the
+ cloned fd back to the start. */
+
+ VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
+ if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
+ && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
+ || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
+ sres = VG_(dup)( VG_(cl_cmdline_fd) );
+ SET_STATUS_from_SysRes( sres );
+ if (!sr_isError(sres)) {
+ OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
+ if (off < 0)
+ SET_STATUS_Failure( VKI_EMFILE );
+ }
+ return;
+ }
+
+ /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
+
+ VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
+ if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
+ && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
+ || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
+ sres = VG_(dup)( VG_(cl_auxv_fd) );
+ SET_STATUS_from_SysRes( sres );
+ if (!sr_isError(sres)) {
+ OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
+ if (off < 0)
+ SET_STATUS_Failure( VKI_EMFILE );
+ }
+ return;
+ }
+
+ /* And for /proc/self/exe or /proc/<pid>/exe case. */
+
+ VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
+ if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
+ && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
+ || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
+ sres = VG_(dup)( VG_(cl_exec_fd) );
+ SET_STATUS_from_SysRes( sres );
+ if (!sr_isError(sres)) {
+ OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
+ if (off < 0)
+ SET_STATUS_Failure( VKI_EMFILE );
+ }
+ return;
+ }
+
+ /* Otherwise handle normally */
+ *flags |= SfMayBlock;
+}
+
+POST(sys_openat2)
+{
+ vg_assert(SUCCESS);
+ if (!ML_(fd_allowed)(RES, "openat2", tid, True)) {
+ VG_(close)(RES);
+ SET_STATUS_Failure( VKI_EMFILE );
+ } else {
+ if (VG_(clo_track_fds))
+ ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
+ }
+}
+
#undef PRE
#undef POST
GENX_(__NR_clone3, sys_ni_syscall), // 435
LINXY(__NR_close_range, sys_close_range), // 436
+ LINXY(__NR_openat2, sys_openat2), // 437
+
LINX_(__NR_faccessat2, sys_faccessat2), // 439
struct vki_timespec it_value;
};
+/* From include/linux/openat2.h */
+
+struct vki_open_how {
+ vki_uint64_t vki_flags;
+ vki_uint64_t vki_mode;
+ vki_uint64_t vki_resolve;
+};
+
+#define VKI_RESOLVE_NO_XDEV 0x01
+#define VKI_RESOLVE_NO_MAGICLINKS 0x02
+#define VKI_RESOLVE_NO_SYMLINKS 0x04
+#define VKI_RESOLVE_BENEATH 0x08
+#define VKI_RESOLVE_IN_ROOT 0x10
+#define VKI_RESOLVE_CACHED 0x20
+
#ifndef VKI_RLIM_INFINITY
#define VKI_RLIM_INFINITY (~0UL)
#endif
#define __NR_clone3 435
#define __NR_close_range 436
+#define __NR_openat2 437
#define __NR_faccessat2 439
GO(__NR_epoll_create1, "1s 0m");
SY(__NR_epoll_create1, x0); SUCC_OR_FAIL;
+ // __NR_openat2 337
+ GO(__NR_openat2, "4s 2m");
+ SY(__NR_openat2, x0, x0+1, x0+1, x0); FAIL;
+
// __NR_process_vm_readv 347
GO(__NR_process_vm_readv, "6s 2m");
SY(__NR_process_vm_readv, x0, x0, x0+1, x0, x0+1, x0); FAIL;
...
by 0x........: main (scalar.c:1277)
+-----------------------------------------------------
+437: __NR_openat2 4s 2m
+-----------------------------------------------------
+Syscall param openat2(dfd) contains uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:1281)
+
+Syscall param openat2(filename) contains uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:1281)
+
+Syscall param openat2(how) contains uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:1281)
+
+Syscall param openat2(size) contains uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:1281)
+
+Syscall param openat2(filename) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:1281)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+Syscall param openat2(how) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:1281)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
-----------------------------------------------------
347:__NR_process_vm_readv 6s 2m
-----------------------------------------------------
Syscall param process_vm_readv(pid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:1281)
+ by 0x........: main (scalar.c:1285)
Syscall param process_vm_readv(lvec) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:1281)
+ by 0x........: main (scalar.c:1285)
Syscall param process_vm_readv(liovcnt) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:1281)
+ by 0x........: main (scalar.c:1285)
Syscall param process_vm_readv(rvec) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:1281)
+ by 0x........: main (scalar.c:1285)
Syscall param process_vm_readv(riovcnt) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:1281)
+ by 0x........: main (scalar.c:1285)
Syscall param process_vm_readv(flags) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:1281)
+ by 0x........: main (scalar.c:1285)
Syscall param process_vm_readv(lvec) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:1281)
+ by 0x........: main (scalar.c:1285)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param process_vm_readv(rvec) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:1281)
+ by 0x........: main (scalar.c:1285)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
-----------------------------------------------------
Syscall param process_vm_writev(pid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:1285)
+ by 0x........: main (scalar.c:1289)
Syscall param process_vm_writev(lvec) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:1285)
+ by 0x........: main (scalar.c:1289)
Syscall param process_vm_writev(liovcnt) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:1285)
+ by 0x........: main (scalar.c:1289)
Syscall param process_vm_writev(rvec) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:1285)
+ by 0x........: main (scalar.c:1289)
Syscall param process_vm_writev(riovcnt) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:1285)
+ by 0x........: main (scalar.c:1289)
Syscall param process_vm_writev(flags) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:1285)
+ by 0x........: main (scalar.c:1289)
Syscall param process_vm_writev(lvec) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:1285)
+ by 0x........: main (scalar.c:1289)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param process_vm_writev(rvec) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:1285)
+ by 0x........: main (scalar.c:1289)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
-----------------------------------------------------
Syscall param exit(status) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:1293)
+ by 0x........: main (scalar.c:1297)