[OpenWrt-Devel] [PATCH 2/3] Replace use of blobmsg_check_attr by blobmsg_check_attr_safe

Yousong Zhou yszhou4tech at gmail.com
Thu Nov 22 23:05:52 EST 2018


On Thu, 22 Nov 2018 at 10:01, Tobias Schramm <tobleminer at gmail.com> wrote:
>
> blobmsg_check_attr_safe adds a length limit specifying the max offset from attr that
> can be read safely
>
> Signed-off-by: Tobias Schramm <tobleminer at gmail.com>
> ---
>  blobmsg.c | 27 ++++++++++++++++++++++-----
>  blobmsg.h |  2 ++
>  2 files changed, 24 insertions(+), 5 deletions(-)
>
> diff --git a/blobmsg.c b/blobmsg.c
> index 8019c45..dd4b506 100644
> --- a/blobmsg.c
> +++ b/blobmsg.c
> @@ -32,18 +32,33 @@ blobmsg_namelen(const struct blobmsg_hdr *hdr)
>  }
>
>  bool blobmsg_check_attr(const struct blob_attr *attr, bool name)
> +{
> +       return blobmsg_check_attr_safe(attr, name, blob_raw_len(attr));
> +}
> +
> +bool blobmsg_check_attr_safe(const struct blob_attr *attr, bool name, size_t len)
>  {
>         const struct blobmsg_hdr *hdr;
>         const char *data;
> -       int id, len;
> +       char *limit = (char*)attr + len;
> +       int id, data_len;
> +
> +       if (len < sizeof(struct blob_attr))
> +               return false;
>
>         if (blob_len(attr) < sizeof(struct blobmsg_hdr))
>                 return false;
>
> +       if (len < sizeof(struct blobmsg_hdr))
> +               return false;
> +
>         hdr = (void *) attr->data;
>         if (!hdr->namelen && name)
>                 return false;
>
> +       if ((char*)hdr->name + blobmsg_namelen(hdr) > limit)
> +               return false;
> +
>         if (blobmsg_namelen(hdr) > blob_len(attr) - sizeof(struct blobmsg_hdr))
>                 return false;
>
> @@ -51,8 +66,10 @@ bool blobmsg_check_attr(const struct blob_attr *attr, bool name)
>                 return false;
>
>         id = blob_id(attr);
> -       len = blobmsg_data_len(attr);
> +       data_len = blobmsg_data_len(attr);
>         data = blobmsg_data(attr);
> +       if (data_len < 0 || data + data_len > limit)
> +               return false;
>
>         if (id > BLOBMSG_TYPE_LAST)
>                 return false;
> @@ -60,7 +77,7 @@ bool blobmsg_check_attr(const struct blob_attr *attr, bool name)
>         if (!blob_type[id])
>                 return true;
>
> -       return blob_check_type(data, len, blob_type[id]);
> +       return blob_check_type(data, data_len, blob_type[id]);
>  }
>
>  int blobmsg_check_array(const struct blob_attr *attr, int type)
> @@ -111,7 +128,7 @@ int blobmsg_parse_array(const struct blobmsg_policy *policy, int policy_len,
>                     blob_id(attr) != policy[i].type)
>                         continue;
>
> -               if (!blobmsg_check_attr(attr, false))
> +               if (!blobmsg_check_attr_safe(attr, false, len))

This cal happens inside __blob_for_each_attr() which should already
have invariant (blob_pad_len(attr) <= len) hold

>                         return -1;
>
>                 if (tb[i])
> @@ -158,7 +175,7 @@ int blobmsg_parse(const struct blobmsg_policy *policy, int policy_len,
>                         if (blobmsg_namelen(hdr) != pslen[i])
>                                 continue;
>
> -                       if (!blobmsg_check_attr(attr, true))
> +                       if (!blobmsg_check_attr_safe(attr, true, len))
>                                 return -1;
>

ditto
                yousong

_______________________________________________
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