commit ba423ce6f0a2692e2105645b05b2beb09c061c28
parent e3e640acce7abd063b8c698e704852344472b99c
Author: Drew DeVault <sir@cmpwn.com>
Date: Wed, 11 Aug 2021 09:34:11 +0200
gen: fix use-after-free on append to self
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/rt/ensure.ha b/rt/ensure.ha
@@ -6,6 +6,9 @@ export type slice = struct {
export fn ensure(s: *slice, membsz: size) void = {
let cap = s.capacity;
+ if (cap >= s.length) {
+ return;
+ };
for (cap < s.length) {
assert(cap >= s.capacity, "slice out of memory (overflow)");
if (cap == 0) {
diff --git a/src/gen.c b/src/gen.c
@@ -532,8 +532,8 @@ gen_expr_append(struct gen_context *ctx, const struct expression *expr)
vlen = constl(vtype->array.length);
break;
case STORAGE_SLICE:
- vlen = mkqtmp(ctx, ctx->arch.sz, ".%d");
- pushi(ctx->current, &vdata, load, &qvobj, NULL);
+ vlen = mkqtmp(ctx, ctx->arch.sz, "vlen.%d");
+ pushi(ctx->current, &vdata, Q_COPY, &qvobj, NULL);
pushi(ctx->current, &ptr, Q_ADD, &qvobj, &offs, NULL);
pushi(ctx->current, &vlen, load, &ptr, NULL);
break;
@@ -572,6 +572,7 @@ gen_expr_append(struct gen_context *ctx, const struct expression *expr)
}
offs = mkqtmp(ctx, ctx->arch.sz, ".%d");
+ ptr = mkqtmp(ctx, ctx->arch.ptr, ".%d");
pushi(ctx->current, &ptr, load, &qslice, NULL);
pushi(ctx->current, &offs, Q_MUL, &len, &membsz, NULL);
pushi(ctx->current, &ptr, Q_ADD, &ptr, &offs, NULL);
@@ -588,9 +589,12 @@ gen_expr_append(struct gen_context *ctx, const struct expression *expr)
}
if (expr->append.variadic) {
- struct qbe_value rtfunc = mkrtfunc(ctx, "rt.memcpy");
+ struct qbe_value rtfunc = mkrtfunc(ctx, "rt.memmove");
struct qbe_value sz = mkqtmp(ctx, ctx->arch.sz, ".%d");
pushi(ctx->current, &sz, Q_MUL, &vlen, &membsz, NULL);
+ if (vtype->storage == STORAGE_SLICE) {
+ pushi(ctx->current, &vdata, load, &vdata, NULL);
+ }
pushi(ctx->current, NULL, Q_CALL, &rtfunc, &ptr, &vdata, &sz, NULL);
}
diff --git a/tests/configure b/tests/configure
@@ -57,6 +57,7 @@ EOF
15-enums \
16-defer \
17-alloc \
+ 19-append \
20-if \
24-imports \
25-promotion \
@@ -66,7 +67,6 @@ EOF
# Disabled tests
#18-match \
- #19-append \
#21-tuples \
#22-delete \
#23-errors \