This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Memory leak in binutils


On Fri, Dec 06, 2019 at 08:56:14AM +0100, Philippe Antoine wrote:
> 	==1==ERROR: LeakSanitizer: detected memory leaks
> Direct leak of 12 byte(s) in 1 object(s) allocated from:
>     #0 0x49759d in malloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
>      #1 0x6c558d in create_register_operand_with_size /src/binutils-gdb/opcodes/s12z-opc.c:285:33
>      #2 0x6c229b in exg_sex_discrim /src/binutils-gdb/opcodes/s12z-opc.c:2206:25
>      #3 0x6bce95 in decode_operation /src/binutils-gdb/opcodes/s12z-opc.c:2663:10
>     #4 0x6bcc81 in decode_s12z /src/binutils-gdb/opcodes/s12z-opc.c:2699:17
>     #5 0x6baf08 in print_insn_s12z /src/binutils-gdb/opcodes/s12z-dis.c:365:5
>     #6 0x4ca15d in LLVMFuzzerTestOneInput /src/binutils-gdb/fuzz/fuzz_disassemble.c:71:13

Easily fixed like so.

	* s12z-opc.c (exg_sex_discrim): Don't leak memory on invalid
	registers.

diff --git a/opcodes/s12z-opc.c b/opcodes/s12z-opc.c
index e7a3577ef7..475c9eb5f1 100644
--- a/opcodes/s12z-opc.c
+++ b/opcodes/s12z-opc.c
@@ -2195,32 +2195,32 @@ loop_prim_n_bytes (struct mem_read_abstraction_base *mra)
 
 
 static enum optr
-exg_sex_discrim (struct mem_read_abstraction_base *mra, enum optr hint ATTRIBUTE_UNUSED)
+exg_sex_discrim (struct mem_read_abstraction_base *mra,
+		 enum optr hint ATTRIBUTE_UNUSED)
 {
   uint8_t eb;
   int status = mra->read (mra, 0, 1, &eb);
+  enum optr operator = OP_INVALID;
   if (status < 0)
-    return OP_INVALID;
+    return operator;
 
   struct operand *op0 = create_register_operand ((eb & 0xf0) >> 4);
   struct operand *op1 = create_register_operand (eb & 0xf);
 
   int reg0 = ((struct register_operand *) op0)->reg;
-  if (reg0 < 0 || reg0 >= S12Z_N_REGISTERS)
-    return OP_INVALID;
-
   int reg1 = ((struct register_operand *) op1)->reg;
-  if (reg1 < 0 || reg1 >= S12Z_N_REGISTERS)
-    return OP_INVALID;
-
-  const struct reg *r0 = registers + reg0;
-  const struct reg *r1 = registers + reg1;
+  if (reg0 >= 0 && reg0 < S12Z_N_REGISTERS
+      && reg1 >= 0 && reg1 < S12Z_N_REGISTERS)
+    {
+      const struct reg *r0 = registers + reg0;
+      const struct reg *r1 = registers + reg1;
 
-  enum optr operator = (r0->bytes < r1->bytes) ? OP_sex : OP_exg;
+      operator = r0->bytes < r1->bytes ? OP_sex : OP_exg;
+    }
 
   free (op0);
   free (op1);
-  
+
   return operator;
 }
 


-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]