1 From 66195aee50424cbda0c2d858014e4cc58a2dc029 Mon Sep 17 00:00:00 2001
2 From: Felix Fietkau <nbd@nbd.name>
3 Date: Mon, 25 May 2020 12:40:04 +0200
4 Subject: [PATCH] blobmsg: fix missing length checks
6 blobmsg_check_attr_len was calling blobmsg_check_data for some, but not all
7 attribute types. These checks was missing for arrays and tables.
9 Additionally, the length check in blobmsg_check_data was a bit off, since
10 it was comparing the blobmsg data length against the raw blob attr length.
12 Fix this by checking the raw blob length against the buffer length in
15 Signed-off-by: Felix Fietkau <nbd@nbd.name>
17 blobmsg.c | 66 +++++++++++++++++--------------------------------------
18 1 file changed, 20 insertions(+), 46 deletions(-)
22 @@ -36,31 +36,18 @@ bool blobmsg_check_attr(const struct blo
23 return blobmsg_check_attr_len(attr, name, blob_raw_len(attr));
26 -static const struct blobmsg_hdr* blobmsg_hdr_from_blob(const struct blob_attr *attr, size_t len)
28 - if (len < sizeof(struct blob_attr) + sizeof(struct blobmsg_hdr))
31 - return blob_data(attr);
34 -static bool blobmsg_hdr_valid_namelen(const struct blobmsg_hdr *hdr, size_t len)
36 - if (len < sizeof(struct blob_attr) + sizeof(struct blobmsg_hdr) + blobmsg_namelen(hdr) + 1)
42 -static bool blobmsg_check_name(const struct blob_attr *attr, size_t len, bool name)
43 +static bool blobmsg_check_name(const struct blob_attr *attr, bool name)
45 const struct blobmsg_hdr *hdr;
48 - hdr = blobmsg_hdr_from_blob(attr, len);
50 + if (!blob_is_extended(attr))
53 + if (blob_len(attr) < sizeof(struct blobmsg_hdr))
56 + hdr = (const struct blobmsg_hdr *)blob_data(attr);
57 if (name && !hdr->namelen)
60 @@ -74,29 +61,20 @@ static bool blobmsg_check_name(const str
64 -static const char* blobmsg_check_data(const struct blob_attr *attr, size_t len, size_t *data_len)
66 - char *limit = (char *) attr + len;
69 - *data_len = blobmsg_data_len(attr);
70 - if (*data_len > blob_raw_len(attr))
73 - data = blobmsg_data(attr);
74 - if (data + *data_len > limit)
80 bool blobmsg_check_attr_len(const struct blob_attr *attr, bool name, size_t len)
86 - if (!blobmsg_check_name(attr, len, name))
87 + if (len < sizeof(struct blob_attr))
90 + data_len = blob_raw_len(attr);
91 + if (data_len < sizeof(struct blob_attr) || data_len > len)
94 + if (!blobmsg_check_name(attr, name))
98 @@ -106,9 +84,8 @@ bool blobmsg_check_attr_len(const struct
102 - data = blobmsg_check_data(attr, len, &data_len);
105 + data = blobmsg_data(attr);
106 + data_len = blobmsg_data_len(attr);
108 return blob_check_type(data, data_len, blob_type[id]);
110 @@ -212,13 +189,13 @@ int blobmsg_parse(const struct blobmsg_p
113 __blob_for_each_attr(attr, data, len) {
114 - hdr = blobmsg_hdr_from_blob(attr, len);
116 + if (!blobmsg_check_attr_len(attr, false, len))
119 - if (!blobmsg_hdr_valid_namelen(hdr, len))
121 + if (!blob_is_extended(attr))
124 + hdr = blob_data(attr);
125 for (i = 0; i < policy_len; i++) {
128 @@ -230,9 +207,6 @@ int blobmsg_parse(const struct blobmsg_p
129 if (blobmsg_namelen(hdr) != pslen[i])
132 - if (!blobmsg_check_attr_len(attr, true, len))