]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
FreeBSD syscall: fixes for semctl
authorPaul Floyd <pjfloyd@wanadoo.fr>
Wed, 6 Mar 2024 20:19:23 +0000 (21:19 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Wed, 6 Mar 2024 20:19:23 +0000 (21:19 +0100)
On FreeBSD, the libc semctl function takes a union semun argument
for commands that take 4 arguments. It then gets that argument
via va_args and takes a pointer to it. That's what gets passed
to the sysctl - a pointer to union semun.

Previously we were handling the 4th argument as if it were
directly a union semun. This seems to have worked OK for years,
possibly due to luck concerning the way that va_args works
and/or the fact that the union is basically a union of
pointers. Recently I've been working on arm64 and there it
most definitely does not work.

coregrind/m_syswrap/syswrap-freebsd.c
coregrind/m_syswrap/syswrap-generic.c
include/vki/vki-freebsd.h
memcheck/tests/freebsd/scalar.c
memcheck/tests/freebsd/scalar.stderr.exp
memcheck/tests/freebsd/scalar.stderr.exp-x86

index d2116843321931230155d4eaf996c5172c0549ff..5f12ef06222a9e960eae937c4bff7c831907680f 100644 (file)
@@ -2186,38 +2186,38 @@ PRE(sys_futimes)
 // int semctl(int semid, int semnum, int cmd, ...);
 PRE(sys_freebsd7___semctl)
 {
+   union vki_semun* semun;
    switch (ARG3) {
-   case VKI_IPC_INFO:
-   case VKI_SEM_INFO:
-      PRINT("sys_semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4);
-      PRE_REG_READ4(int, "semctl",
-                    int, semid, int, semnum, int, cmd, struct seminfo *, arg);
-      break;
    case VKI_IPC_STAT:
    case VKI_SEM_STAT:
    case VKI_IPC_SET:
-      PRINT("sys_semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4);
-      PRE_REG_READ4(int, "semctl",
-                    int, semid, int, semnum, int, cmd, struct vki_semid_ds_old *, arg);
-      break;
    case VKI_GETALL:
    case VKI_SETALL:
-      PRINT("sys_semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4);
+      PRINT("sys_freebsd7___semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4);
       PRE_REG_READ4(int, "semctl",
-                    int, semid, int, semnum, int, cmd, unsigned short *, arg);
+                    int, semid, int, semnum, int, cmd, union vki_semun *, arg);
+      PRE_MEM_READ("sys_freebsd7___semctl(arg)", ARG4, sizeof(union vki_semun));
+      semun = (union vki_semun*)ARG4;
+      if (ML_(safe_to_deref)(semun, sizeof(*semun))) {
+         ARG4 = (RegWord)semun;
+         ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
+      }
       break;
    default:
-      PRINT("sys_semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3);
+      PRINT("sys_freebsd7___semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3);
       PRE_REG_READ3(long, "semctl",
                     int, semid, int, semnum, int, cmd);
       break;
    }
-   ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
 }
 
 POST(sys_freebsd7___semctl)
 {
-   ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
+   union vki_semun* semun = (union vki_semun*)ARG4;
+   if (ML_(safe_to_deref)(semun, sizeof(*semun))) {
+      ARG4 = (RegWord)semun;
+      ML_(generic_POST_sys_semctl)(tid, RES, ARG1,ARG2,ARG3,ARG4);
+   }
 }
 
 // SYS_semget  221
@@ -5647,25 +5647,23 @@ PRE(sys_closefrom)
 // int __semctl(int semid, int semnum, int cmd, _Inout_ union semun *arg);
 PRE(sys___semctl)
 {
+   union vki_semun* semun;
+
    switch (ARG3) {
-   case VKI_IPC_INFO:
-   case VKI_SEM_INFO:
-      PRINT("sys_semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4);
-      PRE_REG_READ4(int, "semctl",
-                    int, semid, int, semnum, int, cmd, struct seminfo *, arg);
-      break;
    case VKI_IPC_STAT:
    case VKI_SEM_STAT:
    case VKI_IPC_SET:
-      PRINT("sys_semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4);
-      PRE_REG_READ4(long, "semctl",
-                    int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
-      break;
    case VKI_GETALL:
    case VKI_SETALL:
-      PRINT("sys_semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4);
+      PRINT("sys___semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4);
       PRE_REG_READ4(long, "semctl",
-                    int, semid, int, semnum, int, cmd, unsigned short *, arg);
+                    int, semid, int, semnum, int, cmd, union  vki_semun *, arg);
+      PRE_MEM_READ("sys___sysctl(arg)", ARG4, sizeof(union vki_semun));
+      semun = (union vki_semun*)ARG4;
+      if (ML_(safe_to_deref)(semun, sizeof(*semun))) {
+         ARG4 = (RegWord)semun;
+         ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
+      }
       break;
    default:
       PRINT("sys_semctl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3);
@@ -5673,12 +5671,15 @@ PRE(sys___semctl)
                     int, semid, int, semnum, int, cmd);
       break;
    }
-   ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
 }
 
 POST(sys___semctl)
 {
-   ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
+   union vki_semun* semun = (union vki_semun*)ARG4;
+   if (ML_(safe_to_deref)(semun, sizeof(*semun))) {
+      ARG4 = (RegWord)semun;
+      ML_(generic_POST_sys_semctl)(tid, RES, ARG1,ARG2,ARG3,ARG4);
+   }
 }
 
 // SYS_msgctl  511
index d5159e7900d50977fe99a87d8744c0832744abf1..8f94b172fa164d9d22d4dd6d5abe10377a4f2cc5 100644 (file)
@@ -1825,7 +1825,7 @@ UInt get_sem_count( Int semid )
 #  elif defined(__NR___semctl) /* FreeBSD */
    struct vki_semid_ds buf;
    arg.buf = &buf;
-   res = VG_(do_syscall4)(__NR___semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg);
+   res = VG_(do_syscall4)(__NR___semctl, semid, 0, VKI_IPC_STAT, (RegWord)&arg);
 
    if (sr_isError(res))
       return 0;
index 1267eb3b3c15b8c7bb284b5ff1a8c5ab63fd15c7..0cf17cc7b5639858a3e49c6aece0ec4104ba842c 100644 (file)
@@ -1270,7 +1270,7 @@ struct vki_utsname {
 #define VKI_IPC_RMID 0     /* remove resource */
 #define VKI_IPC_SET  1     /* set ipc_perm options */
 #define VKI_IPC_STAT 2     /* get ipc_perm options */
-#define VKI_IPC_INFO 3     /* see ipcs */
+#define VKI_IPC_INFO 3     /* only used by Linux compatibilty shm_ctl */
 
 //----------------------------------------------------------------------
 // From sys/ipc.h
index 3518f361afefd1dbbb1bdcbe0c6bfecb4e1f9839..40479dcbb916e851823b7c6b2e436c0f7db3ce73 100644 (file)
@@ -793,8 +793,8 @@ int main(void)
    }
 
    /* SYS_freebsd7___semctl       220 */
-   GO(SYS_freebsd7___semctl, "(IPC_INFO) 4s 1m");
-   SY(SYS_freebsd7___semctl, x0, x0, x0+IPC_INFO, x0+1); FAIL;
+   GO(SYS_freebsd7___semctl, "(IPC_STAT) 4s 1m");
+   SY(SYS_freebsd7___semctl, x0, x0, x0+IPC_STAT, x0+1); FAIL;
 
    GO(SYS_freebsd7___semctl, "(bogus cmd) 3s 0m");
    SY(SYS_freebsd7___semctl, x0, x0, x0-1, x0+1); FAIL;
@@ -1787,8 +1787,8 @@ int main(void)
 #endif
 
    /* SYS___semctl                510 */
-   GO(SYS___semctl, "(IPC_INFO) 4s 1m");
-   SY(SYS___semctl, x0, x0, x0+IPC_INFO, x0+1); FAIL;
+   GO(SYS___semctl, "(IPC_STAT) 4s 1m");
+   SY(SYS___semctl, x0, x0, x0+IPC_STAT, x0+1); FAIL;
 
    GO(SYS___semctl, "(other) 3s 0m");
    SY(SYS___semctl, x0, x0, x0+3000, x0+1); FAIL;
index 38d2380f7861efe41f3ada81e6709c6a89ab0411..5ea7543b61b980329318222edac824e16570347d 100644 (file)
@@ -1560,7 +1560,7 @@ Syscall param poll(ufds.events) points to uninitialised byte(s)
  Address 0x........ is on thread 1's stack
 
 ---------------------------------------------------------
-220:   SYS_freebsd7___semctl (IPC_INFO) 4s 1m
+220:   SYS_freebsd7___semctl (IPC_STAT) 4s 1m
 ---------------------------------------------------------
 Syscall param semctl(semid) contains uninitialised byte(s)
    ...
@@ -1574,7 +1574,7 @@ Syscall param semctl(cmd) contains uninitialised byte(s)
 Syscall param semctl(arg) contains uninitialised byte(s)
    ...
 
-Syscall param semctl(IPC_INFO, arg.buf) points to unaddressable byte(s)
+Syscall param sys_freebsd7___semctl(arg) points to unaddressable byte(s)
    ...
  Address 0x........ is not stack'd, malloc'd or (recently) free'd
 
@@ -4399,7 +4399,7 @@ Syscall param closefrom(lowfd) contains uninitialised byte(s)
    ...
 
 ---------------------------------------------------------
-510:            SYS___semctl (IPC_INFO) 4s 1m
+510:            SYS___semctl (IPC_STAT) 4s 1m
 ---------------------------------------------------------
 Syscall param semctl(semid) contains uninitialised byte(s)
    ...
@@ -4413,7 +4413,7 @@ Syscall param semctl(cmd) contains uninitialised byte(s)
 Syscall param semctl(arg) contains uninitialised byte(s)
    ...
 
-Syscall param semctl(IPC_INFO, arg.buf) points to unaddressable byte(s)
+Syscall param sys___sysctl(arg) points to unaddressable byte(s)
    ...
  Address 0x........ is not stack'd, malloc'd or (recently) free'd
 
index cdb0825ca76d56ee7eb64952bfd04a290b48b125..106381e11218ca25c1f72d92b8e276aec512866d 100644 (file)
@@ -1560,7 +1560,7 @@ Syscall param poll(ufds.events) points to uninitialised byte(s)
  Address 0x........ is on thread 1's stack
 
 ---------------------------------------------------------
-220:   SYS_freebsd7___semctl (IPC_INFO) 4s 1m
+220:   SYS_freebsd7___semctl (IPC_STAT) 4s 1m
 ---------------------------------------------------------
 Syscall param semctl(semid) contains uninitialised byte(s)
    ...
@@ -1574,7 +1574,7 @@ Syscall param semctl(cmd) contains uninitialised byte(s)
 Syscall param semctl(arg) contains uninitialised byte(s)
    ...
 
-Syscall param semctl(IPC_INFO, arg.buf) points to unaddressable byte(s)
+Syscall param sys_freebsd7___semctl(arg) points to unaddressable byte(s)
    ...
  Address 0x........ is not stack'd, malloc'd or (recently) free'd
 
@@ -4430,7 +4430,7 @@ Syscall param closefrom(lowfd) contains uninitialised byte(s)
    ...
 
 ---------------------------------------------------------
-510:            SYS___semctl (IPC_INFO) 4s 1m
+510:            SYS___semctl (IPC_STAT) 4s 1m
 ---------------------------------------------------------
 Syscall param semctl(semid) contains uninitialised byte(s)
    ...
@@ -4444,7 +4444,7 @@ Syscall param semctl(cmd) contains uninitialised byte(s)
 Syscall param semctl(arg) contains uninitialised byte(s)
    ...
 
-Syscall param semctl(IPC_INFO, arg.buf) points to unaddressable byte(s)
+Syscall param sys___sysctl(arg) points to unaddressable byte(s)
    ...
  Address 0x........ is not stack'd, malloc'd or (recently) free'd