[OpenWrt-Devel] [PATCH 2/3] Replace use of blobmsg_check_attr by blobmsg_check_attr_safe
Tobias Schramm
tobleminer at gmail.com
Fri Nov 23 00:52:14 EST 2018
While I do agree that we could safely call blobmsg_check_attr I think
that - to the uninitiated reader - calling blobmsg_check_attr_safe
shows a lot more clearly that the methods in question are actually
safe to use with potentially broken /untrusted input. Otherwise you
would have to look at the implementation of __blob_for_each_attr and
understand it first. Also I don't see any downsides to calling
blobmsg_check_attr_safe over blobmsg_check_attr.
Am Fr., 23. Nov. 2018 um 05:06 Uhr schrieb Yousong Zhou <yszhou4tech at gmail.com>:
>
> 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