Coverity reported a 1 byte overrun in scsi_property_set_loadparm
(CID 15657462). Since loadparam[] length is known, simply directly
allocate it in the device state.
Fixes: 429442e52d ("hw: Add 'loadparm' property to scsi disk devices")
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/scsi/scsi-disk.c | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 96a09fe170..f6d6b7c1ea 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -38,6 +38,7 @@
#include "hw/block/block.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
+#include "hw/s390x/ipl/qipl.h"
#include "sysemu/dma.h"
#include "sysemu/sysemu.h"
#include "qemu/cutils.h"
@@ -112,7 +113,7 @@ struct SCSIDiskState {
char *vendor;
char *product;
char *device_id;
- char *loadparm; /* only for s390x */
+ char loadparm[LOADPARM_LEN]; /* only for s390x */
bool tray_open;
bool tray_locked;
/*
@@ -3145,19 +3146,12 @@ static char *scsi_property_get_loadparm(Object *obj, Error **errp)
static void scsi_property_set_loadparm(Object *obj, const char *value,
Error **errp)
{
- char *lp_str;
-
if (object_property_get_int(obj, "bootindex", NULL) < 0) {
error_setg(errp, "'loadparm' is only valid for boot devices");
return;
}
- lp_str = g_malloc0(strlen(value));
- if (!qdev_prop_sanitize_s390x_loadparm(lp_str, value, errp)) {
- g_free(lp_str);
- return;
- }
- SCSI_DISK_BASE(obj)->loadparm = lp_str;
+ qdev_prop_sanitize_s390x_loadparm(SCSI_DISK_BASE(obj)->loadparm, value, errp);
}
static void scsi_property_add_specifics(DeviceClass *dc)
--
2.45.2
Am 20.11.2024 um 09:53 hat Philippe Mathieu-Daudé geschrieben:
> Coverity reported a 1 byte overrun in scsi_property_set_loadparm
> (CID 15657462). Since loadparam[] length is known, simply directly
> allocate it in the device state.
>
> Fixes: 429442e52d ("hw: Add 'loadparm' property to scsi disk devices")
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Paolo already sent a pull request for a different fix (just allocating
one byte more). I think that's the better approach because other users
might expect the string to actually be null terminated.
Such as scsi_property_get_loadparm(), which you forgot to update:
static char *scsi_property_get_loadparm(Object *obj, Error **errp)
{
return g_strdup(SCSI_DISK_BASE(obj)->loadparm);
}
Kevin
On 20/11/24 10:20, Kevin Wolf wrote:
> Am 20.11.2024 um 09:53 hat Philippe Mathieu-Daudé geschrieben:
>> Coverity reported a 1 byte overrun in scsi_property_set_loadparm
>> (CID 15657462). Since loadparam[] length is known, simply directly
>> allocate it in the device state.
>>
>> Fixes: 429442e52d ("hw: Add 'loadparm' property to scsi disk devices")
>> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>
> Paolo already sent a pull request for a different fix (just allocating
> one byte more). I think that's the better approach because other users
> might expect the string to actually be null terminated.
>
> Such as scsi_property_get_loadparm(), which you forgot to update:
>
> static char *scsi_property_get_loadparm(Object *obj, Error **errp)
> {
> return g_strdup(SCSI_DISK_BASE(obj)->loadparm);
> }
Yeah I missed that.
Maybe consider the first patch as cleanup for 10.0? I can repost later.
Regards,
Phil.
On 11/20/24 09:53, Philippe Mathieu-Daudé wrote:
> @@ -112,7 +113,7 @@ struct SCSIDiskState {
> char *vendor;
> char *product;
> char *device_id;
> - char *loadparm; /* only for s390x */
> + char loadparm[LOADPARM_LEN]; /* only for s390x */
You would need a +1 here because of
static char *scsi_property_get_loadparm(Object *obj, Error **errp)
{
return g_strdup(SCSI_DISK_BASE(obj)->loadparm);
}
expecting NUL-termination as well.
> - lp_str = g_malloc0(strlen(value));
I have sent a pull request that simply adds the +1 here, also because...
> - if (!qdev_prop_sanitize_s390x_loadparm(lp_str, value, errp)) {
> - g_free(lp_str);
> - return;
> - }
> - SCSI_DISK_BASE(obj)->loadparm = lp_str;
> + qdev_prop_sanitize_s390x_loadparm(SCSI_DISK_BASE(obj)->loadparm, value, errp);
... this would overwrite SCSI_DISK_BASE(obj)->loadparm in case of error.
Note how the code is setting loadparm only after a successful
qdev_prop_sanitize_s390x_loadparm. That's not a problem in practice,
because failing to set a property is usually fatal, but not good style
either.
Thanks,
Paolo
On 20/11/24 10:10, Paolo Bonzini wrote:
> On 11/20/24 09:53, Philippe Mathieu-Daudé wrote:
>> @@ -112,7 +113,7 @@ struct SCSIDiskState {
>> char *vendor;
>> char *product;
>> char *device_id;
>> - char *loadparm; /* only for s390x */
>> + char loadparm[LOADPARM_LEN]; /* only for s390x */
>
> You would need a +1 here because of
>
> static char *scsi_property_get_loadparm(Object *obj, Error **errp)
> {
> return g_strdup(SCSI_DISK_BASE(obj)->loadparm);
> }
>
> expecting NUL-termination as well.
>
>> - lp_str = g_malloc0(strlen(value));
>
> I have sent a pull request that simply adds the +1 here, also because...
>
>> - if (!qdev_prop_sanitize_s390x_loadparm(lp_str, value, errp)) {
>> - g_free(lp_str);
>> - return;
>> - }
>> - SCSI_DISK_BASE(obj)->loadparm = lp_str;
>> + qdev_prop_sanitize_s390x_loadparm(SCSI_DISK_BASE(obj)->loadparm,
>> value, errp);
>
> ... this would overwrite SCSI_DISK_BASE(obj)->loadparm in case of error.
> Note how the code is setting loadparm only after a successful
> qdev_prop_sanitize_s390x_loadparm. That's not a problem in practice,
> because failing to set a property is usually fatal, but not good style
> either.
I guess I was not well awake :) Please disregard this patch.
© 2016 - 2026 Red Hat, Inc.