diff --git a/drivers/staging/greybus/firmware.c b/drivers/staging/greybus/firmware.c
index b16f13318be4141187dc6866dbece58ca448cfb9..4e1530fe9ae576dc84c0b1d20b41c1a44a08ab5c 100644
--- a/drivers/staging/greybus/firmware.c
+++ b/drivers/staging/greybus/firmware.c
@@ -87,6 +87,7 @@ static int gb_firmware_get_firmware(struct gb_operation *op)
 {
 	struct gb_connection *connection = op->connection;
 	struct gb_firmware *firmware = connection->private;
+	const struct firmware *fw = firmware->fw;
 	struct gb_firmware_get_firmware_request *firmware_request = op->request->payload;
 	struct gb_firmware_get_firmware_response *firmware_response;
 	struct device *dev = &connection->bundle->dev;
@@ -99,7 +100,7 @@ static int gb_firmware_get_firmware(struct gb_operation *op)
 		return -EINVAL;
 	}
 
-	if (!firmware->fw) {
+	if (!fw) {
 		dev_err(dev, "%s: firmware not available\n", __func__);
 		return -EINVAL;
 	}
@@ -107,6 +108,12 @@ static int gb_firmware_get_firmware(struct gb_operation *op)
 	offset = le32_to_cpu(firmware_request->offset);
 	size = le32_to_cpu(firmware_request->size);
 
+	if (offset >= fw->size || size > fw->size - offset) {
+		dev_warn(dev, "bad firmware request (offs = %u, size = %u)\n",
+				offset, size);
+		return -EINVAL;
+	}
+
 	if (!gb_operation_response_alloc(op, sizeof(*firmware_response) + size,
 					 GFP_KERNEL)) {
 		dev_err(dev, "%s: error allocating response\n", __func__);
@@ -114,7 +121,7 @@ static int gb_firmware_get_firmware(struct gb_operation *op)
 	}
 
 	firmware_response = op->response->payload;
-	memcpy(firmware_response->data, firmware->fw->data + offset, size);
+	memcpy(firmware_response->data, fw->data + offset, size);
 
 	return 0;
 }