summaryrefslogtreecommitdiffstats
path: root/drivers/staging/greybus/operation.c
diff options
context:
space:
mode:
authorAlex Elder2014-12-01 14:53:07 +0100
committerGreg Kroah-Hartman2014-12-02 05:40:35 +0100
commitab3cf8dc7db6755d216173b04043b0e0cd24415b (patch)
tree3c25fbe1dc61e08524def9be2de5a202ff5888cc /drivers/staging/greybus/operation.c
parentgreybus: use outgoing flag when creating operation (diff)
downloadkernel-qcow2-linux-ab3cf8dc7db6755d216173b04043b0e0cd24415b.tar.gz
kernel-qcow2-linux-ab3cf8dc7db6755d216173b04043b0e0cd24415b.tar.xz
kernel-qcow2-linux-ab3cf8dc7db6755d216173b04043b0e0cd24415b.zip
greybus: enforce max representable message size
We represent the size of a message using a 16-bit field. It's possible for a host driver to advertise a maximum message size that's bigger than that. If that happens, reduce the host device's maximum buffer size to the maximum we can represent the first time a message is allocated. This information is actually only used by the Greybus code, but because we're modifying a value that's "owned" by the host driver, issue a warning when this limit is being imposed Ensure (at build time) that our own definition is sane as well. Signed-off-by: Alex Elder <elder@linaro.org> Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
Diffstat (limited to 'drivers/staging/greybus/operation.c')
-rw-r--r--drivers/staging/greybus/operation.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c
index 7617410f7c5a..8a023cbbf511 100644
--- a/drivers/staging/greybus/operation.c
+++ b/drivers/staging/greybus/operation.c
@@ -299,6 +299,12 @@ gb_operation_message_alloc(struct greybus_host_device *hd, u8 type,
size_t size;
u8 *buffer;
+ if (hd->buffer_size_max > GB_OPERATION_MESSAGE_SIZE_MAX) {
+ pr_warn("limiting buffer size to %u\n",
+ GB_OPERATION_MESSAGE_SIZE_MAX);
+ hd->buffer_size_max = GB_OPERATION_MESSAGE_SIZE_MAX;
+ }
+
if (message_size > hd->buffer_size_max)
return NULL;
@@ -750,6 +756,9 @@ int gb_operation_sync(struct gb_connection *connection, int type,
int gb_operation_init(void)
{
+ BUILD_BUG_ON(GB_OPERATION_MESSAGE_SIZE_MAX >
+ U16_MAX - sizeof(struct gb_operation_msg_hdr));
+
gb_operation_cache = kmem_cache_create("gb_operation_cache",
sizeof(struct gb_operation), 0, 0, NULL);
if (!gb_operation_cache)