From patchwork Thu May 14 13:14:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Martin_Storsj=C3=B6?= X-Patchwork-Id: 19686 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 8517744BB27 for ; Thu, 14 May 2020 16:22:22 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 69A6168A460; Thu, 14 May 2020 16:22:22 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ed1-f66.google.com (mail-ed1-f66.google.com [209.85.208.66]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 70F3268A452 for ; Thu, 14 May 2020 16:22:16 +0300 (EEST) Received: by mail-ed1-f66.google.com with SMTP id bs4so2360359edb.6 for ; Thu, 14 May 2020 06:22:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=martin-st.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=Y/Np5IE5+/A6coqsbdDC4J6xLnjqDr5HMlJcsTZDMLM=; b=VtgZghd71BsjrX6p4WQAdmbSoyN/q3cVBZ7kHkQUtdd0c2lLL9CrzhubRvZ3BC7AIW 69B5RtHTZRt/KzODvcSJbn5lMXHG0iHLVKmptNjCjJZLI+HOwoCaf7F5qes/yeonkLFM 5zJfCm0kJmQUHB0exXU1lQzlXKnduXcg+jPUOh/lGr9RDoOuEpBswRUYUa5psYAp0GQi Efhyjs9QTVqTVpO/CAYUFdzyAwzLzF9bc04MYzbw5Igk/B+69Hqh3WIGP4pRGYxwzTUa 5qH7IR5CMURiumB+3Tn7O6AOqOTVZ1X1F0PHOEysJ/lpuvHyCOS91vUoha55VobE4GXr 70/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=Y/Np5IE5+/A6coqsbdDC4J6xLnjqDr5HMlJcsTZDMLM=; b=JDd8ccK34mGW7tekqesFxEOVeu+zhoF9wrWd9b0RqBGabT9dF881oFAW/G7Bp/LjbX eo3/YwvuYieaSLGUU1N7p1PnFr5f3KAWePF/dk+vvesNfIOakXxMevZyqEY9bQFM6aoZ UhT4/nkU6E1Jt5MjACo0n17O5QZ2+vfIqQ/PhU52cToZbMlj3Tl7wbk2v7l6GvhHWpgw e2zGjVNmpSx+VCTfj0WPW1G/RGVJOg4XUaKYqgRZZM0IbCysrBG97/HZEniFJCoT81Zw wmfyKy54BsI5dUTI2Qp0Ulju9r41/FpfSjz5L9EhS+QGtYkAu8qhhjblFH+bIXaCvpUY gRBQ== X-Gm-Message-State: AOAM530ss7LWVa2exVojfF7eaDCcA4wFwvA7N3m3Tf6ZGsfbEFZsUzY9 ad+6P6t1q7aChEUM956qB+/5CMJZIuU= X-Google-Smtp-Source: ABdhPJzFuzS4bZqY42LSC6PAbAq4j6wmYehtL54opjc1rZ1fLeu9Brp1i0nv66F0xDyBSL75+hthzQ== X-Received: by 2002:ac2:4c3b:: with SMTP id u27mr3270342lfq.212.1589462056165; Thu, 14 May 2020 06:14:16 -0700 (PDT) Received: from localhost.localdomain (dsl-tkubng21-58c01c-243.dhcp.inet.fi. [88.192.28.243]) by smtp.gmail.com with ESMTPSA id s9sm1305164ljc.43.2020.05.14.06.14.15 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 May 2020 06:14:15 -0700 (PDT) From: =?utf-8?q?Martin_Storsj=C3=B6?= To: ffmpeg-devel@ffmpeg.org Date: Thu, 14 May 2020 16:14:12 +0300 Message-Id: <20200514131412.27655-5-martin@martin.st> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200514131412.27655-1-martin@martin.st> References: <20200514131412.27655-1-martin@martin.st> Subject: [FFmpeg-devel] [PATCH 5/5] checkasm: aarch64: Check for stack overflows X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Also fill x8-x17 with garbage before calling the function. Figure out the number of stack parameters and make sure that the value on the stack after those is untouched. --- tests/checkasm/aarch64/checkasm.S | 47 +++++++++++++++++++++++++++++-- tests/checkasm/checkasm.h | 7 +++-- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/tests/checkasm/aarch64/checkasm.S b/tests/checkasm/aarch64/checkasm.S index 0dbfe8025e..6d3c738801 100644 --- a/tests/checkasm/aarch64/checkasm.S +++ b/tests/checkasm/aarch64/checkasm.S @@ -44,8 +44,10 @@ const register_init, align=4 endconst -const error_message +const error_message_register .asciz "failed to preserve register" +error_message_stack: + .asciz "stack clobbered" endconst @@ -65,7 +67,8 @@ function checkasm_stack_clobber, export=1 ret endfunc -#define ARG_STACK ((8*(MAX_ARGS - 8) + 15) & ~15) +// + 16 for stack canary reference +#define ARG_STACK ((8*(MAX_ARGS - 8) + 15) & ~15 + 16) function checkasm_checked_call, export=1 stp x29, x30, [sp, #-16]! @@ -100,14 +103,48 @@ function checkasm_checked_call, export=1 .equ pos, pos + 8 .endr + // Fill x8-x17 with garbage. This doesn't have to be preserved, + // but avoids relying on them having any particular value. + movrel x9, register_init + ldp x10, x11, [x9], #32 + ldp x12, x13, [x9], #32 + ldp x14, x15, [x9], #32 + ldp x16, x17, [x9], #32 + ldp x8, x9, [x9] + + // For stack overflows, the callee is free to overwrite the parameters + // that were passed on the stack (if any), so we can only check after + // that point. First figure out how many parameters the function + // really took on the stack: + ldr w2, [x29, #16 + 8*8 + (MAX_ARGS-8)*8] + // Load the first non-parameter value from the stack, that should be + // left untouched by the function. Store a copy of it inverted, so that + // e.g. overwriting everything with zero would be noticed. + ldr x2, [sp, x2, lsl #3] + mvn x2, x2 + str x2, [sp, #ARG_STACK-8] + + // Load the in-register arguments mov x12, x0 ldp x0, x1, [x29, #16] ldp x2, x3, [x29, #32] ldp x4, x5, [x29, #48] ldp x6, x7, [x29, #64] + // Call the target function blr x12 + + // Load the number of stack parameters, stack canary and its reference + ldr w2, [x29, #16 + 8*8 + (MAX_ARGS-8)*8] + ldr x2, [sp, x2, lsl #3] + ldr x3, [sp, #ARG_STACK-8] + add sp, sp, #ARG_STACK stp x0, x1, [sp, #-16]! + + mvn x3, x3 + cmp x2, x3 + b.ne 2f + movrel x9, register_init movi v3.8h, #0 @@ -139,7 +176,11 @@ function checkasm_checked_call, export=1 cbz x3, 0f - movrel x0, error_message + movrel x0, error_message_register + b 1f +2: + movrel x0, error_message_stack +1: bl X(checkasm_fail_func) 0: ldp x0, x1, [sp], #16 diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index 254e28f5e2..e7d47475f6 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -183,12 +183,15 @@ extern void (*checkasm_checked_call)(void *func, int dummy, ...); #elif ARCH_AARCH64 && !defined(__APPLE__) void checkasm_stack_clobber(uint64_t clobber, ...); void checkasm_checked_call(void *func, ...); -#define declare_new(ret, ...) ret (*checked_call)(void *, int, int, int, int, int, int, int, __VA_ARGS__)\ +#define declare_new(ret, ...) ret (*checked_call)(void *, int, int, int, int, int, int, int, __VA_ARGS__,\ + int, int, int, int, int, int, int, int,\ + int, int, int, int, int, int, int)\ = (void *)checkasm_checked_call; #define CLOB (UINT64_C(0xdeadbeefdeadbeef)) #define call_new(...) (checkasm_stack_clobber(CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,\ CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB,CLOB),\ - checked_call(func_new, 0, 0, 0, 0, 0, 0, 0, __VA_ARGS__)) + checked_call(func_new, 0, 0, 0, 0, 0, 0, 0, __VA_ARGS__,\ + 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0)) #else #define declare_new(ret, ...) #define declare_new_float(ret, ...)