linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dan Aloni <dan@kernelim.com>
To: linux-kernel@vger.kernel.org, kernel-hardening@lists.openwall.com
Subject: [PATCHv2 3/7] base64-armor: add bounds checking
Date: Sat, 13 Jan 2018 23:34:37 +0200	[thread overview]
Message-ID: <20180113213441.52047-4-dan@kernelim.com> (raw)
In-Reply-To: <20180113213441.52047-1-dan@kernelim.com>

Future use of the API can benefit from bounds checking.

Signed-off-by: Dan Aloni <dan@kernelim.com>
---
 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;
-- 
2.14.3

  parent reply	other threads:[~2018-01-13 21:37 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-13 21:34 [PATCHv2 0/7] RFC: Public key encryption of dmesg by the kernel Dan Aloni
2018-01-13 21:34 ` [PATCHv2 1/7] crypto: fix memory leak in rsa-kcs1pad encryption Dan Aloni
2018-01-13 21:34 ` [PATCHv2 2/7] Move net/ceph/armor to lib/ and add docs Dan Aloni
2018-01-13 21:34 ` Dan Aloni [this message]
2018-01-13 21:34 ` [PATCHv2 4/7] certs: allow in-kernel access of trusted keys Dan Aloni
2018-01-13 21:34 ` [PATCHv2 5/7] printk: allow kmsg to be encrypted using public key encryption Dan Aloni
2018-01-14  1:48   ` Sergey Senozhatsky
2018-01-14  8:01     ` Dan Aloni
2018-01-15 12:52       ` Steven Rostedt
2018-01-16  2:09         ` Sergey Senozhatsky
2018-01-16 23:44         ` [kernel-hardening] " Daniel Micay
2018-01-17 15:01           ` Steven Rostedt
2018-01-13 21:34 ` [PATCHv2 6/7] tools: add dmesg decryption program Dan Aloni
2018-01-13 21:34 ` [PATCHv2 7/7] docs: add dmesg encryption doc Dan Aloni
2018-01-15  9:11 ` [PATCHv2 4/7] certs: allow in-kernel access of trusted keys David Howells

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180113213441.52047-4-dan@kernelim.com \
    --to=dan@kernelim.com \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).