summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2021-07-14 17:04:40 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2021-07-14 17:04:40 +0000
commit1a46b6c19e0e81cd3125a9e026e6aec76ccb110b (patch)
treec4331af7c24a8fc15bf2d456d80df9a01da991aa
parent6560e7c6fd26dc99604beba0f45292f592155aeb (diff)
downloadplan9front-1a46b6c19e0e81cd3125a9e026e6aec76ccb110b.tar.xz
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
-rw-r--r--sys/src/libaml/aml.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/sys/src/libaml/aml.c b/sys/src/libaml/aml.c
index 454370811..73b22524a 100644
--- a/sys/src/libaml/aml.c
+++ b/sys/src/libaml/aml.c
@@ -285,7 +285,7 @@ mk(int tag, int size)
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 @@ rwfieldunit(Field *f, int off, int len, uvlong v, int write)
{
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 @@ rwfield(Field *f, void *v, int write)
}
} 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 @@ rwfield(Field *f, void *v, int write)
}
}
}
+ amldrop(b);
if(write)
return nil;
if(blen > 64)