From: Philippe Waroquiers Date: Wed, 15 Mar 2017 19:35:29 +0000 (+0000) Subject: Fix 376956 syswrap of SNDDRV and DRM_IOCTL_VERSION causing some addresses X-Git-Tag: svn/VALGRIND_3_13_0~153 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a6a72c71be75034523671076e26b379c16b5f924;p=thirdparty%2Fvalgrind.git Fix 376956 syswrap of SNDDRV and DRM_IOCTL_VERSION causing some addresses to be wrongly marked as addressable Patch from Daniel Glöckner, slightly modified. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16274 --- diff --git a/NEWS b/NEWS index 8f97b9e7b4..f063378c8a 100644 --- a/NEWS +++ b/NEWS @@ -142,6 +142,8 @@ where XXXXXX is the bug number as listed below. 376611 ppc64 and arm64 don't know about prlimit64 syscall 376729 PPC64, remove R2 from the clobber list == 371668 +376956 syswrap of SNDDRV and DRM_IOCTL_VERSION causing some addresses + to be wrongly marked as addressable 377427 PPC64, lxv instruction failing on odd destination register 377478 PPC64: ISA 3.0 setup fixes diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 5a79930aa3..a739a5d9dd 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -6069,6 +6069,11 @@ POST(sys_fcntl64) ioctl wrappers ------------------------------------------------------------------ */ +struct vg_drm_version_info { + struct vki_drm_version data; + struct vki_drm_version *orig; // Original ARG3 pointer value at syscall entry. +}; + PRE(sys_ioctl) { *flags |= SfMayBlock; @@ -7686,7 +7691,8 @@ PRE(sys_ioctl) case VKI_DRM_IOCTL_VERSION: if (ARG3) { - struct vki_drm_version *data = (struct vki_drm_version *)ARG3; + struct vki_drm_version* data = (struct vki_drm_version *)ARG3; + struct vg_drm_version_info* info; PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major)); PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor)); PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel)); @@ -7699,6 +7705,10 @@ PRE(sys_ioctl) PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len)); 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)); + info->data = *data; + info->orig = data; + ARG3 = (Addr)&info->data; } break; case VKI_DRM_IOCTL_GET_UNIQUE: @@ -10174,16 +10184,24 @@ POST(sys_ioctl) case VKI_DRM_IOCTL_VERSION: if (ARG3) { - struct vki_drm_version *data = (struct vki_drm_version *)ARG3; + struct vki_drm_version* data = (struct vki_drm_version *)ARG3; + struct vg_drm_version_info* info = container_of(data, struct vg_drm_version_info, data); + const vki_size_t orig_name_len = info->orig->name_len; + const vki_size_t orig_date_len = info->orig->date_len; + const vki_size_t orig_desc_len = info->orig->desc_len; + *info->orig = info->data; + 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, 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, 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, data->desc_len); + POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len)); } break; case VKI_DRM_IOCTL_GET_UNIQUE: diff --git a/include/pub_tool_basics.h b/include/pub_tool_basics.h index 4712c117cf..ebed99123a 100644 --- a/include/pub_tool_basics.h +++ b/include/pub_tool_basics.h @@ -396,6 +396,10 @@ static inline Bool sr_EQ ( UInt sysno, SysRes sr1, SysRes sr2 ) { # define offsetof(type,memb) ((SizeT)(HWord)&((type*)0)->memb) #endif +#if !defined(container_of) +# define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member))) +#endif + /* Alignment */ /* We use a prefix vg_ for vg_alignof as its behaviour slightly differs from the standard alignof/gcc defined __alignof__