[LTP] [PATCH v2 3/3] safe_semctl: Fix undefined behaviour in vararg handling

Tudor Cretu tudor.cretu@arm.com
Tue Nov 29 14:03:50 CET 2022


Accessing elements in an empty va_list is undefined behaviour.
Therefore, remove the variadicness from safe_semctl as it always calls
semctl with the union semun argument included.

Adapt the SAFE_SEMCTL macro to handle the change by passing a
zero-initialised union semun if it's omitted.

Signed-off-by: Tudor Cretu <tudor.cretu@arm.com>
---
 include/tst_safe_sysv_ipc.h | 14 +++++++++-----
 lib/tst_safe_sysv_ipc.c     | 10 +---------
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/include/tst_safe_sysv_ipc.h b/include/tst_safe_sysv_ipc.h
index 7804ce192..976a30409 100644
--- a/include/tst_safe_sysv_ipc.h
+++ b/include/tst_safe_sysv_ipc.h
@@ -10,6 +10,7 @@
 #include <sys/msg.h>
 #include <sys/shm.h>
 #include <sys/sem.h>
+#include "lapi/sem.h"
 
 int safe_msgget(const char *file, const int lineno, key_t key, int msgflg);
 #define SAFE_MSGGET(key, msgflg) \
@@ -58,11 +59,14 @@ int safe_semget(const char *file, const int lineno, key_t key, int nsems,
 	safe_semget(__FILE__, __LINE__, (key), (nsems), (semflg))
 
 int safe_semctl(const char *file, const int lineno, int semid, int semnum,
-		int cmd, ...);
-#define SAFE_SEMCTL(semid, semnum, cmd, ...) ({ \
-	int tst_ret_ = safe_semctl(__FILE__, __LINE__, (semid), (semnum), \
-				(cmd), ##__VA_ARGS__); \
-	(semid) = ((cmd) == IPC_RMID ? -1 : (semid)); \
+		int cmd, union semun un);
+#define __SAFE_SEMCTL(semid, semnum, cmd, un, ...) \
+	safe_semctl(__FILE__, __LINE__, (semid), (semnum), (cmd), (un))
+
+#define SAFE_SEMCTL(semid, semnum, cmd, ...) ({					\
+	int tst_ret_ = __SAFE_SEMCTL((semid), (semnum), (cmd), ##__VA_ARGS__,	\
+				     (union semun){0});				\
+	(semid) = ((cmd) == IPC_RMID ? -1 : (semid));				\
 	tst_ret_; })
 
 int safe_semop(const char *file, const int lineno, int semid, struct sembuf *sops,
diff --git a/lib/tst_safe_sysv_ipc.c b/lib/tst_safe_sysv_ipc.c
index 5eaa82539..f99f6db5e 100644
--- a/lib/tst_safe_sysv_ipc.c
+++ b/lib/tst_safe_sysv_ipc.c
@@ -228,17 +228,9 @@ int safe_semget(const char *file, const int lineno, key_t key, int nsems,
 }
 
 int safe_semctl(const char *file, const int lineno, int semid, int semnum,
-		int cmd, ...)
+		int cmd, union semun un)
 {
 	int rval;
-	va_list va;
-	union semun un;
-
-	va_start(va, cmd);
-
-	un = va_arg(va, union semun);
-
-	va_end(va);
 
 	rval = semctl(semid, semnum, cmd, un);
 
-- 
2.25.1



More information about the ltp mailing list