From patchwork Sat Jan 13 21:34:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Aloni X-Patchwork-Id: 10162439 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 C14E86029B for ; Sat, 13 Jan 2018 21:37:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AFDB328AFA for ; Sat, 13 Jan 2018 21:37:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A35B528B2B; Sat, 13 Jan 2018 21:37:02 +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=-2.4 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, URIBL_BLACK 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 55D4B28AFA for ; Sat, 13 Jan 2018 21:37:01 +0000 (UTC) Received: (qmail 11862 invoked by uid 550); 13 Jan 2018 21:36:32 -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 Received: (qmail 11582 invoked from network); 13 Jan 2018 21:36:30 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernelim-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=kISgPV2vDQZVAMtg8CcaNcdrstk/Y7Fip2s/zRZKzEM=; b=DZUbyrstvPhns/faj/JLIr5WzPgOYnQ7lTBurh16LiIqWyMwXbpqYW411s0RNuunzj I5SStxkYXEa6wfsuutrezIKYlrSRB5PnsT6lP67Ss3eDVFbCd+wnq/1jLWdOe6yMXdR8 lvhbJRyrRh9/V62fUZRR6y4z2AQ4mAaxy3V8R8vUP9HTobzPGjh+dKakq7qt1tGWpt9L ezEcHCN7e2E6E2V/0WYicHkp8eF5vj99+wjeZe70EhGAlNC4EOLo3XxWIA+mc3+1ShzX UAn7OJIlcDRhdOMPk90N8YqAIiK9UjsdzqtiwDgUgoH0H7mNcmJi3eXg/IYif52yNYnN g4KQ== 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=kISgPV2vDQZVAMtg8CcaNcdrstk/Y7Fip2s/zRZKzEM=; b=I0cRXPNCrVDwsllcCVs/+DB/qy3trHefBe5mk7QKviwcSVq3EolrQysNZ5w43hzBHQ y/jjD69yzVN7xiljaZipofUtkzAWPNI9fpT3iMH6Y+SCoBIlKoMK/uCMKPMJ2tIw3CNk M7LSEXeapxgrdssdemIha2a9vd+oCRP1DkUTfsHo4hxgZ5Ymze33SQuBUfuRg5rN2vA9 HAQ59obp0l4qk7zbOgTyzsHxH3GTL8W54KYY73md3Y5pPau+yZrn3HfUAl3inhL0v8Dz EAoVpbtHwg8A8RcxRd4Pv+Wl5ipi6kacW1ZSFGrHtO4Ch6h84o3Pu+yCfjGtjQKowjwC ZAZA== X-Gm-Message-State: AKGB3mIbzh7YGHP51nsNaA9kYRFArntX/YyERYJQ2lNICqZE/M2kwxBl tB5CawKd8mksujF2Y4T9ncZuzg== X-Google-Smtp-Source: ACJfBotBP1ILiOU5bw1nB2t7mjsbBMf4+TbawvU9UDk03gxK1cj5OzQH3tSZga5uFM4sQYGhO8yerg== X-Received: by 10.223.147.166 with SMTP id 35mr27872818wrp.146.1515879378639; Sat, 13 Jan 2018 13:36:18 -0800 (PST) From: Dan Aloni To: linux-kernel@vger.kernel.org, kernel-hardening@lists.openwall.com Date: Sat, 13 Jan 2018 23:34:37 +0200 Message-Id: <20180113213441.52047-4-dan@kernelim.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180113213441.52047-1-dan@kernelim.com> References: <20180113213441.52047-1-dan@kernelim.com> Subject: [kernel-hardening] [PATCHv2 3/7] base64-armor: add bounds checking X-Virus-Scanned: ClamAV using ClamSMTP Future use of the API can benefit from bounds checking. Signed-off-by: Dan Aloni --- include/linux/base64-armor.h | 17 +++++++++++------ lib/base64-armor.c | 20 ++++++++++++++++++-- net/ceph/crypto.c | 2 +- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/include/linux/base64-armor.h b/include/linux/base64-armor.h index e5160c77bb2f..bb0b4491799e 100644 --- a/include/linux/base64-armor.h +++ b/include/linux/base64-armor.h @@ -8,11 +8,13 @@ * not contain newlines, depending on input length. * * @dst: Beginning of the destination buffer. + * @dst_max: Maximum amount of bytes to write to the destination buffer. * @src: Beginning of the source buffer. * @end: Sentinel for the source buffer, pointing one byte after the * last byte to be encoded. * - * Returns the number of bytes written to the destination buffer. + * Returns the number of bytes written to the destination buffer, or + * an error of the output buffer is insufficient in size. * * _Neither_ the input or output are expected to be NULL-terminated. * @@ -22,19 +24,21 @@ * * See base64_encode_buffer_bound below. */ - -extern int base64_armor(char *dst, const char *src, const char *end); +extern int base64_armor(char *dst, int dst_max, const char *src, + const char *end); /** * base64_unarmor: Perform armored base64 decoding. * * @dst: Beginning of the destination buffer. + * @dst_max: Maximum amount of bytes to write to the destination buffer. * @src: Beginning of the source buffer * @end: Sentinel for the source buffer, pointing one byte after the * last byte to be encoded. * - * Returns the number of bytes written to the destination buffer, or - * -EINVAL if the source buffer contains invalid bytes. + * Returns the number of bytes written to the destination buffer, + * -EINVAL if the source buffer contains invalid bytes, or -ENOSPC + * if the output buffer is insufficient in size. * * _Neither_ the input or output are expected to be NULL-terminated. * @@ -43,7 +47,8 @@ extern int base64_armor(char *dst, const char *src, const char *end); * * See base64_decode_buffer_bound below. */ -extern int base64_unarmor(char *dst, const char *src, const char *end); +extern int base64_unarmor(char *dst, int dst_max, const char *src, + const char *end); /* diff --git a/lib/base64-armor.c b/lib/base64-armor.c index e07d25ac2850..f4a289f8da6a 100644 --- a/lib/base64-armor.c +++ b/lib/base64-armor.c @@ -33,7 +33,7 @@ static int decode_bits(char c) return -EINVAL; } -int base64_armor(char *dst, const char *src, const char *end) +int base64_armor(char *dst, int dst_max, const char *src, const char *end) { int olen = 0; int line = 0; @@ -42,6 +42,8 @@ int base64_armor(char *dst, const char *src, const char *end) unsigned char a, b, c; a = *src++; + if (dst_max < 4) + return -ENOSPC; *dst++ = encode_bits(a >> 2); if (src < end) { b = *src++; @@ -62,17 +64,22 @@ int base64_armor(char *dst, const char *src, const char *end) } olen += 4; line += 4; + dst_max -= 4; + if (line == 64) { line = 0; + if (dst_max < 1) + return -ENOSPC; *(dst++) = '\n'; olen++; + dst_max--; } } return olen; } EXPORT_SYMBOL(base64_unarmor); -int base64_unarmor(char *dst, const char *src, const char *end) +int base64_unarmor(char *dst, int dst_max, const char *src, const char *end) { int olen = 0; @@ -92,13 +99,22 @@ int base64_unarmor(char *dst, const char *src, const char *end) if (a < 0 || b < 0 || c < 0 || d < 0) return -EINVAL; + if (dst_max < 1) + return -ENOSPC; *dst++ = (a << 2) | (b >> 4); + dst_max--; if (src[2] == '=') return olen + 1; + if (dst_max < 1) + return -ENOSPC; *dst++ = ((b & 15) << 4) | (c >> 2); + dst_max--; if (src[3] == '=') return olen + 2; + if (dst_max < 1) + return -ENOSPC; *dst++ = ((c & 3) << 6) | d; + dst_max--; olen += 3; src += 4; } diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c index 25e04e3b1aa4..f7c75368989a 100644 --- a/net/ceph/crypto.c +++ b/net/ceph/crypto.c @@ -116,7 +116,7 @@ int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey) buf = kmalloc(blen, GFP_NOFS); if (!buf) return -ENOMEM; - blen = base64_unarmor(buf, inkey, inkey+inlen); + blen = base64_unarmor(buf, blen, inkey, inkey+inlen); if (blen < 0) { kfree(buf); return blen;