libubox: backport additional length-checking fixes
[openwrt/staging/chunkeey.git] / package / libs / libubox / patches / 0021-blobmsg-fix-missing-length-checks.patch
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
5
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.
8
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.
11
12 Fix this by checking the raw blob length against the buffer length in
13 blobmsg_hdr_from_blob
14
15 Signed-off-by: Felix Fietkau <nbd@nbd.name>
16 ---
17 blobmsg.c | 66 +++++++++++++++++--------------------------------------
18 1 file changed, 20 insertions(+), 46 deletions(-)
19
20 --- a/blobmsg.c
21 +++ b/blobmsg.c
22 @@ -36,31 +36,18 @@ bool blobmsg_check_attr(const struct blo
23 return blobmsg_check_attr_len(attr, name, blob_raw_len(attr));
24 }
25
26 -static const struct blobmsg_hdr* blobmsg_hdr_from_blob(const struct blob_attr *attr, size_t len)
27 -{
28 - if (len < sizeof(struct blob_attr) + sizeof(struct blobmsg_hdr))
29 - return NULL;
30 -
31 - return blob_data(attr);
32 -}
33 -
34 -static bool blobmsg_hdr_valid_namelen(const struct blobmsg_hdr *hdr, size_t len)
35 -{
36 - if (len < sizeof(struct blob_attr) + sizeof(struct blobmsg_hdr) + blobmsg_namelen(hdr) + 1)
37 - return false;
38 -
39 - return true;
40 -}
41 -
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)
44 {
45 const struct blobmsg_hdr *hdr;
46 uint16_t namelen;
47
48 - hdr = blobmsg_hdr_from_blob(attr, len);
49 - if (!hdr)
50 + if (!blob_is_extended(attr))
51 + return !name;
52 +
53 + if (blob_len(attr) < sizeof(struct blobmsg_hdr))
54 return false;
55
56 + hdr = (const struct blobmsg_hdr *)blob_data(attr);
57 if (name && !hdr->namelen)
58 return false;
59
60 @@ -74,29 +61,20 @@ static bool blobmsg_check_name(const str
61 return true;
62 }
63
64 -static const char* blobmsg_check_data(const struct blob_attr *attr, size_t len, size_t *data_len)
65 -{
66 - char *limit = (char *) attr + len;
67 - const char *data;
68 -
69 - *data_len = blobmsg_data_len(attr);
70 - if (*data_len > blob_raw_len(attr))
71 - return NULL;
72 -
73 - data = blobmsg_data(attr);
74 - if (data + *data_len > limit)
75 - return NULL;
76 -
77 - return data;
78 -}
79 -
80 bool blobmsg_check_attr_len(const struct blob_attr *attr, bool name, size_t len)
81 {
82 const char *data;
83 size_t data_len;
84 int id;
85
86 - if (!blobmsg_check_name(attr, len, name))
87 + if (len < sizeof(struct blob_attr))
88 + return false;
89 +
90 + data_len = blob_raw_len(attr);
91 + if (data_len < sizeof(struct blob_attr) || data_len > len)
92 + return false;
93 +
94 + if (!blobmsg_check_name(attr, name))
95 return false;
96
97 id = blob_id(attr);
98 @@ -106,9 +84,8 @@ bool blobmsg_check_attr_len(const struct
99 if (!blob_type[id])
100 return true;
101
102 - data = blobmsg_check_data(attr, len, &data_len);
103 - if (!data)
104 - return false;
105 + data = blobmsg_data(attr);
106 + data_len = blobmsg_data_len(attr);
107
108 return blob_check_type(data, data_len, blob_type[id]);
109 }
110 @@ -212,13 +189,13 @@ int blobmsg_parse(const struct blobmsg_p
111 }
112
113 __blob_for_each_attr(attr, data, len) {
114 - hdr = blobmsg_hdr_from_blob(attr, len);
115 - if (!hdr)
116 + if (!blobmsg_check_attr_len(attr, false, len))
117 return -1;
118
119 - if (!blobmsg_hdr_valid_namelen(hdr, len))
120 - return -1;
121 + if (!blob_is_extended(attr))
122 + continue;
123
124 + hdr = blob_data(attr);
125 for (i = 0; i < policy_len; i++) {
126 if (!policy[i].name)
127 continue;
128 @@ -230,9 +207,6 @@ int blobmsg_parse(const struct blobmsg_p
129 if (blobmsg_namelen(hdr) != pslen[i])
130 continue;
131
132 - if (!blobmsg_check_attr_len(attr, true, len))
133 - return -1;
134 -
135 if (tb[i])
136 continue;
137