From: "Daniel P. Berrangé" <berrange@redhat.com>
To: "Philippe Mathieu-Daudé" <philmd@redhat.com>
Cc: Aleksandar Markovic <amarkovic@wavecomp.com>,
Markus Armbruster <armbru@redhat.com>,
Lidong Chen <lidong.chen@oracle.com>,
Peter Maydell <peter.maydell@linaro.org>,
Aleksandar Rikalo <arikalo@wavecomp.com>,
Jason Wang <jasowang@redhat.com>,
"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
"f4bug@amsat.org" <f4bug@amsat.org>,
"darren.kenny@oracle.com" <darren.kenny@oracle.com>,
Gerd Hoffmann <kraxel@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Richard Henderson <rth@twiddle.net>,
Aurelien Jarno <aurelien@aurel32.net>,
David Gibson <david@gibson.dropbear.id.au>
Subject: Re: [Qemu-devel] [PATCH] sd: Fix out-of-bounds assertions
Date: Thu, 11 Apr 2019 12:52:16 +0100 [thread overview]
Message-ID: <20190411115216.GN3641@redhat.com> (raw)
In-Reply-To: <cd833acf-4643-0d3c-78f5-7677d224954e@redhat.com>
On Tue, Apr 09, 2019 at 11:37:44AM +0200, Philippe Mathieu-Daudé wrote:
> On 4/9/19 10:59 AM, Aleksandar Markovic wrote:
> >>
> >> Lidong Chen <lidong.chen@oracle.com> writes:
> >>
> >>> Due to an off-by-one error, the assert statements allow an
> >>> out-of-bounds array access.
> >>>
> >>> Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
> >>> ---
> >>> hw/sd/sd.c | 4 ++--
> >>> 1 file changed, 2 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> >>> index aaab15f..818f86c 100644
> >>> --- a/hw/sd/sd.c
> >>> +++ b/hw/sd/sd.c
> >>> @@ -144,7 +144,7 @@ static const char *sd_state_name(enum SDCardStates state)
> >>> if (state == sd_inactive_state) {
> >>> return "inactive";
> >>> }
> >>> - assert(state <= ARRAY_SIZE(state_name));
> >>> + assert(state < ARRAY_SIZE(state_name));
> >>> return state_name[state];
> >>> }
> >>>
> >>> @@ -165,7 +165,7 @@ static const char *sd_response_name(sd_rsp_type_t rsp)
> >>> if (rsp == sd_r1b) {
> >>> rsp = sd_r1;
> >>> }
> >>> - assert(rsp <= ARRAY_SIZE(response_name));
> >>> + assert(rsp < ARRAY_SIZE(response_name));
> >>> return response_name[rsp];
> >>> }
> >>
> >> This is the second fix for this bug pattern in a fortnight. Where's
> >> one, there are more:
> >>
> >> $ git-grep '<= ARRAY_SIZE'
> >> hw/intc/arm_gicv3_cpuif.c: assert(aprmax <= ARRAY_SIZE(cs->ich_apr[0]));
> >> hw/intc/arm_gicv3_cpuif.c: assert(aprmax <= ARRAY_SIZE(cs->ich_apr[0]));
> >> hw/net/stellaris_enet.c: if (s->tx_fifo_len + 4 <= ARRAY_SIZE(s->tx_fifo)) {
> >> hw/sd/pxa2xx_mmci.c: && s->tx_len <= ARRAY_SIZE(s->tx_fifo)
> >> hw/sd/pxa2xx_mmci.c: && s->rx_len <= ARRAY_SIZE(s->rx_fifo)
> >> hw/sd/pxa2xx_mmci.c: && s->resp_len <= ARRAY_SIZE(s->resp_fifo);
> >> hw/sd/sd.c: assert(state <= ARRAY_SIZE(state_name));
> >> hw/sd/sd.c: assert(rsp <= ARRAY_SIZE(response_name));
> >> hw/usb/hcd-xhci.c: assert(n <= ARRAY_SIZE(tmp));
> >
> >> target/mips/op_helper.c: if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) {
> >> target/mips/op_helper.c: if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) {
> >> target/mips/op_helper.c: if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) {
> >> target/mips/op_helper.c: if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) {
> >
> > The last four items are OK as they are. The variable multiple_regs is, in fact,
> > an array of 9 int constants:
> >
> > static const int multiple_regs[] = { 16, 17, 18, 19, 20, 21, 22, 23, 30 };
> >
> > ARRAY_SIZE (multiple_regs) will always be equal to 9.
> >
> > The variable base_reglist (that is checked to be > 0 and <=9) is used
> > in succeeding lines like this:
> >
> > for (i = 0; i < base_reglist; i++) {
> > do_sw(env, addr, env->active_tc.gpr[multiple_regs[i]], mem_idx,
> > GETPC());
> > addr += 4;
> > }
> >
> > Therefore, the array multiple_regs will always be accessed within its bounds.
> >
> >> target/ppc/kvm.c: <= ARRAY_SIZE(hw_debug_points));
> >> target/ppc/kvm.c: <= ARRAY_SIZE(hw_debug_points));
> >> target/ppc/kvm.c: assert((nb_hw_breakpoint + nb_hw_watchpoint) <= ARRAY_SIZE(dbg->arch.bp));
> >> tcg/tcg.c: tcg_debug_assert(pi <= ARRAY_SIZE(op->args));
> >> util/main-loop.c: g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds));
> >> util/module.c: assert(n_dirs <= ARRAY_SIZE(dirs));
> >>
> >> Lidong Chen, would you like to have a look at these?
> >>
> >> Cc'ing maintainers to help with further investigation.
> >>
> >
> > Thank you for bringing this to our attention, Markus. And thanks to Lidong too.
> >
> > Aleksandar
> >
> > P. S. Shouldn't perhaps our macro ARRAY_SIZE() be renamed to
> > NUMBER_OF_ELEMENTS()?
>
> I remember this post from Daniel where he suggests sticking to GLib
> G_N_ELEMENTS() (which looks similar to your suggestion):
> https://lists.gnu.org/archive/html/qemu-devel/2018-11/msg02676.html
>
> $ git grep G_N_ELEMENTS|wc -l
> 125
> $ git grep ARRAY_SIZE|wc -l
> 939
>
> Now it is not obvious to me to understand which GLib API we are
> encouraged to use and which ones we shouldn't.
We have a bunch of duplication that is essentially a historical
artifact from before we used GLib in QEMU. IMHO, if GLib provides
something that is equivalent with no functional downside that
matters to QEMU, then there's no reason to keep QEMU's duplicate.
IOW, I would always prefer GLib unless there's a compelling reason
not to in order to minimize what we maintain ourselves
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
WARNING: multiple messages have this Message-ID (diff)
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: "Philippe Mathieu-Daudé" <philmd@redhat.com>
Cc: Peter Maydell <peter.maydell@linaro.org>,
Aleksandar Rikalo <arikalo@wavecomp.com>,
Jason Wang <jasowang@redhat.com>,
David Gibson <david@gibson.dropbear.id.au>,
Markus Armbruster <armbru@redhat.com>,
"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
Lidong Chen <lidong.chen@oracle.com>,
"darren.kenny@oracle.com" <darren.kenny@oracle.com>,
Gerd Hoffmann <kraxel@redhat.com>,
Aleksandar Markovic <amarkovic@wavecomp.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Richard Henderson <rth@twiddle.net>,
Aurelien Jarno <aurelien@aurel32.net>,
"f4bug@amsat.org" <f4bug@amsat.org>
Subject: Re: [Qemu-devel] [PATCH] sd: Fix out-of-bounds assertions
Date: Thu, 11 Apr 2019 12:52:16 +0100 [thread overview]
Message-ID: <20190411115216.GN3641@redhat.com> (raw)
Message-ID: <20190411115216.DOQXXDvc-ijcZrunSNLbSe0r3rXP4bm177xs0r0fbK4@z> (raw)
In-Reply-To: <cd833acf-4643-0d3c-78f5-7677d224954e@redhat.com>
On Tue, Apr 09, 2019 at 11:37:44AM +0200, Philippe Mathieu-Daudé wrote:
> On 4/9/19 10:59 AM, Aleksandar Markovic wrote:
> >>
> >> Lidong Chen <lidong.chen@oracle.com> writes:
> >>
> >>> Due to an off-by-one error, the assert statements allow an
> >>> out-of-bounds array access.
> >>>
> >>> Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
> >>> ---
> >>> hw/sd/sd.c | 4 ++--
> >>> 1 file changed, 2 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> >>> index aaab15f..818f86c 100644
> >>> --- a/hw/sd/sd.c
> >>> +++ b/hw/sd/sd.c
> >>> @@ -144,7 +144,7 @@ static const char *sd_state_name(enum SDCardStates state)
> >>> if (state == sd_inactive_state) {
> >>> return "inactive";
> >>> }
> >>> - assert(state <= ARRAY_SIZE(state_name));
> >>> + assert(state < ARRAY_SIZE(state_name));
> >>> return state_name[state];
> >>> }
> >>>
> >>> @@ -165,7 +165,7 @@ static const char *sd_response_name(sd_rsp_type_t rsp)
> >>> if (rsp == sd_r1b) {
> >>> rsp = sd_r1;
> >>> }
> >>> - assert(rsp <= ARRAY_SIZE(response_name));
> >>> + assert(rsp < ARRAY_SIZE(response_name));
> >>> return response_name[rsp];
> >>> }
> >>
> >> This is the second fix for this bug pattern in a fortnight. Where's
> >> one, there are more:
> >>
> >> $ git-grep '<= ARRAY_SIZE'
> >> hw/intc/arm_gicv3_cpuif.c: assert(aprmax <= ARRAY_SIZE(cs->ich_apr[0]));
> >> hw/intc/arm_gicv3_cpuif.c: assert(aprmax <= ARRAY_SIZE(cs->ich_apr[0]));
> >> hw/net/stellaris_enet.c: if (s->tx_fifo_len + 4 <= ARRAY_SIZE(s->tx_fifo)) {
> >> hw/sd/pxa2xx_mmci.c: && s->tx_len <= ARRAY_SIZE(s->tx_fifo)
> >> hw/sd/pxa2xx_mmci.c: && s->rx_len <= ARRAY_SIZE(s->rx_fifo)
> >> hw/sd/pxa2xx_mmci.c: && s->resp_len <= ARRAY_SIZE(s->resp_fifo);
> >> hw/sd/sd.c: assert(state <= ARRAY_SIZE(state_name));
> >> hw/sd/sd.c: assert(rsp <= ARRAY_SIZE(response_name));
> >> hw/usb/hcd-xhci.c: assert(n <= ARRAY_SIZE(tmp));
> >
> >> target/mips/op_helper.c: if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) {
> >> target/mips/op_helper.c: if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) {
> >> target/mips/op_helper.c: if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) {
> >> target/mips/op_helper.c: if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) {
> >
> > The last four items are OK as they are. The variable multiple_regs is, in fact,
> > an array of 9 int constants:
> >
> > static const int multiple_regs[] = { 16, 17, 18, 19, 20, 21, 22, 23, 30 };
> >
> > ARRAY_SIZE (multiple_regs) will always be equal to 9.
> >
> > The variable base_reglist (that is checked to be > 0 and <=9) is used
> > in succeeding lines like this:
> >
> > for (i = 0; i < base_reglist; i++) {
> > do_sw(env, addr, env->active_tc.gpr[multiple_regs[i]], mem_idx,
> > GETPC());
> > addr += 4;
> > }
> >
> > Therefore, the array multiple_regs will always be accessed within its bounds.
> >
> >> target/ppc/kvm.c: <= ARRAY_SIZE(hw_debug_points));
> >> target/ppc/kvm.c: <= ARRAY_SIZE(hw_debug_points));
> >> target/ppc/kvm.c: assert((nb_hw_breakpoint + nb_hw_watchpoint) <= ARRAY_SIZE(dbg->arch.bp));
> >> tcg/tcg.c: tcg_debug_assert(pi <= ARRAY_SIZE(op->args));
> >> util/main-loop.c: g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds));
> >> util/module.c: assert(n_dirs <= ARRAY_SIZE(dirs));
> >>
> >> Lidong Chen, would you like to have a look at these?
> >>
> >> Cc'ing maintainers to help with further investigation.
> >>
> >
> > Thank you for bringing this to our attention, Markus. And thanks to Lidong too.
> >
> > Aleksandar
> >
> > P. S. Shouldn't perhaps our macro ARRAY_SIZE() be renamed to
> > NUMBER_OF_ELEMENTS()?
>
> I remember this post from Daniel where he suggests sticking to GLib
> G_N_ELEMENTS() (which looks similar to your suggestion):
> https://lists.gnu.org/archive/html/qemu-devel/2018-11/msg02676.html
>
> $ git grep G_N_ELEMENTS|wc -l
> 125
> $ git grep ARRAY_SIZE|wc -l
> 939
>
> Now it is not obvious to me to understand which GLib API we are
> encouraged to use and which ones we shouldn't.
We have a bunch of duplication that is essentially a historical
artifact from before we used GLib in QEMU. IMHO, if GLib provides
something that is equivalent with no functional downside that
matters to QEMU, then there's no reason to keep QEMU's duplicate.
IOW, I would always prefer GLib unless there's a compelling reason
not to in order to minimize what we maintain ourselves
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
next prev parent reply other threads:[~2019-04-11 11:52 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-08 19:04 [Qemu-devel] [PATCH] sd: Fix out-of-bounds assertions Lidong Chen
2019-04-08 19:04 ` Lidong Chen
2019-04-08 19:53 ` Marc-André Lureau
2019-04-08 19:53 ` Marc-André Lureau
2019-04-08 21:27 ` Philippe Mathieu-Daudé
2019-04-08 21:27 ` Philippe Mathieu-Daudé
2019-04-08 21:57 ` Lidong Chen
2019-04-08 21:57 ` Lidong Chen
2019-04-09 0:18 ` Li Qiang
2019-04-09 0:18 ` Li Qiang
2019-04-09 5:51 ` Markus Armbruster
2019-04-09 5:51 ` Markus Armbruster
2019-04-09 8:59 ` Aleksandar Markovic
2019-04-09 8:59 ` Aleksandar Markovic
2019-04-09 9:37 ` Philippe Mathieu-Daudé
2019-04-09 9:37 ` Philippe Mathieu-Daudé
2019-04-11 11:52 ` Daniel P. Berrangé [this message]
2019-04-11 11:52 ` Daniel P. Berrangé
2019-04-11 12:20 ` Markus Armbruster
2019-04-11 12:20 ` Markus Armbruster
2019-04-11 12:45 ` Daniel P. Berrangé
2019-04-11 12:45 ` Daniel P. Berrangé
2019-04-11 13:25 ` Markus Armbruster
2019-04-11 13:25 ` Markus Armbruster
2019-04-09 9:40 ` Aleksandar Markovic
2019-04-09 9:40 ` Aleksandar Markovic
2019-04-09 9:48 ` Peter Maydell
2019-04-09 9:48 ` Peter Maydell
2019-04-09 10:39 ` Liam Merwick
2019-04-09 10:39 ` Liam Merwick
2019-04-10 21:49 ` Lidong Chen
2019-04-10 21:49 ` Lidong Chen
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=20190411115216.GN3641@redhat.com \
--to=berrange@redhat.com \
--cc=amarkovic@wavecomp.com \
--cc=arikalo@wavecomp.com \
--cc=armbru@redhat.com \
--cc=aurelien@aurel32.net \
--cc=darren.kenny@oracle.com \
--cc=david@gibson.dropbear.id.au \
--cc=f4bug@amsat.org \
--cc=jasowang@redhat.com \
--cc=kraxel@redhat.com \
--cc=lidong.chen@oracle.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/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).