Signed-off-by: Tobias Schramm <toblemi...@gmail.com>
---
 blobmsg.c | 12 ++++++++++--
 blobmsg.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/blobmsg.c b/blobmsg.c
index 10f3801..4b142e9 100644
--- a/blobmsg.c
+++ b/blobmsg.c
@@ -75,13 +75,16 @@ bool blobmsg_check_attr_safe(const struct blob_attr *attr, 
bool name, size_t len
        return blob_check_type(data, data_len, blob_type[id]);
 }
 
-int blobmsg_check_array(const struct blob_attr *attr, int type)
+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;
 
+       if (!blobmsg_check_attr_safe(attr, NULL, len))
+               return -1;
+
        switch (blobmsg_type(attr)) {
        case BLOBMSG_TYPE_TABLE:
                name = true;
@@ -97,7 +100,7 @@ int blobmsg_check_array(const struct blob_attr *attr, int 
type)
                if (type != BLOBMSG_TYPE_UNSPEC && blobmsg_type(cur) != type)
                        return -1;
 
-               if (!blobmsg_check_attr(cur, name))
+               if (!blobmsg_check_attr_safe(cur, name, rem))
                        return -1;
 
                size++;
@@ -111,6 +114,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 d17b896..81fa219 100644
--- a/blobmsg.h
+++ b/blobmsg.h
@@ -127,15 +127,62 @@ blobmsg_check_attr(const struct blob_attr *attr, bool 
name)
        return blobmsg_check_attr_safe(attr, name, blob_raw_len(attr));
 }
 
+/*
+ * blobmsg_check_attr_list: validate a list of attributes
+ *
+ * This method 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_list_safe: safely validate a list of untrusted attributes
+ *
+ * This method 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_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_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 method 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);
+
 /*
  * 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 method 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);
+static inline int
+blobmsg_check_array(const struct blob_attr *attr, int type)
+{
+       return blobmsg_check_array_safe(attr, type, blob_raw_len(attr));
+}
 
 int blobmsg_parse(const struct blobmsg_policy *policy, int policy_len,
                   struct blob_attr **tb, void *data, unsigned int len);
-- 
2.19.2


_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to