More changes for FreeBSD 13.1

These concern auxv, swapoff and fcntl F_KINFO

I wanted to use the new fcntl K_INFO to replace the existing
horrible implementation of resolve_filename, but it seems to
have change the behaviour for redirected files. Several
fdleak regtests fail because stdout resolves to an empty
string.
This commit is contained in:
Paul Floyd 2022-05-14 16:46:03 +02:00
parent 7e5073f853
commit 6cb8e52c34
8 changed files with 233 additions and 52 deletions

View File

@ -422,6 +422,9 @@ Bool ML_(am_resolve_filename) ( Int fd, /*OUT*/HChar* buf, Int nbuf )
return False;
#elif defined(VGO_freebsd)
#if (1)
Int mib[4];
SysRes sres;
vki_size_t len;
@ -444,15 +447,29 @@ Bool ML_(am_resolve_filename) ( Int fd, /*OUT*/HChar* buf, Int nbuf )
eb = filedesc_buf + len;
while (bp < eb) {
kf = (struct vki_kinfo_file *)bp;
if (kf->kf_fd == fd)
if (kf->vki_kf_fd == fd)
break;
bp += kf->kf_structsize;
bp += kf->vki_kf_structsize;
}
if (bp >= eb || *kf->kf_path == '\0')
if (bp >= eb || *kf->vki_kf_path == '\0')
VG_(strncpy)( buf, "[unknown]", nbuf );
else
VG_(strncpy)( buf, kf->kf_path, nbuf );
VG_(strncpy)( buf, kf->vki_kf_path, nbuf );
return True;
#else
// PJF it will be a relief to get rid of the above bit of ugliness
struct vki_kinfo_file kinfo_file;
kinfo_file.vki_kf_structsize = VKI_KINFO_FILE_SIZE;
if (0 == ML_(am_fcntl) ( fd, VKI_F_KINFO, (Addr)&kinfo_file )) {
if (nbuf > 0) {
VG_(strncpy)( buf, kinfo_file.vki_kf_path, nbuf < VKI_PATH_MAX ? nbuf : VKI_PATH_MAX );
buf[nbuf-1] = 0;
}
if (buf[0] == '/') return True;
}
return False;
#endif
#elif defined(VGO_darwin)
HChar tmp[VKI_MAXPATHLEN+1];
if (0 == ML_(am_fcntl)(fd, VKI_F_GETPATH, (UWord)tmp)) {

View File

@ -694,7 +694,7 @@ Addr setup_client_stack( void* init_sp,
// case AT_PS_STRINGS:
#endif
#if (FREEBSD_VERS >= FREEBSD_14)
#if (FREEBSD_VERS >= FREEBSD_13_1)
// I think that this is a pointer to a "fenestrasX" structture
// lots of stuff that I don't understand
// arc4random, passing through VDSO page ...

View File

@ -119,6 +119,8 @@ Bool VG_(resolve_filename) ( Int fd, const HChar** result )
return False;
#elif defined(VGO_freebsd)
#if (1)
Int mib[4];
SysRes sres;
vki_size_t len;
@ -148,16 +150,36 @@ Bool VG_(resolve_filename) ( Int fd, const HChar** result )
eb = filedesc_buf + len;
while (bp < eb) {
kf = (struct vki_kinfo_file *)bp;
if (kf->kf_fd == fd)
if (kf->vki_kf_fd == fd)
break;
bp += kf->kf_structsize;
bp += kf->vki_kf_structsize;
}
if (bp >= eb || *kf->kf_path == '\0')
if (bp >= eb || *kf->vki_kf_path == '\0')
VG_(strncpy)( buf, "[unknown]", bufsiz );
else
VG_(strncpy)( buf, kf->kf_path, bufsiz );
VG_(strncpy)( buf, kf->vki_kf_path, bufsiz );
*result = buf;
return True;
#else
// PJF it will be a relief to get rid of the above bit of ugliness
// however it does not seem to have the same functionality
// regarding pipes where it profuces just an empty string
struct vki_kinfo_file kinfo_file;
kinfo_file.vki_kf_structsize = VKI_KINFO_FILE_SIZE;
if (0 == VG_(fcntl) ( fd, VKI_F_KINFO, (Addr)&kinfo_file )) {
static HChar *buf = NULL;
if (buf == NULL)
buf = VG_(malloc)("resolve_filename", VKI_PATH_MAX);
*result = buf;
VG_(strcpy)( buf, kinfo_file.vki_kf_path );
if (buf[0] == '/') return True;
}
*result = NULL;
return False;
#endif
# elif defined(VGO_darwin)
HChar tmp[VKI_MAXPATHLEN+1];
if (0 == VG_(fcntl)(fd, VKI_F_GETPATH, (UWord)tmp)) {
@ -181,6 +203,8 @@ Bool VG_(resolve_filename) ( Int fd, const HChar** result )
#if defined(VGO_freebsd)
#if (1)
/* This should only be called after a successful call to
* Bool VG_(resolve_filename) ( Int fd, const HChar** result )
* so that filedesc_buf is still valid for fd */
@ -194,16 +218,29 @@ Bool VG_(resolve_filemode) ( Int fd, Int * result )
eb = filedesc_buf + sizeof(filedesc_buf);
while (bp < eb) {
kf = (struct vki_kinfo_file *)bp;
if (kf->kf_fd == fd)
if (kf->vki_kf_fd == fd)
break;
bp += kf->kf_structsize;
bp += kf->vki_kf_structsize;
}
if (bp >= eb)
*result = -1;
else
*result = kf->kf_flags;
*result = kf->vki_kf_flags;
return True;
}
#else
/* less ugly version, no dependency on resolve_filename */
Bool VG_(resolve_filemode) ( Int fd, Int * result )
{
struct vki_kinfo_file kinfo_file;
kinfo_file.vki_kf_structsize = VKI_KINFO_FILE_SIZE;
if (0 == VG_(fcntl) ( fd, VKI_F_KINFO, (Addr)&kinfo_file )) {
*result = kinfo_file.vki_kf_flags;
return True;
}
return False;
}
#endif
#endif

View File

@ -372,7 +372,7 @@ DECL_TEMPLATE(freebsd, sys_getcontext) // 421
DECL_TEMPLATE(freebsd, sys_setcontext) // 422
DECL_TEMPLATE(freebsd, sys_swapcontext) // 423
#if (FREEBSD_VERS >= FREEBSD_14)
#if (FREEBSD_VERS >= FREEBSD_13_1)
DECL_TEMPLATE(freebsd, sys_freebsd13_swapoff) // 424
#else
DECL_TEMPLATE(freebsd, sys_swapoff) // 424
@ -552,7 +552,7 @@ DECL_TEMPLATE(freebsd, sys___specialfd) // 577
#endif
#if (FREEBSD_VERS >= FREEBSD_14)
#if (FREEBSD_VERS >= FREEBSD_13_1)
// unimpl __NR_fspacectl 580
// unimpl __NR_sched_getcpu 581

View File

@ -1326,6 +1326,15 @@ PRE(sys_fcntl)
int, fd, int, cmd,
struct flock *, lock);
break;
case VKI_F_KINFO:
PRINT("sys_fcntl[ARG3=='kinfo_file'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3);
PRE_REG_READ3(int, "fcntl",
int, fd, int, cmd,
struct vki_kinfo_file *, kinfo);
if (ARG3) {
struct vki_kinfo_file* p_kinfo_file = (struct vki_kinfo_file*)ARG3;
PRE_MEM_WRITE("fcntl(ARG3=='kinfo_file)", ARG3, p_kinfo_file->vki_kf_structsize);
}
default:
PRINT("sys_fcntl[UNKNOWN] ( %lu, %lu, %lu )", ARG1,ARG2,ARG3);
@ -3856,7 +3865,7 @@ POST(sys_swapcontext)
POST_MEM_WRITE( ARG1, sizeof(struct vki_ucontext) );
}
#if (FREEBSD_VERS >= FREEBSD_14)
#if (FREEBSD_VERS >= FREEBSD_13_1)
// SYS_freebsd13_swapoff 424
// int swapoff(const char *special);
PRE(sys_freebsd13_swapoff)
@ -6296,7 +6305,7 @@ PRE(sys___specialfd)
#endif // (FREEBSD_VERS >= FREEBSD_13_0)
#if (FREEBSD_VERS >= FREEBSD_14)
#if (FREEBSD_VERS >= FREEBSD_13_1)
// SYS_swapoff 582
// int swapoff(const char *special, u_int flags);
@ -6813,7 +6822,7 @@ const SyscallTableEntry ML_(syscall_table)[] = {
BSDX_(__NR_setcontext, sys_setcontext), // 422
BSDXY(__NR_swapcontext, sys_swapcontext), // 423
#if (FREEBSD_VERS >= FREEBSD_14)
#if (FREEBSD_VERS >= FREEBSD_13_1)
BSDX_(__NR_freebsd13_swapoff, sys_freebsd13_swapoff), // 424
#else
BSDX_(__NR_swapoff, sys_swapoff), // 424
@ -7022,7 +7031,7 @@ const SyscallTableEntry ML_(syscall_table)[] = {
// unimpl __NR_aio_readv 579
#endif
#if (FREEBSD_VERS >= FREEBSD_14)
#if (FREEBSD_VERS >= FREEBSD_13_1)
// unimpl __NR_fspacectl 580
// unimpl __NR_sched_getcpu 581
BSDX_(__NR_swapoff, sys_swapoff), // 582

View File

@ -1569,7 +1569,7 @@ struct vki_dirent {
#define VKI_F_GETOWN 6 /* for sockets. */
#define VKI_F_OGETLK 7 /* get record locking information */
#define VKI_F_OSETLK 8 /* set record locking information */
#define VKI_F_OSETLKW 9 /* F_SETLK; wait if blocked */
#define VKI_F_OSETLKW 9 /* F_SETLK; wait if blocked */
#define VKI_F_DUP2FD 10 /* duplicate file descriptor to arg */
#define VKI_F_GETLK 11 /* get record locking information */
#define VKI_F_SETLK 12 /* set record locking information */
@ -1577,11 +1577,13 @@ struct vki_dirent {
#define VKI_F_SETLK_REMOTE 14 /* debugging support for remote locks */
#define VKI_F_READAHEAD 15 /* read ahead */
#define VKI_F_RDAHEAD 16 /* Darwin compatible read ahead */
#define VKI_F_DUPFD_CLOEXEC 17 /* dup close_on_exec */
#define VKI_F_DUP2FD_CLOEXEC 18 /* Like F_DUP2FD, but FD_CLOEXEC is set */
#define VKI_F_DUPFD_CLOEXEC 17 /* dup close_on_exec */
#define VKI_F_DUP2FD_CLOEXEC 18 /* Like F_DUP2FD, but FD_CLOEXEC is set */
#define VKI_F_ADD_SEALS 19 /* apply seals to underlying file */
#define VKI_F_GET_SEALS 20 /* get seals to underlying file */
#define VKI_F_ISUNIONSTACK 21 /* kludge for libc (part of a union stack?) */
/* FreeBSD 13.1 and later */
#define VKI_F_KINFO 22 /* Return kinfo_file for this fd */
/* for F_[GET|SET]FL */
#define VKI_FD_CLOEXEC 1 /* actually anything with low bit set goes */
@ -2101,6 +2103,39 @@ struct vki_uuid {
vki_uint8_t node[6];
};
//----------------------------------------------------------------------
// sys/_sockaddr_storage.h
//----------------------------------------------------------------------
#define VKI__SS_MAXSIZE 128U
#define VKI__SS_ALIGNSIZE (sizeof(__int64_t))
#define VKI__SS_PAD1SIZE (VKI__SS_ALIGNSIZE - sizeof(unsigned char) - \
sizeof(vki_sa_family_t))
#define VKI__SS_PAD2SIZE (VKI__SS_MAXSIZE - sizeof(unsigned char) - \
sizeof(sa_family_t) - VKI__SS_PAD1SIZE - VKI__SS_ALIGNSIZE)
struct vki_sockaddr_storage {
unsigned char vki_ss_len; /* address length */
vki_sa_family_t vki_ss_family; /* address family */
char vki___ss_pad1[VKI__SS_PAD1SIZE];
__int64_t vki___ss_align; /* force desired struct alignment */
char vki___ss_pad2VKI_[_SS_PAD2SIZE];
};
//----------------------------------------------------------------------
// From sys/captrights.h
//----------------------------------------------------------------------
#define VKI_CAP_RIGHTS_VERSION_00 0
#define VKI_CAP_RIGHTS_VERSION VKI_CAP_RIGHTS_VERSION_00
struct vki_cap_rights {
vki_uint64_t cki_cr_rights[VKI_CAP_RIGHTS_VERSION + 2];
};
typedef struct vki_cap_rights vki_cap_rights_t;
//----------------------------------------------------------------------
// From sys/user.h
//----------------------------------------------------------------------
@ -2146,23 +2181,119 @@ struct vki_kinfo_vmentry {
char kve_path[VKI_PATH_MAX];
};
#define VKI_KINFO_FILE_SIZE 1392
struct vki_kinfo_file {
int kf_structsize; /* Variable size of record. */
int kf_type; /* Descriptor type. */
int kf_fd; /* Array index. */
int kf_ref_count; /* Reference count. */
int kf_flags; /* Flags. */
int _kf_pad0; /* Round to 64 bit alignment */
Off64T kf_offset; /* Seek location. */
int kf_vnode_type; /* Vnode type. */
int kf_sock_domain; /* Socket domain. */
int kf_sock_type; /* Socket type. */
int kf_sock_protocol; /* Socket protocol. */
char kf_sa_local[128]; /* Socket address. */
char kf_sa_peer[128]; /* Peer address. */
int _kf_ispare[16]; /* Space for more stuff. */
int vki_kf_structsize; /* Variable size of record. */
int vki_kf_type; /* Descriptor type. */
int vki_kf_fd; /* Array index. */
int vki_kf_ref_count; /* Reference count. */
int vki_kf_flags; /* Flags. */
int vki_kf_pad0; /* Round to 64 bit alignment. */
Off64T vki_kf_offset; /* Seek location. */
union {
struct {
/* API compatiblity with FreeBSD < 12. */
int vki_kf_vnode_type;
int vki_kf_sock_domain;
int vki_kf_sock_type;
int kf_sock_protocol;
struct vki_sockaddr_storage vki_kf_sa_local;
struct vki_sockaddr_storage vki_kf_sa_peer;
};
union {
struct {
/* Sendq size */
vki_uint32_t vki_kf_sock_sendq;
/* Socket domain. */
int vki_kf_sock_domain0;
/* Socket type. */
int vki_kf_sock_type0;
/* Socket protocol. */
int vki_kf_sock_protocol0;
/* Socket address. */
struct vki_sockaddr_storage vki_kf_sa_local;
/* Peer address. */
struct vki_sockaddr_storage vki_kf_sa_peer;
/* Address of so_pcb. */
vki_uint64_t vki_kf_sock_pcb;
/* Address of inp_ppcb. */
vki_uint64_t vki_kf_sock_inpcb;
/* Address of unp_conn. */
vki_uint64_t vki_kf_sock_unpconn;
/* Send buffer state. */
vki_uint16_t vki_kf_sock_snd_sb_state;
/* Receive buffer state. */
vki_uint16_t vki_kf_sock_rcv_sb_state;
/* Recvq size. */
vki_uint32_t vki_kf_sock_recvq;
} vki_kf_sock;
struct {
/* Vnode type. */
int vki_kf_file_type;
/* Space for future use */
int vki_kf_spareint[3];
vki_uint64_t vki_kf_spareint64[30];
/* Vnode filesystem id. */
vki_uint64_t vki_kf_file_fsid;
/* File device. */
vki_uint64_t vki_kf_file_rdev;
/* Global file id. */
vki_uint64_t vki_kf_file_fileid;
/* File size. */
vki_uint64_t vki_kf_file_size;
/* Vnode filesystem id, FreeBSD 11 compat. */
vki_uint32_t vki_kf_file_fsid_freebsd11;
/* File device, FreeBSD 11 compat. */
vki_uint32_t kf_file_rdev_freebsd11;
/* File mode. */
vki_uint16_t vki_kf_file_mode;
/* Round to 64 bit alignment. */
vki_uint16_t vki_kf_file_pad0;
vki_uint32_t kf_file_pad1;
} kf_file;
struct {
vki_uint32_t vki_kf_spareint[4];
vki_uint64_t vki_kf_spareint64[32];
vki_uint32_t vki_kf_sem_value;
vki_uint16_t vki_kf_sem_mode;
} kf_sem;
struct {
vki_uint32_t vki_kf_spareint[4];
vki_uint64_t vki_kf_spareint64[32];
vki_uint64_t vki_kf_pipe_addr;
vki_uint64_t vki_kf_pipe_peer;
vki_uint32_t vki_kf_pipe_buffer_cnt;
/* Round to 64 bit alignment. */
vki_uint32_t vki_kf_pipe_pad0[3];
} kf_pipe;
struct {
vki_uint32_t vki_kf_spareint[4];
vki_uint64_t vki_kf_spareint64[32];
vki_uint32_t vki_kf_pts_dev_freebsd11;
vki_uint32_t vki_kf_pts_pad0;
vki_uint64_t vki_kf_pts_dev;
/* Round to 64 bit alignment. */
vki_uint32_t vki_kf_pts_pad1[4];
} kf_pts;
struct {
vki_uint32_t vki_kf_spareint[4];
vki_uint64_t vki_kf_spareint64[32];
vki_pid_t vki_kf_pid;
} vki_kf_proc;
struct {
vki_uint64_t vki_kf_eventfd_value;
vki_uint32_t vki_kf_eventfd_flags;
} vki_kf_eventfd;
} vki_kf_un;
};
vki_uint16_t vki_kf_status; /* Status flags. */
vki_uint16_t vki_kf_pad1; /* Round to 32 bit alignment. */
int vki__kf_ispare0; /* Space for more stuff. */
vki_cap_rights_t vki_kf_cap_rights; /* Capability rights. */
vki_uint64_t vki__kf_cap_spare; /* Space for future cap_rights_t. */
/* Truncated before copyout in sysctl */
char kf_path[VKI_PATH_MAX]; /* Path to file, if any. */
char vki_kf_path[VKI_PATH_MAX]; /* Path to file, if any. */
};
//----------------------------------------------------------------------
@ -2240,19 +2371,6 @@ struct vki_arch_elf_state {
#endif
//----------------------------------------------------------------------
// From sys/caprights.h
//----------------------------------------------------------------------
#define VKI_CAP_RIGHTS_VERSION_00 0
#define VKI_CAP_RIGHTS_VERSION VKI_CAP_RIGHTS_VERSION_00
struct vki_cap_rights {
vki_uint64_t cr_rights[VKI_CAP_RIGHTS_VERSION + 2];
};
typedef struct vki_cap_rights vki_cap_rights_t;
//----------------------------------------------------------------------
// From ufs/ufs/quota.h
//----------------------------------------------------------------------

View File

@ -458,7 +458,7 @@
#define __NR_getcontext 421
#define __NR_setcontext 422
#define __NR_swapcontext 423
#if (FREEBSD_VERS >= FREEBSD_14)
#if (FREEBSD_VERS >= FREEBSD_13_1)
#define __NR_freebsd13_swapoff 424
#else
#define __NR_swapoff 424
@ -653,7 +653,7 @@
#endif
#if (FREEBSD_VERS >= FREEBSD_14)
#if (FREEBSD_VERS >= FREEBSD_13_1)
#define __NR_fspacectl 580
#define __NR_sched_getcpu 581

View File

@ -1396,7 +1396,7 @@ int main(void)
GO(SYS_swapcontext, "2s 2m");
SY(SYS_swapcontext, x0+1, x0+2); FAIL;
#if (FREEBSD_VERS >= FREEBSD_14)
#if (FREEBSD_VERS >= FREEBSD_13_1)
/* SYS_freebsd13_swapoff 424 */
GO(SYS_freebsd13_swapoff, "1s 1m");
SY(SYS_freebsd13_swapoff, x0+1); FAIL;