[OpenWrt-Devel] [PATCH v2 3/3] Add _safe variants for all attribute checking methods
Tobias Schramm
tobleminer at gmail.com
Fri Nov 23 01:27:47 EST 2018
Signed-off-by: Tobias Schramm <tobleminer at gmail.com>
---
blobmsg.c | 15 ++++++++++++---
blobmsg.h | 40 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/blobmsg.c b/blobmsg.c
index dd4b506..97a9a0b 100644
--- a/blobmsg.c
+++ b/blobmsg.c
@@ -81,10 +81,14 @@ bool blobmsg_check_attr_safe(const struct blob_attr *attr, bool name, size_t len
}
int blobmsg_check_array(const struct blob_attr *attr, int type)
+{
+ return blobmsg_check_array_safe(attr, type, blob_raw_len(attr));
+}
+
+int blobmsg_check_array_safe(const struct blob_attr *attr, int type, size_t len)
{
struct blob_attr *cur;
bool name;
- int rem;
int size = 0;
switch (blobmsg_type(attr)) {
@@ -98,11 +102,11 @@ int blobmsg_check_array(const struct blob_attr *attr, int type)
return -1;
}
- blobmsg_for_each_attr(cur, attr, rem) {
+ __blobmsg_for_each_attr(cur, attr, len) {
if (type != BLOBMSG_TYPE_UNSPEC && blobmsg_type(cur) != type)
return -1;
- if (!blobmsg_check_attr(cur, name))
+ if (!blobmsg_check_attr_safe(cur, name, len))
return -1;
size++;
@@ -116,6 +120,11 @@ bool blobmsg_check_attr_list(const struct blob_attr *attr, int type)
return blobmsg_check_array(attr, type) >= 0;
}
+bool blobmsg_check_attr_list_safe(const struct blob_attr *attr, int type, size_t len)
+{
+ return blobmsg_check_array_safe(attr, type, len) >= 0;
+}
+
int blobmsg_parse_array(const struct blobmsg_policy *policy, int policy_len,
struct blob_attr **tb, void *data, unsigned int len)
{
diff --git a/blobmsg.h b/blobmsg.h
index b1dec4e..30b70bc 100644
--- a/blobmsg.h
+++ b/blobmsg.h
@@ -123,16 +123,50 @@ bool blobmsg_check_attr(const struct blob_attr *attr, bool name);
*/
bool blobmsg_check_attr_safe(const struct blob_attr *attr, bool name, size_t len);
+/*
+ * blobmsg_check_attr: validate a list of attributes
+ *
+ * This methods may be used with trusted data only. Providing
+ * malformed blobs will cause out of bounds memory access and
+ * crash your program or get your device 0wned.
+ */
bool blobmsg_check_attr_list(const struct blob_attr *attr, int type);
+/*
+ * blobmsg_check_attr_safe: safely validate a list of untrusted attributes
+ *
+ * This methods is a safe implementation of blobmsg_check_attr_list.
+ * It will limit all memory access performed on the blob to the
+ * range [attr, attr + len] (upper bound non inclusive) and is
+ * thus suited for checking untrusted blob attributes.
+ */
+bool blobmsg_check_attr_list_safe(const struct blob_attr *attr, int type, size_t len);
+
/*
* blobmsg_check_array: validate array/table and return size
*
* Checks if all elements of an array or table are valid and have
* the specified type. Returns the number of elements in the array
+ *
+ * This methods may be used with trusted data only. Providing
+ * malformed blobs will cause out of bounds memory access and
+ * crash your program or get your device 0wned.
*/
int blobmsg_check_array(const struct blob_attr *attr, int type);
+/*
+ * blobmsg_check_array: safely validate untrusted array/table and return size
+ *
+ * Checks if all elements of an array or table are valid and have
+ * the specified type. Returns the number of elements in the array
+ *
+ * This methods is a safe implementation of blobmsg_check_array.
+ * It will limit all memory access performed on the blob to the
+ * range [attr, attr + len] (upper bound non inclusive) and is
+ * thus suited for checking untrusted blob attributes.
+ */
+int blobmsg_check_array_safe(const struct blob_attr *attr, int type, size_t len);
+
int blobmsg_parse(const struct blobmsg_policy *policy, int policy_len,
struct blob_attr **tb, void *data, unsigned int len);
int blobmsg_parse_array(const struct blobmsg_policy *policy, int policy_len,
@@ -288,4 +322,10 @@ int blobmsg_printf(struct blob_buf *buf, const char *name, const char *format, .
(blob_pad_len(pos) >= sizeof(struct blob_attr)); \
rem -= blob_pad_len(pos), pos = blob_next(pos))
+#define __blobmsg_for_each_attr(pos, attr, rem) \
+ for (pos = (struct blob_attr *) (attr ? blobmsg_data(attr) : NULL); \
+ rem >= sizeof(struct blob_attr) && (blob_pad_len(pos) <= rem) && \
+ (blob_pad_len(pos) >= sizeof(struct blob_attr)); \
+ rem -= blob_pad_len(pos), pos = blob_next(pos))
+
#endif
--
2.19.1
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel
More information about the openwrt-devel
mailing list