git: 9front

Download patch

ref: eb419f93fd5ca6cd199f1bd8223aee694c015fbb
parent: 850d68c5ec15d1403ada170462ae53a0a647aeb6
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed Jul 14 13:04:40 EDT 2021

libaml: fix gc bug, need to amltake()/amldrop() temporary buffer

we have to protect the temporary buffer allocated by rwfield()
as rwreg() calls amlmapio() which might cause further aml code
execution causing gc() which frees it under us (as it is not
referenced from the interpreter state).

this fixes a panic on boot of a

Lenovo Thinkpad P17 Gen1 Professional Mobile Workstation

--- a/sys/src/libaml/aml.c
+++ b/sys/src/libaml/aml.c
@@ -285,7 +285,7 @@
 	int a;
 
 	a = sizeof(Heap) + size;
-	assert(a >= 0);
+	assert(a >= sizeof(Heap));
 	h = amlalloc(a);
 	h->size = size;
 	h->tag = tag;
@@ -615,20 +615,16 @@
 {
 	if(f->index){
 		if(TAG(f->reg) == 'f'){
-			void *b;
-
 			/* set index field */
 			rwfield(f->index, mki(off), 1);
 
-			/* set data field */
-			f = f->reg;
+			/* set or get data field */
 			if(write){
-				b = mk('b', len);
+				void *b = mk('b', len);
 				putle(b, len, v);
-				rwfield(f, b, 1);
+				rwfield(f->reg, b, 1);
 			}else{
-				b = rwfield(f, nil, 0);
-				v = getle(b, len);
+				v = ival(rwfield(f->reg, nil, 0));
 			}
 			return v;
 		}
@@ -661,6 +657,11 @@
 		}
 	} else
 		b = mk('b', (blen+7)/8);
+	/*
+	 * don't free b while in rwfieldunit()/rwreg(),
+	 * gc can't find this temporary object referenced.
+	 */
+	amltake(b);
 	wa = fieldalign(f->flags);
 	wd = wa*8;
 	boff = 0;
@@ -688,6 +689,7 @@
 			}
 		}
 	}
+	amldrop(b);
 	if(write)
 		return nil;
 	if(blen > 64)
--