diff options
author | Przemyslaw Szczerbik <przemekszczerbik@gmail.com> | 2016-05-30 21:26:00 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-06-24 17:32:25 (GMT) |
commit | 424b3b6d0ddb809869d5ba87fa927ca086f8e5f8 (patch) | |
tree | 19c7b104fb49d77d8376d06ac10d3ca724fa55dd | |
parent | 838f43faee39bb01e10036971bcadb0fac92ec6e (diff) | |
download | libnl-424b3b6d0ddb809869d5ba87fa927ca086f8e5f8.zip libnl-424b3b6d0ddb809869d5ba87fa927ca086f8e5f8.tar.gz libnl-424b3b6d0ddb809869d5ba87fa927ca086f8e5f8.tar.bz2 |
lib: return error on Netlink attribute length overflow
Netlink attribute length is defined as u16. It's possible to exceed nla_len when
creating nested attributes. Storing incorrect length due to overflow will cause
a reader to read only a part of nested attribute or skip it entirely.
As a solution cancel the addition of a nested attribute when nla_len size is
exceeded.
Signed-off-by: Przemyslaw Szczerbik <przemek.szczerbik@gmail.com>
Signed-off-by: Thomas Haller <thaller@redhat.com>
http://lists.infradead.org/pipermail/libnl/2016-May/002131.html
-rw-r--r-- | include/netlink/errno.h | 3 | ||||
-rw-r--r-- | lib/attr.c | 9 | ||||
-rw-r--r-- | lib/error.c | 1 |
3 files changed, 8 insertions, 5 deletions
diff --git a/include/netlink/errno.h b/include/netlink/errno.h index f8b5130..35710cf 100644 --- a/include/netlink/errno.h +++ b/include/netlink/errno.h @@ -50,8 +50,9 @@ extern "C" { #define NLE_NODEV 31 #define NLE_IMMUTABLE 32 #define NLE_DUMP_INTR 33 +#define NLE_ATTRSIZE 34 -#define NLE_MAX NLE_DUMP_INTR +#define NLE_MAX NLE_ATTRSIZE extern const char * nl_geterror(int); extern void nl_perror(int, const char *); @@ -912,7 +912,7 @@ struct nlattr *nla_nest_start(struct nl_msg *msg, int attrtype) * * Corrects the container attribute header to include the appeneded attributes. * - * @return 0 + * @return 0 on success or a negative error code. */ int nla_nest_end(struct nl_msg *msg, struct nlattr *start) { @@ -920,14 +920,15 @@ int nla_nest_end(struct nl_msg *msg, struct nlattr *start) len = (void *) nlmsg_tail(msg->nm_nlh) - (void *) start; - if (len == NLA_HDRLEN) { + if (len == NLA_HDRLEN || len > USHRT_MAX) { /* - * Kernel can't handle empty nested attributes, trim the + * Max nlattr size exceeded or empty nested attribute, trim the * attribute header again */ nla_nest_cancel(msg, start); - return 0; + /* Return error only if nlattr size was exceeded */ + return (len == NLA_HDRLEN) ? 0 : -NLE_ATTRSIZE; } start->nla_len = len; diff --git a/lib/error.c b/lib/error.c index f30b9a5..7fbd389 100644 --- a/lib/error.c +++ b/lib/error.c @@ -47,6 +47,7 @@ static const char *errmsg[NLE_MAX+1] = { [NLE_NODEV] = "No such device", [NLE_IMMUTABLE] = "Immutable attribute", [NLE_DUMP_INTR] = "Dump inconsistency detected, interrupted", +[NLE_ATTRSIZE] = "Attribute max length exceeded", }; /** |