forked from pool/systemd
112 lines
4.4 KiB
Diff
112 lines
4.4 KiB
Diff
Backport of 7ca1d31964a2553f7bd011bc10ac42e0ebc1f975 Mon Sep 17 00:00:00 2001
|
|
From: Tom Gundersen <teg@jklm.no>
|
|
Date: Fri, 2 May 2014 22:29:18 +0200
|
|
Subject: [PATCH] sd-rtnl-message: append - fix uninitialized memory
|
|
|
|
We were not properly clearing the padding at the front of some containers.
|
|
---
|
|
src/libsystemd/sd-rtnl/rtnl-message.c | 42 +++++++++++++++++++++-------------
|
|
1 file changed, 27 insertions(+), 15 deletions(-)
|
|
|
|
--- src/libsystemd/sd-rtnl/rtnl-message.c
|
|
+++ src/libsystemd/sd-rtnl/rtnl-message.c 2014-05-05 13:33:01.998235340 +0000
|
|
@@ -314,24 +314,28 @@ int sd_rtnl_message_link_get_flags(sd_rt
|
|
/* If successful the updated message will be correctly aligned, if
|
|
unsuccessful the old message is untouched. */
|
|
static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data, size_t data_length) {
|
|
- uint32_t rta_length, message_length;
|
|
+ uint32_t rta_length;
|
|
+ size_t message_length, padding_length;
|
|
struct nlmsghdr *new_hdr;
|
|
struct rtattr *rta;
|
|
char *padding;
|
|
unsigned i;
|
|
+ int offset;
|
|
|
|
assert(m);
|
|
assert(m->hdr);
|
|
assert(!m->sealed);
|
|
assert(NLMSG_ALIGN(m->hdr->nlmsg_len) == m->hdr->nlmsg_len);
|
|
- assert(!data || data_length > 0);
|
|
- assert(data || m->n_containers < RTNL_CONTAINER_DEPTH);
|
|
+ assert(!data || data_length);
|
|
+
|
|
+ /* get offset of the new attribute */
|
|
+ offset = m->hdr->nlmsg_len;
|
|
|
|
/* get the size of the new rta attribute (with padding at the end) */
|
|
rta_length = RTA_LENGTH(data_length);
|
|
|
|
/* get the new message size (with padding at the end) */
|
|
- message_length = m->hdr->nlmsg_len + RTA_ALIGN(rta_length);
|
|
+ message_length = offset + RTA_ALIGN(rta_length);
|
|
|
|
/* realloc to fit the new attribute */
|
|
new_hdr = realloc(m->hdr, message_length);
|
|
@@ -340,32 +344,35 @@ static int add_rtattr(sd_rtnl_message *m
|
|
m->hdr = new_hdr;
|
|
|
|
/* get pointer to the attribute we are about to add */
|
|
- rta = (struct rtattr *) ((uint8_t *) m->hdr + m->hdr->nlmsg_len);
|
|
+ rta = (struct rtattr *) ((uint8_t *) m->hdr + offset);
|
|
|
|
/* if we are inside containers, extend them */
|
|
for (i = 0; i < m->n_containers; i++)
|
|
- GET_CONTAINER(m, i)->rta_len += message_length - m->hdr->nlmsg_len;
|
|
+ GET_CONTAINER(m, i)->rta_len += message_length - offset;
|
|
|
|
/* fill in the attribute */
|
|
rta->rta_type = type;
|
|
rta->rta_len = rta_length;
|
|
- if (!data) {
|
|
- /* this is the start of a new container */
|
|
- m->container_offsets[m->n_containers ++] = m->hdr->nlmsg_len;
|
|
- } else {
|
|
+ if (data)
|
|
/* we don't deal with the case where the user lies about the type
|
|
* and gives us too little data (so don't do that)
|
|
- */
|
|
+ */
|
|
padding = mempcpy(RTA_DATA(rta), data, data_length);
|
|
- /* make sure also the padding at the end of the message is initialized */
|
|
- memzero(padding,
|
|
- (uint8_t *) m->hdr + message_length - (uint8_t *) padding);
|
|
+ else {
|
|
+ /* if no data was passed, make sure we still initialize the padding
|
|
+ note that we can have data_length > 0 (used by some containers) */
|
|
+ padding = RTA_DATA(rta);
|
|
+ data_length = 0;
|
|
}
|
|
|
|
+ /* make sure also the padding at the end of the message is initialized */
|
|
+ padding_length = (uint8_t*)m->hdr + message_length - (uint8_t*)padding;
|
|
+ memzero(padding, padding_length);
|
|
+
|
|
/* update message size */
|
|
m->hdr->nlmsg_len = message_length;
|
|
|
|
- return 0;
|
|
+ return offset;
|
|
}
|
|
|
|
int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const char *data) {
|
|
@@ -498,6 +505,7 @@ int sd_rtnl_message_append_u32(sd_rtnl_m
|
|
|
|
assert_return(m, -EINVAL);
|
|
assert_return(!m->sealed, -EPERM);
|
|
+ assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -ERANGE);
|
|
|
|
r = sd_rtnl_message_get_type(m, &rtm_type);
|
|
if (r < 0)
|
|
@@ -548,6 +556,10 @@ int sd_rtnl_message_append_u32(sd_rtnl_m
|
|
if (r < 0)
|
|
return r;
|
|
|
|
+ m->container_offsets[m->n_containers ++] = r;
|
|
+
|
|
+ m->container_offsets[m->n_containers ++] = r;
|
|
+
|
|
return 0;
|
|
}
|
|
|