From 2a907fd4597d57d94fdf573f37c1d553318a7104 Mon Sep 17 00:00:00 2001 From: Alex Musolino Date: Fri, 27 Nov 2020 11:19:49 +1030 Subject: [PATCH] games/mix: fix implementation of MOVE instruction (thanks nicolagi) Plan 9 memcpy(2) uses the same implementation as memmove(2) to handle overlapping ranges. Hovewer, the MIX MOVE instruction, as described in TAOCP, specifically does not do this. It copies words one at a time starting from the lowest address. This change also expands the address validation to check that all addresses within the source and destination ranges are valid before proceeding. --- sys/src/games/mix/mix.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/sys/src/games/mix/mix.c b/sys/src/games/mix/mix.c index b7f451c0c..071d10f95 100644 --- a/sys/src/games/mix/mix.c +++ b/sys/src/games/mix/mix.c @@ -729,14 +729,20 @@ void mixmove(int s, int f) { int d; + u32int *p, *q, *pe; if(f == 0) return; - + if(s < 0 || s >= 4000 || s+f < 0 || s+f > 4000) + vmerror("Bad src range MOVE %d:%d", s, s+f-1); d = mval(ri[1], 0, MASK2); - if(d < 0 || d > 4000) - vmerror("Bad address MOVE %d", d); - memcpy(cells+d, cells+s, f*sizeof(u32int)); + if(d < 0 || d >= 4000 || d+f < 0 || d+f > 4000) + vmerror("Bad dst range MOVE %d:%d", d, d+f-1); + p = cells+d; + q = cells+s; + pe = p+f; + while(p < pe) + *p++ = *q++; d += f; d &= MASK2; ri[1] = d < 0 ? -d|SIGNB : d;