The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Joan Bruguera <joanbrugueram@gmail.com>
To: haren@us.ibm.com
Cc: linux-kernel@vger.kernel.org
Subject: Re: [PATCH] Add missing bound checks for software 842 decompressor
Date: Sun, 16 Aug 2020 02:33:41 +0200	[thread overview]
Message-ID: <6b69d99f-515f-b53c-b1c1-d525788779e3@gmail.com> (raw)
In-Reply-To: <20200605154416.5022-1-joanbrugueram@gmail.com>

Any feedback?

- Joan

On 05.06.20 17:44, Joan Bruguera wrote:
> The software 842 decompressor receives, through the initial value of the
> 'olen' parameter, the capacity of the buffer pointed to by 'out'. If this
> capacity is insufficient to decode the compressed bitstream, -ENOSPC
> should be returned.
> 
> However, the bounds checks are missing for index references (for those
> ops. where decomp_ops includes a I2, I4 or I8 subop.), and also for
> OP_SHORT_DATA. Due to this, sw842_decompress can write past the capacity
> of the 'out' buffer.
> 
> The case for index references can be triggered by compressing data that
> follows a 16-byte periodic pattern (excluding special cases which are
> better encoded by OP_ZEROS) and passing a 'olen' somewhat smaller than the
> original length.
> The case for OP_SHORT_DATA can be triggered by compressing an amount of
> data that is not a multiple of 8, and then a slightly smaller 'olen' that
> can't fit those last <8 bytes.
> 
> Following is a small test module to demonstrate the issue.
> 
> -
> 
> #include <linux/module.h>
> #include <linux/kernel.h>
> #include <linux/sw842.h>
> 
> static unsigned char workspace[1000000] = { 0 }; // Hacky
> 
> static void test_bound(const char *name, unsigned ibound, unsigned dbound)
> {
> 	uint8_t in[ibound], out[ibound * 4], decomp[ibound /* Overallocated */];
> 	unsigned clen = ibound * 4, dlen = dbound, i;
> 	int ret;
> 
> 	for (i = 0; i < ibound; i ++)
> 		in[i] = i % 16; // 0, 1, 2, ..., 14, 15, 0, 1, 2, ...
> 	for (i = dbound; i < ibound; i++)
> 		decomp[i] = 0xFF; // Place guard bytes
> 
> 	ret = sw842_compress(in, ibound, out, &clen, workspace);
> 	BUG_ON(ret != 0);
> 
> 	ret = sw842_decompress(out, clen, decomp, &dlen);
> 	if (ret != -ENOSPC) {
> 		printk(KERN_ERR "%s: Expected ENOSPC to be returned\n", name);
> 	}
> 	for (i = dbound; i < ibound; i++) {
> 		if (decomp[i] != 0xFF) {
> 			printk(KERN_ERR "%s: Guard overwritten\n", name);
> 			break;
> 		}
> 	}
> }
> 
> int init_module(void)
> {
> 	test_bound("Index reference test", 256, 64);
> 	test_bound("Short data test", 12, 8);
> 	return -ECANCELED; // Do not leave this test module hanging around
> }
> 
> void cleanup_module(void)
> {
> }
> 
> MODULE_LICENSE("GPL");
> MODULE_SOFTDEP("pre: 842");
> 
> Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com>
> ---
>   lib/842/842_decompress.c | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/lib/842/842_decompress.c b/lib/842/842_decompress.c
> index 582085ef8b4..c29fbfc9d08 100644
> --- a/lib/842/842_decompress.c
> +++ b/lib/842/842_decompress.c
> @@ -202,6 +202,9 @@ static int __do_index(struct sw842_param *p, u8 size, u8 bits, u64 fsize)
>   			 (unsigned long)total,
>   			 (unsigned long)beN_to_cpu(&p->ostart[offset], size));
>   
> +	if (size > p->olen)
> +		return -ENOSPC;
> +
>   	memcpy(p->out, &p->ostart[offset], size);
>   	p->out += size;
>   	p->olen -= size;
> @@ -345,6 +348,9 @@ int sw842_decompress(const u8 *in, unsigned int ilen,
>   			if (!bytes || bytes > SHORT_DATA_BITS_MAX)
>   				return -EINVAL;
>   
> +			if (bytes > p.olen)
> +				return -ENOSPC;
> +
>   			while (bytes-- > 0) {
>   				ret = next_bits(&p, &tmp, 8);
>   				if (ret)
> 

  reply	other threads:[~2020-08-16  0:35 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-05 15:44 [PATCH] Add missing bound checks for software 842 decompressor Joan Bruguera
2020-08-16  0:33 ` Joan Bruguera [this message]
2020-08-19 20:19   ` Kees Cook
     [not found] <202008191311.A4E1B54 () keescook>
2020-08-24  1:24 ` Joan Bruguera

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=6b69d99f-515f-b53c-b1c1-d525788779e3@gmail.com \
    --to=joanbrugueram@gmail.com \
    --cc=haren@us.ibm.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