* [PATCH] eif: cope with huge section offsets
@ 2024-11-06 17:42 Paolo Bonzini
2024-11-06 17:47 ` Pierrick Bouvier
0 siblings, 1 reply; 6+ messages in thread
From: Paolo Bonzini @ 2024-11-06 17:42 UTC (permalink / raw)
To: qemu-devel; +Cc: dorjoychy111
Check for overflow to avoid that fseek() receives a sign-extended value.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/qemu/osdep.h | 4 ++++
hw/core/eif.c | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index fe7c3c5f673..fdff07fd992 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -297,6 +297,10 @@ void QEMU_ERROR("code path is reachable")
#error building with G_DISABLE_ASSERT is not supported
#endif
+#ifndef OFF_MAX
+#define OFF_MAX (sizeof (off_t) == 8 ? INT64_MAX : INT32_MAX)
+#endif
+
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
diff --git a/hw/core/eif.c b/hw/core/eif.c
index 7f3b2edc9a7..cbcd80de58b 100644
--- a/hw/core/eif.c
+++ b/hw/core/eif.c
@@ -115,6 +115,10 @@ static bool read_eif_header(FILE *f, EifHeader *header, uint32_t *crc,
for (int i = 0; i < MAX_SECTIONS; ++i) {
header->section_offsets[i] = be64_to_cpu(header->section_offsets[i]);
+ if (header->section_offsets[i] > OFF_MAX) {
+ error_setg(errp, "Invalid EIF image. Section offset out of bounds");
+ return false;
+ }
}
for (int i = 0; i < MAX_SECTIONS; ++i) {
--
2.47.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] eif: cope with huge section offsets
2024-11-06 17:42 [PATCH] eif: cope with huge section offsets Paolo Bonzini
@ 2024-11-06 17:47 ` Pierrick Bouvier
2024-11-06 17:49 ` Paolo Bonzini
0 siblings, 1 reply; 6+ messages in thread
From: Pierrick Bouvier @ 2024-11-06 17:47 UTC (permalink / raw)
To: Paolo Bonzini, qemu-devel; +Cc: dorjoychy111
On 11/6/24 09:42, Paolo Bonzini wrote:
> Check for overflow to avoid that fseek() receives a sign-extended value.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> include/qemu/osdep.h | 4 ++++
> hw/core/eif.c | 4 ++++
> 2 files changed, 8 insertions(+)
>
> diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
> index fe7c3c5f673..fdff07fd992 100644
> --- a/include/qemu/osdep.h
> +++ b/include/qemu/osdep.h
> @@ -297,6 +297,10 @@ void QEMU_ERROR("code path is reachable")
> #error building with G_DISABLE_ASSERT is not supported
> #endif
>
> +#ifndef OFF_MAX
> +#define OFF_MAX (sizeof (off_t) == 8 ? INT64_MAX : INT32_MAX)
> +#endif
> +
> #ifndef O_LARGEFILE
> #define O_LARGEFILE 0
> #endif
> diff --git a/hw/core/eif.c b/hw/core/eif.c
> index 7f3b2edc9a7..cbcd80de58b 100644
> --- a/hw/core/eif.c
> +++ b/hw/core/eif.c
> @@ -115,6 +115,10 @@ static bool read_eif_header(FILE *f, EifHeader *header, uint32_t *crc,
>
> for (int i = 0; i < MAX_SECTIONS; ++i) {
> header->section_offsets[i] = be64_to_cpu(header->section_offsets[i]);
> + if (header->section_offsets[i] > OFF_MAX) {
Maybe we could add a comment that sections_offsets is unsigned, as it
can be confusing to read value > INT_MAX without more context.
> + error_setg(errp, "Invalid EIF image. Section offset out of bounds");
> + return false;
> + }
> }
>
> for (int i = 0; i < MAX_SECTIONS; ++i) {
Else,
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] eif: cope with huge section offsets
2024-11-06 17:47 ` Pierrick Bouvier
@ 2024-11-06 17:49 ` Paolo Bonzini
2024-11-06 17:54 ` Pierrick Bouvier
0 siblings, 1 reply; 6+ messages in thread
From: Paolo Bonzini @ 2024-11-06 17:49 UTC (permalink / raw)
To: Pierrick Bouvier; +Cc: qemu-devel, dorjoychy111
On Wed, Nov 6, 2024 at 6:47 PM Pierrick Bouvier
<pierrick.bouvier@linaro.org> wrote:
> > for (int i = 0; i < MAX_SECTIONS; ++i) {
> > header->section_offsets[i] = be64_to_cpu(header->section_offsets[i]);
> > + if (header->section_offsets[i] > OFF_MAX) {
>
> Maybe we could add a comment that sections_offsets is unsigned, as it
> can be confusing to read value > INT_MAX without more context.
It does sound like OFF_MAX is related to section_offsets[], but it's
actually related to off_t. So the comparison is with the maximum
value of off_t, which is signed.
The problem would happen even if section_offsets[] was signed (for
example off_t could be 32-bit).
Paolo
> > + error_setg(errp, "Invalid EIF image. Section offset out of bounds");
> > + return false;
> > + }
> > }
> >
> > for (int i = 0; i < MAX_SECTIONS; ++i) {
>
> Else,
> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] eif: cope with huge section offsets
2024-11-06 17:49 ` Paolo Bonzini
@ 2024-11-06 17:54 ` Pierrick Bouvier
2024-11-06 17:58 ` Paolo Bonzini
0 siblings, 1 reply; 6+ messages in thread
From: Pierrick Bouvier @ 2024-11-06 17:54 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, dorjoychy111
On 11/6/24 09:49, Paolo Bonzini wrote:
> On Wed, Nov 6, 2024 at 6:47 PM Pierrick Bouvier
> <pierrick.bouvier@linaro.org> wrote:
>
>>> for (int i = 0; i < MAX_SECTIONS; ++i) {
>>> header->section_offsets[i] = be64_to_cpu(header->section_offsets[i]);
>>> + if (header->section_offsets[i] > OFF_MAX) {
>>
>> Maybe we could add a comment that sections_offsets is unsigned, as it
>> can be confusing to read value > INT_MAX without more context.
>
> It does sound like OFF_MAX is related to section_offsets[], but it's
> actually related to off_t. So the comparison is with the maximum
> value of off_t, which is signed.
>
> The problem would happen even if section_offsets[] was signed (for
> example off_t could be 32-bit).
>
I'm a bit confused.
It works because section_offsets[i] is unsigned. If it was signed, and
sizeof(off_t) is 8, we can never satisfy "(int64) > INT64_MAX".
> Paolo
>
>>> + error_setg(errp, "Invalid EIF image. Section offset out of bounds");
>>> + return false;
>>> + }
>>> }
>>>
>>> for (int i = 0; i < MAX_SECTIONS; ++i) {
>>
>> Else,
>> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
>>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] eif: cope with huge section offsets
2024-11-06 17:54 ` Pierrick Bouvier
@ 2024-11-06 17:58 ` Paolo Bonzini
2024-11-06 18:07 ` Dorjoy Chowdhury
0 siblings, 1 reply; 6+ messages in thread
From: Paolo Bonzini @ 2024-11-06 17:58 UTC (permalink / raw)
To: Pierrick Bouvier; +Cc: qemu-devel, dorjoychy111
On Wed, Nov 6, 2024 at 6:54 PM Pierrick Bouvier
<pierrick.bouvier@linaro.org> wrote:
>
> On 11/6/24 09:49, Paolo Bonzini wrote:
> > On Wed, Nov 6, 2024 at 6:47 PM Pierrick Bouvier
> > <pierrick.bouvier@linaro.org> wrote:
> >
> >>> for (int i = 0; i < MAX_SECTIONS; ++i) {
> >>> header->section_offsets[i] = be64_to_cpu(header->section_offsets[i]);
> >>> + if (header->section_offsets[i] > OFF_MAX) {
> >>
> >> Maybe we could add a comment that sections_offsets is unsigned, as it
> >> can be confusing to read value > INT_MAX without more context.
> >
> > It does sound like OFF_MAX is related to section_offsets[], but it's
> > actually related to off_t. So the comparison is with the maximum
> > value of off_t, which is signed.
> >
> > The problem would happen even if section_offsets[] was signed (for
> > example off_t could be 32-bit).
>
> I'm a bit confused.
> It works because section_offsets[i] is unsigned. If it was signed, and
> sizeof(off_t) is 8, we can never satisfy "(int64) > INT64_MAX".
The fact that you cannot satisfy "int64 > INT64_MAX" just means that
on this system that erroneous condition is unreachable, but it could
be reachable on others. (Actually the fact that section_offsets[] is
unsigned does matter, because otherwise you'd nede a check against 0
as well. But it doesn't matter for the correctness of *this* check
against OFF_MAX).
Paolo
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] eif: cope with huge section offsets
2024-11-06 17:58 ` Paolo Bonzini
@ 2024-11-06 18:07 ` Dorjoy Chowdhury
0 siblings, 0 replies; 6+ messages in thread
From: Dorjoy Chowdhury @ 2024-11-06 18:07 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Pierrick Bouvier, qemu-devel
On Wed, Nov 6, 2024 at 11:58 PM Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> On Wed, Nov 6, 2024 at 6:54 PM Pierrick Bouvier
> <pierrick.bouvier@linaro.org> wrote:
> >
> > On 11/6/24 09:49, Paolo Bonzini wrote:
> > > On Wed, Nov 6, 2024 at 6:47 PM Pierrick Bouvier
> > > <pierrick.bouvier@linaro.org> wrote:
> > >
> > >>> for (int i = 0; i < MAX_SECTIONS; ++i) {
> > >>> header->section_offsets[i] = be64_to_cpu(header->section_offsets[i]);
> > >>> + if (header->section_offsets[i] > OFF_MAX) {
> > >>
> > >> Maybe we could add a comment that sections_offsets is unsigned, as it
> > >> can be confusing to read value > INT_MAX without more context.
> > >
> > > It does sound like OFF_MAX is related to section_offsets[], but it's
> > > actually related to off_t. So the comparison is with the maximum
> > > value of off_t, which is signed.
> > >
> > > The problem would happen even if section_offsets[] was signed (for
> > > example off_t could be 32-bit).
> >
> > I'm a bit confused.
> > It works because section_offsets[i] is unsigned. If it was signed, and
> > sizeof(off_t) is 8, we can never satisfy "(int64) > INT64_MAX".
>
> The fact that you cannot satisfy "int64 > INT64_MAX" just means that
> on this system that erroneous condition is unreachable, but it could
> be reachable on others. (Actually the fact that section_offsets[] is
> unsigned does matter, because otherwise you'd nede a check against 0
> as well. But it doesn't matter for the correctness of *this* check
> against OFF_MAX).
>
I think instead of putting the check for > OFF_MAX inside
read_eif_header, it would make more sense to put the check in the
read_eif_file function before the fseek line where we are actually
doing the seeking, no? What do you think?
Regards,
Dorjoy
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-11-06 18:07 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-06 17:42 [PATCH] eif: cope with huge section offsets Paolo Bonzini
2024-11-06 17:47 ` Pierrick Bouvier
2024-11-06 17:49 ` Paolo Bonzini
2024-11-06 17:54 ` Pierrick Bouvier
2024-11-06 17:58 ` Paolo Bonzini
2024-11-06 18:07 ` Dorjoy Chowdhury
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).