summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrzemyslaw Szczerbik <przemekszczerbik@gmail.com>2016-05-30 21:26:00 (GMT)
committerThomas Haller <thaller@redhat.com>2016-06-24 17:32:25 (GMT)
commit424b3b6d0ddb809869d5ba87fa927ca086f8e5f8 (patch)
tree19c7b104fb49d77d8376d06ac10d3ca724fa55dd
parent838f43faee39bb01e10036971bcadb0fac92ec6e (diff)
downloadlibnl-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.h3
-rw-r--r--lib/attr.c9
-rw-r--r--lib/error.c1
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 *);
diff --git a/lib/attr.c b/lib/attr.c
index 9d8bb26..a3d1b16 100644
--- a/lib/attr.c
+++ b/lib/attr.c
@@ -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",
};
/**