From 4d810715652385668c3746e9d7656d8eec6bd3ee Mon Sep 17 00:00:00 2001 From: Paul Floyd Date: Sun, 28 Apr 2024 18:22:43 +0200 Subject: [PATCH] FreeBSD ioctl: enable SIOCGIFMEDIA PCIOCGETCONF CAMIOCOMMAND ioctls and add SIOCGIFSTATUS --- coregrind/m_syswrap/syswrap-freebsd.c | 90 +++++++++++++++------------ include/vki/vki-freebsd.h | 13 ++-- 2 files changed, 59 insertions(+), 44 deletions(-) diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index 0a937d37f..8d99e6aaa 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -990,31 +990,25 @@ PRE(sys_ioctl) PRE_REG_READ3(int, "ioctl", int, fd, unsigned long, request, unsigned long, arg); - switch (ARG2) { - case VKI_FIODGNAME: { - struct vki_fiodgname_arg* data = (struct vki_fiodgname_arg*)(Addr)ARG3; - PRE_FIELD_READ("ioctl(FIODGNAME).len", data->len); - PRE_FIELD_READ("ioctl(FIODGNAME).buf", data->buf); - PRE_MEM_WRITE("ioctl(FIODGNAME).buf", (Addr)data->buf, data->len); - break; - } - default: - ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3); + switch (ARG2 /* request */) { + /* Handle specific ioctls which pass structures which may have pointers to other + buffers */ + case VKI_FIODGNAME: + // #define FIODGNAME _IOW('f', 120, struct fiodgname_arg) /* get dev. name */ + // has a regression test + if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(struct vki_fiodgname_arg))) { + struct vki_fiodgname_arg* data = (struct vki_fiodgname_arg*)(Addr)ARG3; + PRE_FIELD_READ("ioctl(FIODGNAME).len", data->len); + PRE_FIELD_READ("ioctl(FIODGNAME).buf", data->buf); + PRE_MEM_WRITE("ioctl(FIODGNAME).buf", (Addr)data->buf, data->len); + } break; - } - // The block below is from Ryan Stone // https://bitbucket.org/rysto32/valgrind-freebsd/commits/5323c22be9f6c71a00e842c3ddfa1fa8a7feb279 - // however it drags in hundreds of lines of headers into vki-freebsd.h. - // How stable are these structures? -> maintainability is a concern - // Also there are no testcases for this. - // Hence #if 0 -#if 0 - /* Handle specific ioctls which pass structures which may have pointers to other - buffers */ - switch (ARG2 /* request */) { case VKI_SIOCGIFMEDIA: - if (ARG3) { + // #define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */ + // test with "ifconfig -m" + if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(struct vki_ifmediareq))) { struct vki_ifmediareq* imr = (struct vki_ifmediareq*)ARG3; if (imr->ifm_ulist) { PRE_MEM_WRITE("ioctl(SIOCGIFMEDIA).ifm_ulist", @@ -1024,7 +1018,9 @@ PRE(sys_ioctl) break; case VKI_PCIOCGETCONF: - if (ARG3) { + // #define PCIOCGETCONF _IOWR('p', 5, struct pci_conf_io) + // test with "pciconf -l" + if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(struct vki_pci_conf_io))) { struct vki_pci_conf_io* pci = (struct vki_pci_conf_io*)ARG3; PRE_MEM_READ("ioctl(PCIOCGETCONF).patterns", (Addr)(pci->patterns), pci->pat_buf_len); @@ -1032,11 +1028,15 @@ PRE(sys_ioctl) (Addr)(pci->matches), pci->match_buf_len); } break; - case VKI_CAMIOCOMMAND: - if (ARG3) { + // #define CAMIOCOMMAND _IOWR(CAM_VERSION, 2, union ccb) + if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(union vki_ccb))) { + // test with "camcontrol devlist" (as root) + // (many errors at present) union vki_ccb* ccb = (union vki_ccb*)ARG3; if (ccb->ccb_h.func_code == VKI_XPT_DEV_MATCH) { + PRE_FIELD_READ("ioctl(CAMIOCOMMAND).cdm.match_buf_len", ccb->cdm.match_buf_len); + PRE_FIELD_READ("ioctl(CAMIOCOMMAND).cdm.matches", ccb->cdm.matches); PRE_MEM_WRITE("ioctl(CAMIOCOMMAND:XPT_DEV_MATCH).matches", (Addr)(ccb->cdm.matches), ccb->cdm.match_buf_len); } else if (ccb->ccb_h.func_code == VKI_XPT_SCSI_IO) { @@ -1056,32 +1056,43 @@ PRE(sys_ioctl) // do nothing } else { VG_(message)(Vg_UserMsg, - "Warning: unhandled ioctl CAMIOCOMMAND function 0x%lx\n", + "Warning: unhandled ioctl CAMIOCOMMAND function 0x%x\n", ccb->ccb_h.func_code); } } break; + case VKI_SIOCGIFSTATUS: + // #define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) /* get IF status */ + // test with "ifconfig -a" + if (ARG3 && ML_(safe_to_deref)((const void*)ARG3, sizeof(struct vki_ifstat))) { + struct vki_ifstat* data = (struct vki_ifstat*)(Addr)ARG3; + PRE_MEM_RASCIIZ("ioctl(SIOCGIFSTATUS).ifs_name", (Addr)data->ifs_name); + PRE_MEM_WRITE("ioctl(SIOCGIFSTATUS).ascii", (Addr)data->ascii, sizeof(data->ascii)); + } + break; + default: + ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3); + break; } -#endif } POST(sys_ioctl) { - switch (ARG2) { - case VKI_FIODGNAME: { + switch (ARG2/* request */) { + /* Handle specific ioctls which pass structures which may have pointers to other + buffers */ + case VKI_FIODGNAME: + if (ARG3) { struct vki_fiodgname_arg* data = (struct vki_fiodgname_arg*)(Addr)ARG3; - POST_MEM_WRITE((Addr)data->buf, data->len); + POST_MEM_WRITE((Addr)data->buf, data->len); + } break; - } - default: - ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3); + case VKI_SIOCGIFSTATUS: { + // #define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) /* get IF status */ + struct vki_ifstat* data = (struct vki_ifstat*)(Addr)ARG3; + POST_MEM_WRITE((Addr)data->ascii, sizeof(data->ascii)); break; } - -#if 0 - /* Handle specific ioctls which pass structures which may have pointers to other - buffers */ - switch (ARG2 /* request */) { case VKI_SIOCGIFMEDIA: if (ARG3) { struct vki_ifmediareq* imr = (struct vki_ifmediareq*)ARG3; @@ -1090,7 +1101,6 @@ POST(sys_ioctl) } } break; - case VKI_PCIOCGETCONF: if (ARG3) { struct vki_pci_conf_io* pci = (struct vki_pci_conf_io*)ARG3; @@ -1113,8 +1123,10 @@ POST(sys_ioctl) } } break; + default: + ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3); + break; } -#endif } // SYS_reboot 55 diff --git a/include/vki/vki-freebsd.h b/include/vki/vki-freebsd.h index 77f75457d..858865a85 100644 --- a/include/vki/vki-freebsd.h +++ b/include/vki/vki-freebsd.h @@ -972,7 +972,7 @@ struct vki_termios { #define _VKI_IOC_SIZEMASK ((1ul << _VKI_IOC_SIZEBITS)-1) #define _VKI_IOC_DIRMASK ((1ul << _VKI_IOC_DIRBITS)-1) -#define _VKI_IOC_BASESHIFT 0U +#define _VKI_IOC_BASESHIFT 0U #define _VKI_IOC_NRSHIFT 0U #define _VKI_IOC_TYPESHIFT (_VKI_IOC_NRSHIFT+_VKI_IOC_NRBITS) #define _VKI_IOC_SIZESHIFT (_VKI_IOC_TYPESHIFT+_VKI_IOC_TYPEBITS) @@ -1097,7 +1097,6 @@ struct vki_fiodgname_arg { #define VKI_FIODGNAME _VKI_IOW('f', 120, struct vki_fiodgname_arg) /* get dev. name */ // See syswrap-freebsd.c PRE/POST(sys_ioctl) -#if 0 //---------------------------------------------------------------------- // From net/if.h //---------------------------------------------------------------------- @@ -1113,12 +1112,17 @@ struct vki_ifmediareq { int *ifm_ulist; }; +#define VKI_IFSTATMAX 800 /* 10 lines of text */ +struct vki_ifstat { + char ifs_name[VKI_IFNAMSIZ]; /* if name, e.g. "en0" */ + char ascii[VKI_IFSTATMAX + 1]; +}; +#define VKI_SIOCGIFSTATUS _VKI_IOWR('i', 59, struct vki_ifstat) //---------------------------------------------------------------------- // From sys/sockio.h //---------------------------------------------------------------------- #define VKI_SIOCGIFMEDIA _VKI_IOWR('i', 56, struct vki_ifmediareq) -#endif //---------------------------------------------------------------------- // From sys/poll.h @@ -2614,7 +2618,6 @@ struct vki_ps_strings { #endif // See syswrap-freebsd.c PRE/POST(sys_ioctl) -#if 0 //---------------------------------------------------------------------- // From sys/pciio.h @@ -3347,7 +3350,7 @@ union vki_ccb { #define VKI_CAMIOCOMMAND _VKI_IOWR(VKI_CAM_VERSION, 2, union vki_ccb) -#endif + /*--------------------------------------------------------------------*/ /*--- end ---*/ /*--------------------------------------------------------------------*/ -- 2.39.2