[01/19] _mul_overflow and get_encoded_value

Message ID 20210515080957.20305-2-amodra@gmail.com
State New
Headers show
Series
  • Pointer UB in binutils/dwarf.c
Related show

Commit Message

Nick Alcock via Binutils May 15, 2021, 8:09 a.m.
A sufficiently mad compiler optimiser can take undefined behaviour
according to the C standard as an opportunity to remove code.  Since
"data + size" might be seen to be past the end of an array,
calculating such an expression is UB.

_mul_overflow is infrastructure for later patches.

	* bucomm.h (_mul_overflow): Define.
	* dwarf.c (get_encoded_value): Avoid pointer UB.

Patch

diff --git a/binutils/bucomm.h b/binutils/bucomm.h
index 78f61762cac..2769c278671 100644
--- a/binutils/bucomm.h
+++ b/binutils/bucomm.h
@@ -80,4 +80,12 @@  void *xmalloc (size_t);
 
 void *xrealloc (void *, size_t);
 
+#if __GNUC__ >= 7
+#define _mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
+#else
+/* Assumes unsigned values.  Careful!  Args evaluated multiple times.  */
+#define _mul_overflow(a, b, res) \
+  ((*res) = (a), (*res) *= (b), (b) != 0 && (*res) / (b) != (a))
+#endif
+
 #endif /* _BUCOMM_H */
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 2794a15a1d3..020b7e071ec 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -178,7 +178,7 @@  get_encoded_value (unsigned char **pdata,
   unsigned int size = size_of_encoded_value (encoding);
   dwarf_vma val;
 
-  if (data + size >= end)
+  if (data >= end || size > (size_t) (end - data))
     {
       warn (_("Encoded value extends past end of section\n"));
       * pdata = end;