All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: Masami Hiramatsu <mhiramat@kernel.org>,
	Srikar Dronamraju <srikar@linux.vnet.ibm.com>,
	Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Cc: akpm@linux-foundation.org, bp@alien8.de, coreteam@netfilter.org,
	syzbot <syzbot+9b64b619f10f19d19a7c@syzkaller.appspotmail.com>,
	davem@davemloft.net, gustavoars@kernel.org, hpa@zytor.com,
	john.stultz@linaro.org, kaber@trash.net,
	kadlec@blackhole.kfki.hu, linux-kernel@vger.kernel.org,
	mingo@redhat.com, netdev@vger.kernel.org,
	netfilter-devel@vger.kernel.org, pablo@netfilter.org,
	syzkaller-bugs@googlegroups.com, tglx@linutronix.de,
	torvalds@linux-foundation.org, wang.yi59@zte.com.cn,
	x86@kernel.org
Subject: Re: UBSAN: array-index-out-of-bounds in arch_uprobe_analyze_insn
Date: Tue, 1 Dec 2020 16:48:55 -0800	[thread overview]
Message-ID: <202012011616.DFBE3FC5BC@keescook> (raw)
In-Reply-To: <0000000000002cd54805afdf483f@google.com>

Hi,

There appears to be a problem with prefix counting for the instruction
decoder. It looks like insn_get_prefixes() isn't keeping "nb" and "nbytes"
in sync correctly:

        while (inat_is_legacy_prefix(attr)) {
                /* Skip if same prefix */
                for (i = 0; i < nb; i++)
                        if (prefixes->bytes[i] == b)
                                goto found;
                if (nb == 4)
                        /* Invalid instruction */
                        break;
                prefixes->bytes[nb++] = b;
		...
found:
                prefixes->nbytes++;
                insn->next_byte++;
                lb = b;
                b = peek_next(insn_byte_t, insn);
                attr = inat_get_opcode_attribute(b);
        }

(nbytes is incremented on repeated prefixes, but "nb" isn't)

However, it looks like nbytes is used as an offset:

static inline int insn_offset_rex_prefix(struct insn *insn)
{
        return insn->prefixes.nbytes;
}
static inline int insn_offset_vex_prefix(struct insn *insn)
{
        return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes;
}

Which means everything that iterates over prefixes.bytes[] is buggy,
since they may be trying to read past the end of the array:

$ git grep -A3 -E '< .*prefixes(\.|->)nbytes'
boot/compressed/sev-es.c:       for (i = 0; i < insn->prefixes.nbytes; i++) {
boot/compressed/sev-es.c-               insn_byte_t p =
insn->prefixes.bytes[i];
boot/compressed/sev-es.c-
boot/compressed/sev-es.c-               if (p == 0xf2 || p == 0xf3)
--
kernel/uprobes.c:       for (i = 0; i < insn->prefixes.nbytes; i++) {
kernel/uprobes.c-               insn_attr_t attr;
kernel/uprobes.c-
kernel/uprobes.c-               attr = inat_get_opcode_attribute(insn->prefixes.bytes[i]);
--
kernel/uprobes.c:       for (i = 0; i < insn->prefixes.nbytes; i++) {
kernel/uprobes.c-               if (insn->prefixes.bytes[i] == 0x66)
kernel/uprobes.c-                       return -ENOTSUPP;
kernel/uprobes.c-       }
--
lib/insn-eval.c:        for (i = 0; i < insn->prefixes.nbytes; i++) {
lib/insn-eval.c-                insn_byte_t p = insn->prefixes.bytes[i];
lib/insn-eval.c-
lib/insn-eval.c-                if (p == 0xf2 || p == 0xf3)
--
lib/insn-eval.c:        for (i = 0; i < insn->prefixes.nbytes; i++) {
lib/insn-eval.c-                insn_attr_t attr;
lib/insn-eval.c-
lib/insn-eval.c-                attr = inat_get_opcode_attribute(insn->prefixes.bytes[i]);

I don't see a clear way to fix this.

-Kees

On Mon, Sep 21, 2020 at 09:20:07PM -0700, syzbot wrote:
> syzbot has bisected this issue to:
> 
> commit 4b2bd5fec007a4fd3fc82474b9199af25013de4c
> Author: John Stultz <john.stultz@linaro.org>
> Date:   Sat Oct 8 00:02:33 2016 +0000
> 
>     proc: fix timerslack_ns CAP_SYS_NICE check when adjusting self
> 
> bisection log:  https://syzkaller.appspot.com/x/bisect.txt?x=1697348d900000
> start commit:   325d0eab Merge branch 'akpm' (patches from Andrew)
> git tree:       upstream
> final oops:     https://syzkaller.appspot.com/x/report.txt?x=1597348d900000
> console output: https://syzkaller.appspot.com/x/log.txt?x=1197348d900000
> kernel config:  https://syzkaller.appspot.com/x/.config?x=b12e84189082991c
> dashboard link: https://syzkaller.appspot.com/bug?extid=9b64b619f10f19d19a7c
> syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=1573a8ad900000
> C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=164ee6c5900000
> 
> Reported-by: syzbot+9b64b619f10f19d19a7c@syzkaller.appspotmail.com
> Fixes: 4b2bd5fec007 ("proc: fix timerslack_ns CAP_SYS_NICE check when adjusting self")
> 
> For information about bisection process see: https://goo.gl/tpsmEJ#bisection

-- 
Kees Cook

  reply	other threads:[~2020-12-02  0:49 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-20 23:02 UBSAN: array-index-out-of-bounds in arch_uprobe_analyze_insn syzbot
2020-09-21  0:13 ` syzbot
2020-09-22  4:20 ` syzbot
2020-12-02  0:48   ` Kees Cook [this message]
2020-12-02  6:12     ` Masami Hiramatsu

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=202012011616.DFBE3FC5BC@keescook \
    --to=keescook@chromium.org \
    --cc=akpm@linux-foundation.org \
    --cc=bp@alien8.de \
    --cc=coreteam@netfilter.org \
    --cc=davem@davemloft.net \
    --cc=gustavoars@kernel.org \
    --cc=hpa@zytor.com \
    --cc=john.stultz@linaro.org \
    --cc=kaber@trash.net \
    --cc=kadlec@blackhole.kfki.hu \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    --cc=ricardo.neri-calderon@linux.intel.com \
    --cc=srikar@linux.vnet.ibm.com \
    --cc=syzbot+9b64b619f10f19d19a7c@syzkaller.appspotmail.com \
    --cc=syzkaller-bugs@googlegroups.com \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=wang.yi59@zte.com.cn \
    --cc=x86@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.