Commit f96b4675 authored by Borislav Petkov's avatar Borislav Petkov

x86/insn: Use get_unaligned() instead of memcpy()

Use get_unaligned() instead of memcpy() to access potentially unaligned
memory, which, when accessed through a pointer, leads to undefined
behavior. get_unaligned() describes much better what is happening there
anyway even if memcpy() does the job.

In addition, since perf tool builds with -Werror, it would fire with:

  util/intel-pt-decoder/../../../arch/x86/lib/insn.c: In function '__insn_get_emulate_prefix':
  tools/include/../include/asm-generic/unaligned.h:10:15: error: packed attribute is unnecessary [-Werror=packed]
     10 |  const struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \

because -Werror=packed would complain if the packed attribute would have
no effect on the layout of the structure.

In this case, that is intentional so disable the warning only for that
compilation unit.

That part is Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>

No functional changes.

Fixes: 5ba1071f ("x86/insn, tools/x86: Fix undefined behavior due to potential unaligned accesses")
Suggested-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Acked-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
Tested-by: default avatarStephen Rothwell <sfr@canb.auug.org.au>
Link: https://lkml.kernel.org/r/YVSsIkj9Z29TyUjE@zn.tnic
parent ef775a0e
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#endif #endif
#include <asm/inat.h> /*__ignore_sync_check__ */ #include <asm/inat.h> /*__ignore_sync_check__ */
#include <asm/insn.h> /* __ignore_sync_check__ */ #include <asm/insn.h> /* __ignore_sync_check__ */
#include <asm/unaligned.h> /* __ignore_sync_check__ */
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/kconfig.h> #include <linux/kconfig.h>
...@@ -37,10 +38,10 @@ ...@@ -37,10 +38,10 @@
((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr) ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr)
#define __get_next(t, insn) \ #define __get_next(t, insn) \
({ t r; memcpy(&r, insn->next_byte, sizeof(t)); insn->next_byte += sizeof(t); leXX_to_cpu(t, r); }) ({ t r = get_unaligned((t *)(insn)->next_byte); (insn)->next_byte += sizeof(t); leXX_to_cpu(t, r); })
#define __peek_nbyte_next(t, insn, n) \ #define __peek_nbyte_next(t, insn, n) \
({ t r; memcpy(&r, (insn)->next_byte + n, sizeof(t)); leXX_to_cpu(t, r); }) ({ t r = get_unaligned((t *)(insn)->next_byte + n); leXX_to_cpu(t, r); })
#define get_next(t, insn) \ #define get_next(t, insn) \
({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); }) ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); })
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#endif #endif
#include "../include/asm/inat.h" /* __ignore_sync_check__ */ #include "../include/asm/inat.h" /* __ignore_sync_check__ */
#include "../include/asm/insn.h" /* __ignore_sync_check__ */ #include "../include/asm/insn.h" /* __ignore_sync_check__ */
#include "../include/asm-generic/unaligned.h" /* __ignore_sync_check__ */
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/kconfig.h> #include <linux/kconfig.h>
...@@ -37,10 +38,10 @@ ...@@ -37,10 +38,10 @@
((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr) ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr)
#define __get_next(t, insn) \ #define __get_next(t, insn) \
({ t r; memcpy(&r, insn->next_byte, sizeof(t)); insn->next_byte += sizeof(t); leXX_to_cpu(t, r); }) ({ t r = get_unaligned((t *)(insn)->next_byte); (insn)->next_byte += sizeof(t); leXX_to_cpu(t, r); })
#define __peek_nbyte_next(t, insn, n) \ #define __peek_nbyte_next(t, insn, n) \
({ t r; memcpy(&r, (insn)->next_byte + n, sizeof(t)); leXX_to_cpu(t, r); }) ({ t r = get_unaligned((t *)(insn)->next_byte + n); leXX_to_cpu(t, r); })
#define get_next(t, insn) \ #define get_next(t, insn) \
({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); }) ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); })
......
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copied from the kernel sources to tools/perf/:
*/
#ifndef __TOOLS_LINUX_ASM_GENERIC_UNALIGNED_H
#define __TOOLS_LINUX_ASM_GENERIC_UNALIGNED_H
#define __get_unaligned_t(type, ptr) ({ \
const struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \
__pptr->x; \
})
#define __put_unaligned_t(type, val, ptr) do { \
struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \
__pptr->x = (val); \
} while (0)
#define get_unaligned(ptr) __get_unaligned_t(typeof(*(ptr)), (ptr))
#define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr))
#endif /* __TOOLS_LINUX_ASM_GENERIC_UNALIGNED_H */
...@@ -18,3 +18,5 @@ CFLAGS_intel-pt-insn-decoder.o += -I$(OUTPUT)util/intel-pt-decoder ...@@ -18,3 +18,5 @@ CFLAGS_intel-pt-insn-decoder.o += -I$(OUTPUT)util/intel-pt-decoder
ifeq ($(CC_NO_CLANG), 1) ifeq ($(CC_NO_CLANG), 1)
CFLAGS_intel-pt-insn-decoder.o += -Wno-override-init CFLAGS_intel-pt-insn-decoder.o += -Wno-override-init
endif endif
CFLAGS_intel-pt-insn-decoder.o += -Wno-packed
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment