aboutsummaryrefslogtreecommitdiffstats
path: root/package/libs/libubox/patches/0021-blobmsg-fix-missing-length-checks.patch
blob: 1f72cc0144212ef0e7d59999aed9c4b2d0c6aa22 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
From 66195aee50424cbda0c2d858014e4cc58a2dc029 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name>
Date: Mon, 25 May 2020 12:40:04 +0200
Subject: [PATCH] blobmsg: fix missing length checks

blobmsg_check_attr_len was calling blobmsg_check_data for some, but not all
attribute types. These checks was missing for arrays and tables.

Additionally, the length check in blobmsg_check_data was a bit off, since
it was comparing the blobmsg data length against the raw blob attr length.

Fix this by checking the raw blob length against the buffer length in
blobmsg_hdr_from_blob

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
 blobmsg.c | 66 +++++++++++++++++--------------------------------------
 1 file changed, 20 insertions(+), 46 deletions(-)

--- a/blobmsg.c
+++ b/blobmsg.c
@@ -36,31 +36,18 @@ bool blobmsg_check_attr(const struct blo
 	return blobmsg_check_attr_len(attr, name, blob_raw_len(attr));
 }
 
-static const struct blobmsg_hdr* blobmsg_hdr_from_blob(const struct blob_attr *attr, size_t len)
-{
-	if (len < sizeof(struct blob_attr) + sizeof(struct blobmsg_hdr))
-		return NULL;
-
-	return blob_data(attr);
-}
-
-static bool blobmsg_hdr_valid_namelen(const struct blobmsg_hdr *hdr, size_t len)
-{
-	if (len < sizeof(struct blob_attr) + sizeof(struct blobmsg_hdr) + blobmsg_namelen(hdr) + 1)
-		return false;
-
-	return true;
-}
-
-static bool blobmsg_check_name(const struct blob_attr *attr, size_t len, bool name)
+static bool blobmsg_check_name(const struct blob_attr *attr, bool name)
 {
 	const struct blobmsg_hdr *hdr;
 	uint16_t namelen;
 
-	hdr = blobmsg_hdr_from_blob(attr, len);
-	if (!hdr)
+	if (!blob_is_extended(attr))
+		return !name;
+
+	if (blob_len(attr) < sizeof(struct blobmsg_hdr))
 		return false;
 
+	hdr = (const struct blobmsg_hdr *)blob_data(attr);
 	if (name && !hdr->namelen)
 		return false;
 
@@ -74,29 +61,20 @@ static bool blobmsg_check_name(const str
 	return true;
 }
 
-static const char* blobmsg_check_data(const struct blob_attr *attr, size_t len, size_t *data_len)
-{
-	char *limit = (char *) attr + len;
-	const char *data;
-
-	*data_len = blobmsg_data_len(attr);
-	if (*data_len > blob_raw_len(attr))
-		return NULL;
-
-	data = blobmsg_data(attr);
-	if (data + *data_len > limit)
-		return NULL;
-
-	return data;
-}
-
 bool blobmsg_check_attr_len(const struct blob_attr *attr, bool name, size_t len)
 {
 	const char *data;
 	size_t data_len;
 	int id;
 
-	if (!blobmsg_check_name(attr, len, name))
+	if (len < sizeof(struct blob_attr))
+		return false;
+
+	data_len = blob_raw_len(attr);
+	if (data_len < sizeof(struct blob_attr) || data_len > len)
+		return false;
+
+	if (!blobmsg_check_name(attr, name))
 		return false;
 
 	id = blob_id(attr);
@@ -106,9 +84,8 @@ bool blobmsg_check_attr_len(const struct
 	if (!blob_type[id])
 		return true;
 
-	data = blobmsg_check_data(attr, len, &data_len);
-	if (!data)
-		return false;
+	data = blobmsg_data(attr);
+	data_len = blobmsg_data_len(attr);
 
 	return blob_check_type(data, data_len, blob_type[id]);
 }
@@ -212,13 +189,13 @@ int blobmsg_parse(const struct blobmsg_p
 	}
 
 	__blob_for_each_attr(attr, data, len) {
-		hdr = blobmsg_hdr_from_blob(attr, len);
-		if (!hdr)
+		if (!blobmsg_check_attr_len(attr, false, len))
 			return -1;
 
-		if (!blobmsg_hdr_valid_namelen(hdr, len))
-			return -1;
+		if (!blob_is_extended(attr))
+			continue;
 
+		hdr = blob_data(attr);
 		for (i = 0; i < policy_len; i++) {
 			if (!policy[i].name)
 				continue;
@@ -230,9 +207,6 @@ int blobmsg_parse(const struct blobmsg_p
 			if (blobmsg_namelen(hdr) != pslen[i])
 				continue;
 
-			if (!blobmsg_check_attr_len(attr, true, len))
-				return -1;
-
 			if (tb[i])
 				continue;