Blob Blame History Raw
commit 81bde8f873216c116988a98a0804dd79009b3d40
Author: Mark Wielaard <mjw@redhat.com>
Date:   Mon Jun 22 16:57:59 2015 +0200

    runtime/unwind.c: Also sanity check DWARF regno for DW_CFA_restore[_extended].
    
    When processCFI wanted to restore a register state to its initial value it
    wasn't checking whether the register was actually interesting (or existing).
    DWARF_REG_MAP might return a marker (9999) that we don't know or don't care
    about this register. This was checked in all the set_*_rule functions, but
    not in the case we reset the rule of the register. Add this check also for
    DW_CFA_restore[_extended].

diff --git a/runtime/unwind.c b/runtime/unwind.c
index d38363b..4dbab33 100644
--- a/runtime/unwind.c
+++ b/runtime/unwind.c
@@ -426,7 +426,8 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
 						    value, DWARF_REG_MAP(value));
 					value = DWARF_REG_MAP(value);
 				}
-				memcpy(&REG_STATE.regs[value], &state->cie_regs[value], sizeof(struct unwind_item));
+				if (value < ARRAY_SIZE(REG_STATE.regs))
+					memcpy(&REG_STATE.regs[value], &state->cie_regs[value], sizeof(struct unwind_item));
 				break;
 			case DW_CFA_undefined:
 				value = get_uleb128(&ptr.p8, end);
@@ -641,7 +642,8 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
 					    value, DWARF_REG_MAP(value));
 				value = DWARF_REG_MAP(value);
 			}
-			memcpy(&REG_STATE.regs[value], &state->cie_regs[value], sizeof(struct unwind_item));
+			if (value < ARRAY_SIZE(REG_STATE.regs))
+				memcpy(&REG_STATE.regs[value], &state->cie_regs[value], sizeof(struct unwind_item));
 			break;
 		}
 		dbug_unwind(1, "targetLoc=%lx state->loc=%lx\n", targetLoc, state->loc);

commit db6670607f9ba837a7a7af8a0ea076595e9eca1d
Author: David Smith <dsmith@redhat.com>
Date:   Tue Jun 30 15:24:54 2015 -0500

    Two small stat code fixes found by source analysis.
    
    * runtime/stat-common.c (_stp_stat_print_histogram_buf): Fixed small
      potential overflow problem by widening values.
    * runtime/stat.c (_stp_stat_init): Fixed missing 'va_end' call in an error
      situation.

diff --git a/runtime/stat-common.c b/runtime/stat-common.c
index f8372ac..4491b27 100644
--- a/runtime/stat-common.c
+++ b/runtime/stat-common.c
@@ -261,10 +261,10 @@ static void _stp_stat_print_histogram_buf(char *buf, size_t size, Hist st,
 				val_prefix = "<";
 			} else if (i == st->buckets-1) {
 				/* overflow */
-				val = st->start + (i - 2) * st->interval;
+				val = st->start + (int64_t)(i - 2) * st->interval;
 				val_prefix = ">";
 			} else
-				val = st->start + (i - 1) * st->interval;
+				val = st->start + (int64_t)(i - 1) * st->interval;
 		} else
 			val = _stp_bucket_to_val(i);
 
diff --git a/runtime/stat.c b/runtime/stat.c
index 63ffccc..fa5939b 100644
--- a/runtime/stat.c
+++ b/runtime/stat.c
@@ -71,8 +71,10 @@ static Stat _stp_stat_init (int type, ...)
 			interval = va_arg(ap, int);
 
 			buckets = _stp_stat_calc_buckets(stop, start, interval);
-			if (!buckets)
+			if (!buckets) {
+				va_end (ap);
 				return NULL;
+			}
 		}
 		va_end (ap);
 	}

commit 39c6af0c27dfd5cdd71ee60e1667d40d101ff8ac
Author: Mark Wielaard <mjw@redhat.com>
Date:   Tue Jun 30 21:54:28 2015 +0200

    unwind.c (compute_expr): Don't fallthrough after div/mod/shr.
    
    When processing DW_OP_div, DW_OP_mod or DW_OP_shr compute_expr
    would accidentially fallthrough to the next case statement causing
    the DWARF value stack to contain wrong values.

diff --git a/runtime/unwind.c b/runtime/unwind.c
index 4dbab33..b5c8f6f 100644
--- a/runtime/unwind.c
+++ b/runtime/unwind.c
@@ -1036,6 +1036,7 @@ static int compute_expr(const u8 *expr, struct unwind_frame_info *frame,
 			if (b == 0)
 				goto divzero;
 			PUSH (a % b);
+			break;
 		}
 
 		case DW_OP_div: {
@@ -1044,12 +1045,14 @@ static int compute_expr(const u8 *expr, struct unwind_frame_info *frame,
 			if (b == 0)
 				goto divzero;
 			PUSH (a / b);
+			break;
 		}
 
 		case DW_OP_shr: {
 			unsigned long b = POP;
 			unsigned long a = POP;
 			PUSH (a >> b);
+			break;
 		}
 
 		case DW_OP_not:
diff --git a/runtime/unwind/unwind.h b/runtime/unwind/unwind.h
index e81e741..d72f68d 100644
--- a/runtime/unwind/unwind.h
+++ b/runtime/unwind/unwind.h
@@ -157,6 +157,7 @@ static unsigned long read_ptr_sect(const u8 **pLoc, const void *end,
 #else
 		BUILD_BUG_ON(sizeof(u32) != sizeof(value));
 #endif
+	/* fallthrough, see above. */
 	case DW_EH_PE_absptr:
 		if (compat_task)
 		{