The firmware container allocations passed cont->size + sizeof(int) to
kzalloc(), which was wrong: the struct contains an int len followed by a
u8 data[] flexible array. It ended up being the same as the struct's
size is only the int member but still wrong.
Use the modern struct_size helper for this.
Add __counted_by for extra runtime analysis.
Assisted-by: Claude:Opus-4.7
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Link: https://patch.msgid.link/20260523011749.101555-1-rosenp@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
static int aw88081_request_firmware_file(struct aw88081 *aw88081)
{
const struct firmware *cont = NULL;
+ struct aw_container *aw_cfg;
int ret;
aw88081->aw_pa->fw_status = AW88081_DEV_FW_FAILED;
dev_dbg(aw88081->aw_pa->dev, "loaded %s - size: %zu\n",
AW88081_ACF_FILE, cont ? cont->size : 0);
- aw88081->aw_cfg = devm_kzalloc(aw88081->aw_pa->dev, cont->size + sizeof(int), GFP_KERNEL);
- if (!aw88081->aw_cfg) {
+ aw_cfg = devm_kzalloc(aw88081->aw_pa->dev, struct_size(aw_cfg, data, cont->size), GFP_KERNEL);
+ if (!aw_cfg) {
release_firmware(cont);
return -ENOMEM;
}
- aw88081->aw_cfg->len = (int)cont->size;
- memcpy(aw88081->aw_cfg->data, cont->data, cont->size);
+ aw_cfg->len = (int)cont->size;
+ memcpy(aw_cfg->data, cont->data, cont->size);
+
+ aw88081->aw_cfg = aw_cfg;
+
release_firmware(cont);
ret = aw88395_dev_load_acf_check(aw88081->aw_pa, aw88081->aw_cfg);
static int aw88261_request_firmware_file(struct aw88261 *aw88261)
{
const struct firmware *cont = NULL;
+ struct aw_container *aw_cfg;
const char *fw_name;
int ret;
dev_info(aw88261->aw_pa->dev, "loaded %s - size: %zu\n",
fw_name, cont ? cont->size : 0);
- aw88261->aw_cfg = devm_kzalloc(aw88261->aw_pa->dev, cont->size + sizeof(int), GFP_KERNEL);
- if (!aw88261->aw_cfg) {
+ aw_cfg = devm_kzalloc(aw88261->aw_pa->dev, struct_size(aw_cfg, data, cont->size), GFP_KERNEL);
+ if (!aw_cfg) {
release_firmware(cont);
return -ENOMEM;
}
- aw88261->aw_cfg->len = (int)cont->size;
- memcpy(aw88261->aw_cfg->data, cont->data, cont->size);
+ aw_cfg->len = (int)cont->size;
+ memcpy(aw_cfg->data, cont->data, cont->size);
release_firmware(cont);
+ aw88261->aw_cfg = aw_cfg;
+
ret = aw88395_dev_load_acf_check(aw88261->aw_pa, aw88261->aw_cfg);
if (ret) {
dev_err(aw88261->aw_pa->dev, "load [%s] failed !", fw_name);
static int aw88395_request_firmware_file(struct aw88395 *aw88395)
{
const struct firmware *cont = NULL;
+ struct aw_container *aw_cfg;
int ret;
aw88395->aw_pa->fw_status = AW88395_DEV_FW_FAILED;
dev_info(aw88395->aw_pa->dev, "loaded %s - size: %zu\n",
AW88395_ACF_FILE, cont ? cont->size : 0);
- aw88395->aw_cfg = devm_kzalloc(aw88395->aw_pa->dev, cont->size + sizeof(int), GFP_KERNEL);
- if (!aw88395->aw_cfg) {
+ aw_cfg = devm_kzalloc(aw88395->aw_pa->dev, struct_size(aw_cfg, data, cont->size), GFP_KERNEL);
+ if (!aw_cfg) {
release_firmware(cont);
return -ENOMEM;
}
- aw88395->aw_cfg->len = (int)cont->size;
- memcpy(aw88395->aw_cfg->data, cont->data, cont->size);
+ aw_cfg->len = (int)cont->size;
+ memcpy(aw_cfg->data, cont->data, cont->size);
release_firmware(cont);
+ aw88395->aw_cfg = aw_cfg;
+
ret = aw88395_dev_load_acf_check(aw88395->aw_pa, aw88395->aw_cfg);
if (ret < 0) {
dev_err(aw88395->aw_pa->dev, "Load [%s] failed ....!", AW88395_ACF_FILE);
struct aw_container {
int len;
- u8 data[];
+ u8 data[] __counted_by(len);
};
struct aw_device {