* [Qemu-devel] [PATCH] monitor: fix parsing of big int
@ 2013-08-01 6:31 Fam Zheng
2013-08-01 13:52 ` Eric Blake
0 siblings, 1 reply; 5+ messages in thread
From: Fam Zheng @ 2013-08-01 6:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Luiz Capitulino, Fam Zheng
We call strtoull(3) to parse a string to int. the range we can accept
with our local variable "int64_t n" is (-9223372036854775808 ~
9223372036854775807), but strtoull(3) can return (0 ~
18446744073709551615UL).
So when we pass a int from HMP within the range of 9223372036854775808 ~
18446744073709551615, it's safely converted and implicitly casted to
int64_t, so n is assigned a negative value, silently, which is
incorrect. We can verify this by
(HMP) block_set_io_throttle ide0-hd0 999999999999999999 0 0 0 0 0
(HMP) block_set_io_throttle ide0-hd0 9999999999999999999 0 0 0 0 0
bps and iops values must be 0 or greater
(HMP) block_set_io_throttle ide0-hd0 99999999999999999999 0 0 0 0 0
number too large
The first command succeeds, the second is reporting a negative value
error, the third command has correct prompt.
Fix it by calling strtoll instead, which will report ERANGE as expected.
(HMP) block_set_io_throttle ide0-hd0 999999999999999999 0 0 0 0 0
(HMP) block_set_io_throttle ide0-hd0 9999999999999999999 0 0 0 0 0
number too large
(HMP) block_set_io_throttle ide0-hd0 99999999999999999999 0 0 0 0 0
number too large
Signed-off-by: Fam Zheng <famz@redhat.com>
---
monitor.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/monitor.c b/monitor.c
index 5dc0aa9..7bfb469 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3286,7 +3286,7 @@ static int64_t expr_unary(Monitor *mon)
break;
default:
errno = 0;
- n = strtoull(pch, &p, 0);
+ n = strtoll(pch, &p, 0);
if (errno == ERANGE) {
expr_error(mon, "number too large");
}
--
1.8.3.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH] monitor: fix parsing of big int
2013-08-01 6:31 [Qemu-devel] [PATCH] monitor: fix parsing of big int Fam Zheng
@ 2013-08-01 13:52 ` Eric Blake
2013-08-01 14:00 ` Luiz Capitulino
2013-08-02 3:07 ` Fam Zheng
0 siblings, 2 replies; 5+ messages in thread
From: Eric Blake @ 2013-08-01 13:52 UTC (permalink / raw)
To: Fam Zheng; +Cc: Luiz Capitulino, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 1688 bytes --]
On 08/01/2013 12:31 AM, Fam Zheng wrote:
> Fix it by calling strtoll instead, which will report ERANGE as expected.
>
> (HMP) block_set_io_throttle ide0-hd0 999999999999999999 0 0 0 0 0
> (HMP) block_set_io_throttle ide0-hd0 9999999999999999999 0 0 0 0 0
> number too large
> (HMP) block_set_io_throttle ide0-hd0 99999999999999999999 0 0 0 0 0
> number too large
Your change causes this error message:
(HMP) block_set_io_throttle ide0-hd0 -99999999999999999999 0 0 0 0 0
number too large
Does the "too large" mean in magnitude (correct message) or in value
(misleading message, as any negative number is smaller in value than our
minimum of 0)?
>
> Signed-off-by: Fam Zheng <famz@redhat.com>
> ---
> monitor.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/monitor.c b/monitor.c
> index 5dc0aa9..7bfb469 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -3286,7 +3286,7 @@ static int64_t expr_unary(Monitor *mon)
> break;
> default:
> errno = 0;
> - n = strtoull(pch, &p, 0);
> + n = strtoll(pch, &p, 0);
I'm worried that this will break callers that treat their argument as
unsigned, and where the full range of unsigned input was desirable. At
this point, it's probably safer to do a case-by-case analysis of all
callers that use expr_unary() to decide which callers must reject
negative values, instead of making the parser reject numbers that it
previously accepted, thus changing the behavior of callers that treated
the result as unsigned.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH] monitor: fix parsing of big int
2013-08-01 13:52 ` Eric Blake
@ 2013-08-01 14:00 ` Luiz Capitulino
2013-08-02 2:39 ` Fam Zheng
2013-08-02 3:07 ` Fam Zheng
1 sibling, 1 reply; 5+ messages in thread
From: Luiz Capitulino @ 2013-08-01 14:00 UTC (permalink / raw)
To: Eric Blake; +Cc: Luiz Capitulino, Fam Zheng, qemu-devel
On Thu, 01 Aug 2013 07:52:17 -0600
Eric Blake <eblake@redhat.com> wrote:
> On 08/01/2013 12:31 AM, Fam Zheng wrote:
> > Fix it by calling strtoll instead, which will report ERANGE as expected.
> >
> > (HMP) block_set_io_throttle ide0-hd0 999999999999999999 0 0 0 0 0
> > (HMP) block_set_io_throttle ide0-hd0 9999999999999999999 0 0 0 0 0
> > number too large
> > (HMP) block_set_io_throttle ide0-hd0 99999999999999999999 0 0 0 0 0
> > number too large
>
> Your change causes this error message:
> (HMP) block_set_io_throttle ide0-hd0 -99999999999999999999 0 0 0 0 0
> number too large
>
> Does the "too large" mean in magnitude (correct message) or in value
> (misleading message, as any negative number is smaller in value than our
> minimum of 0)?
>
> >
> > Signed-off-by: Fam Zheng <famz@redhat.com>
> > ---
> > monitor.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/monitor.c b/monitor.c
> > index 5dc0aa9..7bfb469 100644
> > --- a/monitor.c
> > +++ b/monitor.c
> > @@ -3286,7 +3286,7 @@ static int64_t expr_unary(Monitor *mon)
> > break;
> > default:
> > errno = 0;
> > - n = strtoull(pch, &p, 0);
> > + n = strtoll(pch, &p, 0);
>
> I'm worried that this will break callers that treat their argument as
> unsigned, and where the full range of unsigned input was desirable. At
> this point, it's probably safer to do a case-by-case analysis of all
> callers that use expr_unary() to decide which callers must reject
> negative values, instead of making the parser reject numbers that it
> previously accepted, thus changing the behavior of callers that treated
> the result as unsigned.
>
Fam, what motivated this change? Is anyone entering such big numbers
for block_set_io_throttle?
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH] monitor: fix parsing of big int
2013-08-01 14:00 ` Luiz Capitulino
@ 2013-08-02 2:39 ` Fam Zheng
0 siblings, 0 replies; 5+ messages in thread
From: Fam Zheng @ 2013-08-02 2:39 UTC (permalink / raw)
To: Luiz Capitulino; +Cc: Luiz Capitulino, qemu-devel
On Thu, 08/01 10:00, Luiz Capitulino wrote:
> On Thu, 01 Aug 2013 07:52:17 -0600
> Eric Blake <eblake@redhat.com> wrote:
>
> > On 08/01/2013 12:31 AM, Fam Zheng wrote:
> > > Fix it by calling strtoll instead, which will report ERANGE as expected.
> > >
> > > (HMP) block_set_io_throttle ide0-hd0 999999999999999999 0 0 0 0 0
> > > (HMP) block_set_io_throttle ide0-hd0 9999999999999999999 0 0 0 0 0
> > > number too large
> > > (HMP) block_set_io_throttle ide0-hd0 99999999999999999999 0 0 0 0 0
> > > number too large
> >
> > Your change causes this error message:
> > (HMP) block_set_io_throttle ide0-hd0 -99999999999999999999 0 0 0 0 0
> > number too large
> >
> > Does the "too large" mean in magnitude (correct message) or in value
> > (misleading message, as any negative number is smaller in value than our
> > minimum of 0)?
> >
> > >
> > > Signed-off-by: Fam Zheng <famz@redhat.com>
> > > ---
> > > monitor.c | 2 +-
> > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/monitor.c b/monitor.c
> > > index 5dc0aa9..7bfb469 100644
> > > --- a/monitor.c
> > > +++ b/monitor.c
> > > @@ -3286,7 +3286,7 @@ static int64_t expr_unary(Monitor *mon)
> > > break;
> > > default:
> > > errno = 0;
> > > - n = strtoull(pch, &p, 0);
> > > + n = strtoll(pch, &p, 0);
> >
> > I'm worried that this will break callers that treat their argument as
> > unsigned, and where the full range of unsigned input was desirable. At
> > this point, it's probably safer to do a case-by-case analysis of all
> > callers that use expr_unary() to decide which callers must reject
> > negative values, instead of making the parser reject numbers that it
> > previously accepted, thus changing the behavior of callers that treated
> > the result as unsigned.
> >
>
> Fam, what motivated this change? Is anyone entering such big numbers
> for block_set_io_throttle?
It's for:
https://bugzilla.redhat.com/show_bug.cgi?id=988701#c1
In practice I don't think anyone entering such big numbers, it's corner
case. But as this seems an expr_unary() bug for me (input is big int,
ret value is negative), I try to fix it.
--
Fam
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH] monitor: fix parsing of big int
2013-08-01 13:52 ` Eric Blake
2013-08-01 14:00 ` Luiz Capitulino
@ 2013-08-02 3:07 ` Fam Zheng
1 sibling, 0 replies; 5+ messages in thread
From: Fam Zheng @ 2013-08-02 3:07 UTC (permalink / raw)
To: Eric Blake; +Cc: Luiz Capitulino, qemu-devel
On Thu, 08/01 07:52, Eric Blake wrote:
> On 08/01/2013 12:31 AM, Fam Zheng wrote:
> > Fix it by calling strtoll instead, which will report ERANGE as expected.
> >
> > (HMP) block_set_io_throttle ide0-hd0 999999999999999999 0 0 0 0 0
> > (HMP) block_set_io_throttle ide0-hd0 9999999999999999999 0 0 0 0 0
> > number too large
> > (HMP) block_set_io_throttle ide0-hd0 99999999999999999999 0 0 0 0 0
> > number too large
>
> Your change causes this error message:
> (HMP) block_set_io_throttle ide0-hd0 -99999999999999999999 0 0 0 0 0
> number too large
>
> Does the "too large" mean in magnitude (correct message) or in value
> (misleading message, as any negative number is smaller in value than our
> minimum of 0)?
OK, it's another thing. If you try this w/o my patch:
(qemu) block_set_io_throttle ide0-hd0 -999999999999999999 0 0 0 0 0
bps and iops values must be 0 or greater
(qemu) block_set_io_throttle ide0-hd0 -9999999999999999999 0 0 0 0 0
/* Oops, no fail here? Of course it's because int64_t overflow (a
* negative negative) . */
(qemu) block_set_io_throttle ide0-hd0 -99999999999999999999 0 0 0 0 0
number too large
Because in expr_unary():
3233 case '-':
3234 next();
3235 n = -expr_unary(mon);
3236 break;
Then you know why, the nested expr_unary(mon) getting absolute part
reports too large...
>
> >
> > Signed-off-by: Fam Zheng <famz@redhat.com>
> > ---
> > monitor.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/monitor.c b/monitor.c
> > index 5dc0aa9..7bfb469 100644
> > --- a/monitor.c
> > +++ b/monitor.c
> > @@ -3286,7 +3286,7 @@ static int64_t expr_unary(Monitor *mon)
> > break;
> > default:
> > errno = 0;
> > - n = strtoull(pch, &p, 0);
> > + n = strtoll(pch, &p, 0);
>
> I'm worried that this will break callers that treat their argument as
> unsigned, and where the full range of unsigned input was desirable. At
> this point, it's probably safer to do a case-by-case analysis of all
> callers that use expr_unary() to decide which callers must reject
> negative values, instead of making the parser reject numbers that it
> previously accepted, thus changing the behavior of callers that treated
> the result as unsigned.
>
You are right, there are callers cast it back to uint64_t, e.g.
hmp.c:735
uint32_t size = qdict_get_int(qdict, "size")
which means they could get number as large as 9999999999999999999. This
is tricky.
--
Fam
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-08-02 4:07 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-01 6:31 [Qemu-devel] [PATCH] monitor: fix parsing of big int Fam Zheng
2013-08-01 13:52 ` Eric Blake
2013-08-01 14:00 ` Luiz Capitulino
2013-08-02 2:39 ` Fam Zheng
2013-08-02 3:07 ` Fam Zheng
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).