From patchwork Mon Jul 24 13:38:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Liljestrand X-Patchwork-Id: 9860087 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8635D601A1 for ; Mon, 24 Jul 2017 18:57:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 79C4C284B2 for ; Mon, 24 Jul 2017 18:57:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6E9B52852B; Mon, 24 Jul 2017 18:57:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id B5FBC284B2 for ; Mon, 24 Jul 2017 18:57:14 +0000 (UTC) Received: (qmail 16059 invoked by uid 550); 24 Jul 2017 18:57:04 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Delivered-To: moderator for kernel-hardening@lists.openwall.com Received: (qmail 28594 invoked from network); 24 Jul 2017 13:39:41 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=mQAytYhdCCprC+OX8PLCadQMAwArFTP8R/+q2YLkUjM=; b=VnnxZmPqaveOXVpZT3iz1+GG1BkTh2mT9xamtN2u0C0YL8AgN0HKEQXmDZPaOZeJ3G G/PYL9gXzI6RRy/YqvEYJNmsqiRimk5c8xVMdARyUHdeVtMN2OiZalTktQQq7sDOo/w8 vApLLX2EGtASxEGRtJZkL7vIHLRq4Bw9tSFIkyn+F7jWJ983f4L8LZJetjLnpGnlKwQ7 l7uCWXcTT2K3uMpVAeE0P7IJIuZ9RePYuVc2reNGfUe8spbW6oc7+UDq4hVDKbZU8jsO zsPN8rOe8jsslkBxiroAhyCH6CehrK1Qk8g9/b6BRT2koHW9inMUjV2mq7W8a3qaYiTM oi/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=mQAytYhdCCprC+OX8PLCadQMAwArFTP8R/+q2YLkUjM=; b=MaDfJ9HLRIJseJcQUQiPArurxMrE4HU6GdK+ExuND/1XEA+1lVHr+pCXrgeeb4OBdd 8Rwan6NDaLBLFnFVjW45UJOVnKYd17T2Pwx6U0llDTx/nIpwDqYqr/0IRH1eWV7XeXJN 4VGs1VjyTc7onI4rkJSKrLJvNeFgnuWi7OZVC4gYxgWuLVR5W5FbFtIjd0uk6HV1JxnA JOFWMi82P/H2tgnzyRxiyZ2VVHHxSuUnYDRl5iPVt8A5DTJ7vbimJ84ED2/ROBbC/34+ oi/3lZOwgMpq392ykEl6md/5uFE1fn2px6KfZ2ip43a50C3D/Pmy63S9barL9IfX15b3 +SVA== X-Gm-Message-State: AIVw1107gv+4b2FwKRq/DnBdzy3jDYlxdGJmHUAODdEjsWKegc4eVBNp rHivzXnBQbmjV2JGpsoYTg== X-Received: by 10.25.16.26 with SMTP id f26mr4411348lfi.171.1500903569541; Mon, 24 Jul 2017 06:39:29 -0700 (PDT) Sender: Hans Liljestrand From: Hans Liljestrand X-Google-Original-From: Hans Liljestrand To: kernel-hardening@lists.openwall.com Cc: elena.reshetova@intel.com, dave.hansen@intel.com, keescook@chromium.org, hpa@zytor.com, Hans Liljestrand , Hans Liljestrand Date: Mon, 24 Jul 2017 16:38:22 +0300 Message-Id: <20170724133824.27223-4-LiljestrandH@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170724133824.27223-1-LiljestrandH@gmail.com> References: <20170724133824.27223-1-LiljestrandH@gmail.com> Subject: [kernel-hardening] [RFC PATCH 3/5] x86: add mpxk-wrappers X-Virus-Scanned: ClamAV using ClamSMTP This adds actual implementation for mpxk-wrapper functions. The wrapper function are used by the instrumentation to update and check pointer bounds on functions that alter memory, e.g. kmalloc and memcpy. The kmalloc wrapper function for instance simply executes kmalloc, associates bounds with the returned pointer, and returns both. Other wrapper functions, such as for memcpy, also check the bounds of incoming arguments. For future work these wrappers could potentially be replaced by direct instrumentation without the need to incur the cost of calling the wrapper function. In this scenario every kmalloc would simply be preceded by an appropriate mkbnd instruction, and memcpy preceded by bndcu+bndcl instructions. The wrappers are added by the MPXK gcc-plugin, and as such work on preprocessed code. This introduces another problem with our implementation since macros might actually be used to direct "base functions" into specific implementations (e.g. memcpy might be a macro pointing to __memcpy). One solution is covering all possibilities, but this might introduce unwanted code bloat. Signed-off-by: Hans Liljestrand Signed-off-by: Elena Reshetova --- arch/x86/lib/mpxk-wrappers.c | 157 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 arch/x86/lib/mpxk-wrappers.c diff --git a/arch/x86/lib/mpxk-wrappers.c b/arch/x86/lib/mpxk-wrappers.c new file mode 100644 index 000000000000..0b0fe235c90f --- /dev/null +++ b/arch/x86/lib/mpxk-wrappers.c @@ -0,0 +1,157 @@ +/* + * arch/x86/lib/mpxk-wrappers.h + * + * Copyright (C) 2017 Aalto University + */ +#include +#include +#include +#include +#include +#include + +#define MPXK_BUILTIN_DEF(r, f, ...) extern r f(__VA_ARGS__); +#define MPXK_WRAPPER_DEF(r, f, ...) extern r mpxk_wrapper_##f(__VA_ARGS__); + +#include "../../../../scripts/gcc-plugins/mpxk_builtins.def" + +#undef MPXK_WRAPPER_DEF +#undef MPXK_BUILTIN_DEF + +void *mpxk_wrapper_kmalloc(size_t s, gfp_t f) +{ + void *p = kmalloc(s, f); + + if (p) + return __bnd_set_ptr_bounds(p, s); + return __bnd_null_ptr_bounds(p); +} + +void *mpxk_wrapper_krealloc(void *p, size_t s, gfp_t f) +{ + if (!p) + return mpxk_wrapper_kmalloc(s, f); + + __bnd_chk_ptr_lbounds(p); + p = krealloc(p, s, f); + + if (p) + return __bnd_set_ptr_bounds(p, s); + return __bnd_null_ptr_bounds(p); +} + +void *mpxk_wrapper_memmove(void *d, const void *s, size_t c) +{ + if (c == 0) + return d; + + __bnd_chk_ptr_bounds(d, c); + __bnd_chk_ptr_bounds(s, c); + + return memmove(d, s, c); +} + +void *mpxk_wrapper_memcpy(void *d, const void *s, size_t c) +{ + if (c == 0) + return d; + + __bnd_chk_ptr_bounds(d, c); + __bnd_chk_ptr_bounds(s, c); + + return memcpy(d, s, c); +} + +/* Because the MPXK gcc-plugin works on preprocessed code it cannot properly + * handle macro expanded calls such as potential memcpy -> __memcpy changes. + * This probably needs to be solved in some cleaner way, and probably also + * affects other function besides memcpy. + */ +void *mpxk_wrapper___inline_memcpy(void *d, const void *s, size_t c) +{ + if (c == 0) + return d; + + __bnd_chk_ptr_bounds(d, c); + __bnd_chk_ptr_bounds(s, c); + + return __inline_memcpy(d, s, c); +} + +void *mpxk_wrapper___memcpy(void *d, const void *s, size_t c) +{ + if (c == 0) + return d; + + __bnd_chk_ptr_bounds(d, c); + __bnd_chk_ptr_bounds(s, c); + + return __memcpy(d, s, c); +} + +void *mpxk_wrapper_memset(void *s, int c, size_t l) +{ + if (l > 0) { + __bnd_chk_ptr_bounds(s, l); + memset(s, c, l); + } + return s; +} + +char *mpxk_wrapper_strcat(char *d, const char *s) +{ + size_t ds = mpxk_wrapper_strlen(d); + size_t ss = mpxk_wrapper_strlen(s); + + __bnd_chk_ptr_bounds(d, ds + ss + 1); + __bnd_chk_ptr_bounds(s, ss + 1); + + return strcat(d, s); +} + +char *mpxk_wrapper_strncat(char *d, const char *s, size_t c) +{ + size_t ds = mpxk_wrapper_strlen(d); + size_t ss = mpxk_wrapper_strnlen(s, c); + + __bnd_chk_ptr_bounds(d, ds + ss + 1); + __bnd_chk_ptr_bounds(s, (ss < c ? ss + 1 : ss)); + + return strncat(d, s, c); +} + +char *mpxk_wrapper_strcpy(char *d, const char *s) +{ + size_t ss = mpxk_wrapper_strlen(s); + + __bnd_chk_ptr_bounds(d, ss + 1); + __bnd_chk_ptr_bounds(s, ss + 1); + + return strcpy(d, s); +} + +char *mpxk_wrapper_strncpy(char *d, const char *s, size_t c) +{ + size_t ss = strnlen(s, c); + + __bnd_chk_ptr_bounds(d, c); + __bnd_chk_ptr_bounds(s, (ss < c ? ss + 1 : ss)); + + return strncpy(d, s, c); +} + +size_t mpxk_wrapper_strlen(const char *s) +{ + const size_t l = strlen(s); + + __bnd_chk_ptr_bounds(s, l + 1); + return l; +} + +size_t mpxk_wrapper_strnlen(const char *s, size_t c) +{ + const size_t l = strnlen(s, c); + + __bnd_chk_ptr_bounds(s, l + 1); + return l; +}