message: allocate the correct size of kmsg->iov
authorDaniel Mack <daniel@zonque.org>
Sat, 20 Dec 2014 23:12:58 +0000 (00:12 +0100)
committerDaniel Mack <daniel@zonque.org>
Sat, 20 Dec 2014 23:12:58 +0000 (00:12 +0100)
Allocating (n_vecs + n_memfds) number of elements in kmsg->iov
is likely too much. Calculate how many we really need.

Signed-off-by: Daniel Mack <daniel@zonque.org>
message.c

index 7cda69909a7a538e526241b03e33d4115c4b45b0..a90ecd86b34ecce8ac62fdad15939d0057a5871c 100644 (file)
--- a/message.c
+++ b/message.c
@@ -225,6 +225,8 @@ static int kdbus_msg_scan_items(struct kdbus_kmsg *kmsg,
                        break;
                case KDBUS_ITEM_PAYLOAD_MEMFD:
                        ++n_memfds;
+                       if (item->memfd.size % 8)
+                               ++n_vecs;
                        break;
                default:
                        break;
@@ -236,8 +238,10 @@ static int kdbus_msg_scan_items(struct kdbus_kmsg *kmsg,
                res->data = kcalloc(n, sizeof(*res->data), GFP_KERNEL);
                if (!res->data)
                        return -ENOMEM;
+       }
 
-               kmsg->iov = kcalloc(n, sizeof(*kmsg->iov), GFP_KERNEL);
+       if (n_vecs > 0) {
+               kmsg->iov = kcalloc(n_vecs, sizeof(*kmsg->iov), GFP_KERNEL);
                if (!kmsg->iov)
                        return -ENOMEM;
        }
@@ -293,6 +297,7 @@ static int kdbus_msg_scan_items(struct kdbus_kmsg *kmsg,
                        struct kdbus_msg_data *d = res->data + res->data_count;
                        u64 start = item->memfd.start;
                        u64 size = item->memfd.size;
+                       size_t pad = size % 8;
                        int seals, mask;
                        struct file *f;
 
@@ -308,11 +313,11 @@ static int kdbus_msg_scan_items(struct kdbus_kmsg *kmsg,
                        if (!f)
                                return -EBADF;
 
-                       if (size % 8) {
+                       if (pad) {
                                iov->iov_base = (char __user *)zeros;
-                               iov->iov_len = size % 8;
+                               iov->iov_len = pad;
 
-                               kmsg->pool_size += iov->iov_len;
+                               kmsg->pool_size += pad;
                                ++kmsg->iov_count;
                        }