]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
FreeBSD ioctl: enable SIOCGIFMEDIA PCIOCGETCONF CAMIOCOMMAND ioctls and add SIOCGIFSTATUS
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 28 Apr 2024 16:22:43 +0000 (18:22 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 28 Apr 2024 16:22:43 +0000 (18:22 +0200)
coregrind/m_syswrap/syswrap-freebsd.c
include/vki/vki-freebsd.h

index 0a937d37fdd98feafcdd5bdaf312c331e9336c6a..8d99e6aaa21e6eb61e01660e7e0de4383b6315fb 100644 (file)
@@ -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
index 77f75457d8f640cf6d0bfd825b47f29bf78b4e5b..858865a85a362473d23a34f82e0c5639835200b9 100644 (file)
@@ -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                                                          ---*/
 /*--------------------------------------------------------------------*/