diff --git a/drsyscall/drsyscall_linux.c b/drsyscall/drsyscall_linux.c index dbb75886..b9dfa1f0 100644 --- a/drsyscall/drsyscall_linux.c +++ b/drsyscall/drsyscall_linux.c @@ -978,8 +978,12 @@ handle_semctl(void *drcontext, cls_syscall_t *pt, sysarg_iter_info_t *ii, ASSERT(argnum_semid + 3 < SYSCALL_NUM_ARG_STORE, "index too high"); cmd = (uint) pt->sysarg[argnum_semid + 2]; arg_val = (ptr_int_t) pt->sysarg[argnum_semid + 3]; - /* XXX i#2547: Use safe_read to de-reference below. */ - arg_ptr = (union semun *)arg_val; + union semun temp_arg; + if (!d_r_safe_read((void *)arg_val, sizeof(temp_arg), &temp_arg)) { + ELOGF(0, f_global, "ERROR: Failed to safe_read arg_val at %p\n", (void *)arg_val); + return; + } + arg_ptr = &temp_arg; semid = (int) pt->sysarg[argnum_semid]; if (!ii->arg->pre && (ptr_int_t)dr_syscall_get_result(drcontext) < 0) return;