From: Philippe Waroquiers Date: Fri, 17 Mar 2017 18:38:42 +0000 (+0000) Subject: Follow up to fix 376956 syswrap of SNDDRV and DRM_IOCTL_VERSION causing some X-Git-Tag: svn/VALGRIND_3_13_0~150 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eb0d79c25a421e3771494f9a437dceca7d137b5c;p=thirdparty%2Fvalgrind.git Follow up to fix 376956 syswrap of SNDDRV and DRM_IOCTL_VERSION causing some addresses to be wrongly marked as addressable As noted by Ivo, if the syscall fails, then we have a leak. So, enable the flag SfPostOnFail if we allocate memory. In the POST ioctl, check that FAILURE only happens for this drm ioctl, and free the memory for both SUCCESS and FAILURE. Do the POST_MEM_WRITE only if SUCCESS git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16277 --- diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index a739a5d9dd..8d2f7d880b 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -7706,6 +7706,8 @@ PRE(sys_ioctl) PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc)); PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len); info = VG_(malloc)("syswrap.ioctl.1", sizeof(*info)); + // To ensure we VG_(free) info even when syscall fails: + *flags |= SfPostOnFail; info->data = *data; info->orig = data; ARG3 = (Addr)&info->data; @@ -9011,7 +9013,7 @@ PRE(sys_ioctl) POST(sys_ioctl) { - vg_assert(SUCCESS); + vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2)); ARG2 = (UInt)ARG2; @@ -10193,15 +10195,17 @@ POST(sys_ioctl) ARG3 = (Addr)info->orig; data = info->orig; VG_(free)(info); - POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major)); - POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor)); - POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel)); - POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len)); - POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len)); - POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len)); - POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len)); - POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len)); - POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len)); + if (SUCCESS) { + POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major)); + POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor)); + POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel)); + POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len)); + POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len)); + POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len)); + POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len)); + POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len)); + POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len)); + } } break; case VKI_DRM_IOCTL_GET_UNIQUE: