shithub: MicroHs

Download patch

ref: be88c32ed5ce6368378d5ed2448e8026dfc541f3
parent: a753d47a5eb757ac62ab6568f5d58ea1deda78ab
parent: f8a541c362363bbe695c9b46e6a98fbef55b7628
author: Lennart Augustsson <lennart@augustsson.net>
date: Tue Jan 30 06:49:09 EST 2024

Merge pull request #32 from jmaessen/asan-ubsan

Fix asan and ubsan violations, one of which was causing periodic crashes

--- a/src/runtime/config-unix-64.h
+++ b/src/runtime/config-unix-64.h
@@ -139,18 +139,19 @@
 {
   int pid = (int)getpid();
   char *tmp = getenv("TMPDIR");
+  const size_t PID_DIGITS = 10;
   if (!tmp)
     tmp = "/tmp";
-  char *s = malloc(strlen(tmp) + 1 + strlen(pre) + 5 + strlen(suf) + 1);
+  char *s = malloc(strlen(tmp) + 1 + strlen(pre) + PID_DIGITS + strlen(suf) + 1);
   /* This might loop forever.  See if I care. :) */
   for(;;) {
     strcpy(s, tmp);
     strcat(s, "/");
     strcat(s, pre);
-    /* Insert 8 digits of the PID */
-    char *p = s + strlen(s) + 10;
+    /* Insert PID_DIGITS digits of the PID */
+    char *p = s + strlen(s) + PID_DIGITS;
     *p-- = 0;
-    for(int i = 0; i < 10; i++) {
+    for(int i = 0; i < PID_DIGITS; i++) {
       *p-- = pid % 10 + '0';
       pid /= 10;
     }
--- a/src/runtime/eval.c
+++ b/src/runtime/eval.c
@@ -1131,8 +1131,9 @@
 value_t
 parse_int(BFILE *f)
 {
-  value_t i = 0;
-  value_t neg = 1;
+  // Parse using uvalue_t, which wraps on overflow.
+  uvalue_t i = 0;
+  int neg = 1;
   int c = getb(f);
   if (c == '-') {
     neg = -1;
@@ -1139,7 +1140,7 @@
     c = getb(f);
   }
   for(;;) {
-    i = i * 10 + c - '0';
+    i = i * 10 + (c - '0');
     c = getb(f);
     if (c < '0' || c > '9') {
       ungetb(c, f);
@@ -1146,7 +1147,8 @@
       break;
     }
   }
-  return neg * i;
+  // Multiply by neg without triggering undefined behavior.
+  return (value_t)(((uvalue_t)neg) * i);
 }
 
 #if WANT_FLOAT
@@ -2253,9 +2255,9 @@
     case T_K4:               CHECK(5); POP(5); n = TOP(-1); x = ARG(TOP(-5)); GOIND(x);     /* K4 x y z w v = *x */
     case T_CCB:  GCCHECK(2); CHKARG4; GOAP(new_ap(x, z), new_ap(y, w));                     /* C'B x y z w = x z (y w) */
 
-    case T_ADD:  ARITHBIN(+);
-    case T_SUB:  ARITHBIN(-);
-    case T_MUL:  ARITHBIN(*);
+    case T_ADD:  ARITHBINU(+);
+    case T_SUB:  ARITHBINU(-);
+    case T_MUL:  ARITHBINU(*);
     case T_QUOT: ARITHBIN(/);
     case T_REM:  ARITHBIN(%);
     case T_SUBR: OPINT2(r = yi - xi); SETINT(n, r); RET;
--