Aarch64: Better termination checks for sigcontext reading

Message ID 20181018100430.5627-1-alan.hayward@arm.com
State New, archived
Headers

Commit Message

Alan Hayward Oct. 18, 2018, 10:04 a.m. UTC
  Fixing up my own error. Almost sent this as OBV, but held off.

When reading the reserved section on in the sigcontext ensure
address is updated on an unknown section. For additional safety, add
checks to prevent reading past the end of the array.

Fixes gdb.base/savedregs.exp

2018-10-18  Alan Hayward  <alan.hayward@arm.com>

	* aarch64-linux-tdep.c (AARCH64_SIGCONTEXT_RESERVED_SIZE): New
	define.
	(aarch64_linux_sigframe_init): Extra boundary checks.
---
 gdb/aarch64-linux-tdep.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)
  

Comments

Kevin Buettner Oct. 19, 2018, 11:51 a.m. UTC | #1
Hi Alan,

My only nit is the extra preposition in your description...

On Thu, 18 Oct 2018 11:04:30 +0100
Alan Hayward <alan.hayward@arm.com> wrote:

> When reading the reserved section on in the sigcontext ensure

s/on in/in/

Otherwise, LGTM.

Kevin
  

Patch

diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index f2962075c5..d6dfbb6775 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -137,6 +137,8 @@ 
 #define AARCH64_SIGCONTEXT_XO_OFFSET            8
 #define AARCH64_SIGCONTEXT_RESERVED_OFFSET      288
 
+#define AARCH64_SIGCONTEXT_RESERVED_SIZE	4096
+
 /* Unique identifiers that may be used for aarch64_ctx.magic.  */
 #define AARCH64_EXTRA_MAGIC			0x45585401
 #define AARCH64_FPSIMD_MAGIC			0x46508001
@@ -197,9 +199,11 @@  aarch64_linux_sigframe_init (const struct tramp_frame *self,
   CORE_ADDR sigcontext_addr = (sp + AARCH64_RT_SIGFRAME_UCONTEXT_OFFSET
 			       + AARCH64_UCONTEXT_SIGCONTEXT_OFFSET );
   CORE_ADDR section = sigcontext_addr + AARCH64_SIGCONTEXT_RESERVED_OFFSET;
+  CORE_ADDR section_end = section + AARCH64_SIGCONTEXT_RESERVED_SIZE;
   CORE_ADDR fpsimd = 0;
   CORE_ADDR sve_regs = 0;
   uint32_t size, magic;
+  bool extra_found = false;
   int num_regs = gdbarch_num_regs (gdbarch);
 
   /* Read in the integer registers.  */
@@ -218,8 +222,9 @@  aarch64_linux_sigframe_init (const struct tramp_frame *self,
 			   sigcontext_addr + AARCH64_SIGCONTEXT_XO_OFFSET
 			     + 32 * AARCH64_SIGCONTEXT_REG_SIZE);
 
-  /* Find the FP and SVE sections.  */
-  while ((magic = read_aarch64_ctx (section, byte_order, &size)) != 0)
+  /* Search for the FP and SVE sections, stopping at null.  */
+  while ((magic = read_aarch64_ctx (section, byte_order, &size)) != 0
+	 && size != 0)
     {
       switch (magic)
 	{
@@ -273,12 +278,20 @@  aarch64_linux_sigframe_init (const struct tramp_frame *self,
 	      }
 
 	    section = extract_unsigned_integer (buf, 8, byte_order);
+	    extra_found = true;
 	    break;
 	  }
 
 	default:
+	  section += size;
 	  break;
 	}
+
+      /* Prevent searching past the end of the reserved section.  The extra
+	 section does not have a hard coded limit - we have to rely on it ending
+	 with nulls.  */
+      if (!extra_found && section > section_end)
+	break;
     }
 
   if (sve_regs != 0)