Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

greybus: Avoid fake flexible array for response data

FORTIFY_SOURCE has been ignoring 0-sized destinations while the kernel
code base has been converted to flexible arrays. In order to enforce
the 0-sized destinations (e.g. with __counted_by), the remaining 0-sized
destinations need to be handled. Instead of converting an empty struct
into using a flexible array, just directly use a pointer without any
additional indirection. Remove struct gb_bootrom_get_firmware_response
and struct gb_fw_download_fetch_firmware_response.

Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Alex Elder <elder@linaro.org>
Link: https://lore.kernel.org/r/20240304211940.it.083-kees@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Kees Cook and committed by
Greg Kroah-Hartman
7ba59ac7 34164202

+10 -14
+4 -4
drivers/staging/greybus/bootrom.c
··· 243 243 struct gb_bootrom *bootrom = gb_connection_get_data(op->connection); 244 244 const struct firmware *fw; 245 245 struct gb_bootrom_get_firmware_request *firmware_request; 246 - struct gb_bootrom_get_firmware_response *firmware_response; 247 246 struct device *dev = &op->connection->bundle->dev; 248 247 unsigned int offset, size; 249 248 enum next_request_type next_request; 249 + u8 *firmware_response; 250 250 int ret = 0; 251 251 252 252 /* Disable timeouts */ ··· 280 280 goto unlock; 281 281 } 282 282 283 - if (!gb_operation_response_alloc(op, sizeof(*firmware_response) + size, 284 - GFP_KERNEL)) { 283 + /* gb_bootrom_get_firmware_response contains only a byte array */ 284 + if (!gb_operation_response_alloc(op, size, GFP_KERNEL)) { 285 285 dev_err(dev, "%s: error allocating response\n", __func__); 286 286 ret = -ENOMEM; 287 287 goto unlock; 288 288 } 289 289 290 290 firmware_response = op->response->payload; 291 - memcpy(firmware_response->data, fw->data + offset, size); 291 + memcpy(firmware_response, fw->data + offset, size); 292 292 293 293 dev_dbg(dev, "responding with firmware (offs = %u, size = %u)\n", 294 294 offset, size);
+4 -4
drivers/staging/greybus/fw-download.c
··· 270 270 struct gb_connection *connection = op->connection; 271 271 struct fw_download *fw_download = gb_connection_get_data(connection); 272 272 struct gb_fw_download_fetch_firmware_request *request; 273 - struct gb_fw_download_fetch_firmware_response *response; 274 273 struct fw_request *fw_req; 275 274 const struct firmware *fw; 276 275 unsigned int offset, size; 277 276 u8 firmware_id; 277 + u8 *response; 278 278 int ret = 0; 279 279 280 280 if (op->request->payload_size != sizeof(*request)) { ··· 324 324 goto put_fw; 325 325 } 326 326 327 - if (!gb_operation_response_alloc(op, sizeof(*response) + size, 328 - GFP_KERNEL)) { 327 + /* gb_fw_download_fetch_firmware_response contains only a byte array */ 328 + if (!gb_operation_response_alloc(op, size, GFP_KERNEL)) { 329 329 dev_err(fw_download->parent, 330 330 "error allocating fetch firmware response\n"); 331 331 ret = -ENOMEM; ··· 333 333 } 334 334 335 335 response = op->response->payload; 336 - memcpy(response->data, fw->data + offset, size); 336 + memcpy(response, fw->data + offset, size); 337 337 338 338 dev_dbg(fw_download->parent, 339 339 "responding with firmware (offs = %u, size = %u)\n", offset,
+2 -6
include/linux/greybus/greybus_protocols.h
··· 232 232 __le32 size; 233 233 } __packed; 234 234 235 - struct gb_fw_download_fetch_firmware_response { 236 - __u8 data[0]; 237 - } __packed; 235 + /* gb_fw_download_fetch_firmware_response contains no other data */ 238 236 239 237 /* firmware download release firmware request */ 240 238 struct gb_fw_download_release_firmware_request { ··· 412 414 __le32 size; 413 415 } __packed; 414 416 415 - struct gb_bootrom_get_firmware_response { 416 - __u8 data[0]; 417 - } __packed; 417 + /* gb_bootrom_get_firmware_response contains no other data */ 418 418 419 419 /* Bootrom protocol Ready to boot request */ 420 420 struct gb_bootrom_ready_to_boot_request {