|
From: <sv...@va...> - 2017-03-17 18:38:50
|
Author: philippe
Date: Fri Mar 17 18:38:42 2017
New Revision: 16277
Log:
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
Modified:
trunk/coregrind/m_syswrap/syswrap-linux.c
Modified: trunk/coregrind/m_syswrap/syswrap-linux.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-linux.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-linux.c Fri Mar 17 18:38:42 2017
@@ -7706,6 +7706,8 @@
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 @@
POST(sys_ioctl)
{
- vg_assert(SUCCESS);
+ vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2));
ARG2 = (UInt)ARG2;
@@ -10193,15 +10195,17 @@
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:
|