[systemd-commits] 2 commits - src/libsystemd
Tom Gundersen
tomegun at kemper.freedesktop.org
Sun Mar 23 14:05:56 PDT 2014
src/libsystemd/sd-rtnl/rtnl-message.c | 34 +++++++++++++++++++++++++---------
src/libsystemd/sd-rtnl/test-rtnl.c | 4 ++--
2 files changed, 27 insertions(+), 11 deletions(-)
New commits:
commit f66eeb6bb636f8061bf45e6e8e24761e87510800
Author: Tom Gundersen <teg at jklm.no>
Date: Sun Mar 23 21:44:47 2014 +0100
sd-rtnl: message - protect against SEGFAULT when reading messages
Make sure the returned data fits the datatype we requested. Otherwise return -EIO.
Also fix a broken test that this exposed.
diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index 56fb68f..23c8099 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -807,6 +807,8 @@ int sd_rtnl_message_read(sd_rtnl_message *m, unsigned short *type, void **data)
}
int rtnl_message_read_internal(sd_rtnl_message *m, unsigned short type, void **data) {
+ struct rtattr *rta;
+
assert_return(m, -EINVAL);
assert_return(m->sealed, -EPERM);
assert_return(data, -EINVAL);
@@ -816,9 +818,11 @@ int rtnl_message_read_internal(sd_rtnl_message *m, unsigned short type, void **d
if(!m->rta_offset_tb[type])
return -ENODATA;
- *data = RTA_DATA((struct rtattr *)((uint8_t *) m->hdr + m->rta_offset_tb[type]));
+ rta = (struct rtattr*)((uint8_t *) m->hdr + m->rta_offset_tb[type]);
- return 0;
+ *data = RTA_DATA(rta);
+
+ return RTA_PAYLOAD(rta);
}
int sd_rtnl_message_read_string(sd_rtnl_message *m, unsigned short type, char **data) {
@@ -828,8 +832,10 @@ int sd_rtnl_message_read_string(sd_rtnl_message *m, unsigned short type, char **
assert_return(data, -EINVAL);
r = rtnl_message_read_internal(m, type, &attr_data);
- if(r < 0)
+ if (r < 0)
return r;
+ else if (strnlen(attr_data, r) >= (size_t) r)
+ return -EIO;
*data = (char *) attr_data;
@@ -843,8 +849,10 @@ int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned short type, uint8_t *da
assert_return(data, -EINVAL);
r = rtnl_message_read_internal(m, type, &attr_data);
- if(r < 0)
+ if (r < 0)
return r;
+ else if ((size_t) r < sizeof(uint8_t))
+ return -EIO;
*data = *(uint8_t *) attr_data;
@@ -858,8 +866,10 @@ int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, uint16_t *
assert_return(data, -EINVAL);
r = rtnl_message_read_internal(m, type, &attr_data);
- if(r < 0)
+ if (r < 0)
return r;
+ else if ((size_t) r < sizeof(uint16_t))
+ return -EIO;
*data = *(uint16_t *) attr_data;
@@ -873,8 +883,10 @@ int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, uint32_t *
assert_return(data, -EINVAL);
r = rtnl_message_read_internal(m, type, &attr_data);
- if(r < 0)
+ if (r < 0)
return r;
+ else if ((size_t)r < sizeof(uint32_t))
+ return -EIO;
*data = *(uint32_t *) attr_data;
@@ -888,8 +900,10 @@ int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, str
assert_return(data, -EINVAL);
r = rtnl_message_read_internal(m, type, &attr_data);
- if(r < 0)
+ if (r < 0)
return r;
+ else if ((size_t)r < sizeof(struct ether_addr))
+ return -EIO;
memcpy(data, attr_data, sizeof(struct ether_addr));
@@ -903,8 +917,10 @@ int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct
assert_return(data, -EINVAL);
r = rtnl_message_read_internal(m, type, &attr_data);
- if(r < 0)
+ if (r < 0)
return r;
+ else if ((size_t)r < sizeof(struct in_addr))
+ return -EIO;
memcpy(data, attr_data, sizeof(struct in_addr));
diff --git a/src/libsystemd/sd-rtnl/test-rtnl.c b/src/libsystemd/sd-rtnl/test-rtnl.c
index 6ecd660..6d9159c 100644
--- a/src/libsystemd/sd-rtnl/test-rtnl.c
+++ b/src/libsystemd/sd-rtnl/test-rtnl.c
@@ -152,6 +152,7 @@ static void test_address_get(sd_rtnl *rtnl, int ifindex) {
sd_rtnl_message *m;
sd_rtnl_message *r;
struct in_addr in_data;
+ char *label;
assert_se(sd_rtnl_message_new_addr(rtnl, &m, RTM_GETADDR, ifindex, AF_INET) >= 0);
assert_se(m);
@@ -160,8 +161,7 @@ static void test_address_get(sd_rtnl *rtnl, int ifindex) {
assert_se(sd_rtnl_message_read_in_addr(r, IFA_LOCAL, &in_data) == 0);
assert_se(sd_rtnl_message_read_in_addr(r, IFA_ADDRESS, &in_data) == 0);
- assert_se(sd_rtnl_message_read_in_addr(r, IFA_LABEL, &in_data) == 0);
- assert_se(sd_rtnl_message_read_in_addr(r, IFA_CACHEINFO, &in_data) == 0);
+ assert_se(sd_rtnl_message_read_string(r, IFA_LABEL, &label) == 0);
assert_se(sd_rtnl_flush(rtnl) >= 0);
assert_se((m = sd_rtnl_message_unref(m)) == NULL);
commit a212d0dadd1e5e7bc0a57b8dfe2feb9111db2678
Author: Tom Gundersen <teg at jklm.no>
Date: Sun Mar 23 17:51:20 2014 +0100
sd-rtnl: message - don't skip parts of message when parsing
If a message type occurs repeatedly let the last one win.
Also, don't skip type == MAX.
Based on patch from: Susant Sahani <susant at redhat.com>
diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index e243c7b..56fb68f 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -1016,7 +1016,7 @@ int rtnl_message_parse(sd_rtnl_message *m,
for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
type = rta->rta_type;
- if (type < max && !tb[type])
+ if (type <= max)
tb[type] = (uint8_t *) rta - (uint8_t *) m->hdr;
}
More information about the systemd-commits
mailing list