From 9e6cdbf6fc60f95e232c4ca34004606da9536d01 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 13 Mar 2013 16:53:07 +0100 Subject: [PATCH] attr: Add nla_nest_cancel() to remove partially added nested attributes Signed-off-by: Thomas Graf --- doc/core.txt | 1 + include/netlink/attr.h | 1 + lib/attr.c | 25 +++++++++++++++++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/doc/core.txt b/doc/core.txt index 8a26dba..1e951d0 100644 --- a/doc/core.txt +++ b/doc/core.txt @@ -2316,6 +2316,7 @@ int put_opts(struct nl_msg *msg) return 0; nla_put_failure: + nla_nest_cancel(msg, opts); return -EMSGSIZE; } -------- diff --git a/include/netlink/attr.h b/include/netlink/attr.h index 69ecb08..0ed3da3 100644 --- a/include/netlink/attr.h +++ b/include/netlink/attr.h @@ -124,6 +124,7 @@ extern int nla_put_msecs(struct nl_msg *, int, unsigned long); extern int nla_put_nested(struct nl_msg *, int, struct nl_msg *); extern struct nlattr * nla_nest_start(struct nl_msg *, int); extern int nla_nest_end(struct nl_msg *, struct nlattr *); +extern void nla_nest_cancel(struct nl_msg *, struct nlattr *); extern int nla_parse_nested(struct nlattr **, int, struct nlattr *, struct nla_policy *); extern int nla_is_nested(struct nlattr *); diff --git a/lib/attr.c b/lib/attr.c index 26bece3..2c03fa1 100644 --- a/lib/attr.c +++ b/lib/attr.c @@ -820,8 +820,7 @@ int nla_nest_end(struct nl_msg *msg, struct nlattr *start) * Kernel can't handle empty nested attributes, trim the * attribute header again */ - msg->nm_nlh->nlmsg_len -= NLA_HDRLEN; - memset(nlmsg_tail(msg->nm_nlh), 0, NLA_HDRLEN); + nla_nest_cancel(msg, start); return 0; } @@ -849,6 +848,28 @@ int nla_nest_end(struct nl_msg *msg, struct nlattr *start) return 0; } +/** + * Cancel the addition of a nested attribute + * @arg msg Netlink message + * @arg attr Nested netlink attribute + * + * Removes any partially added nested Netlink attribute from the message + * by resetting the message to the size before the call to nla_nest_start() + * and by overwriting any potentially touched message segments with 0. + */ +void nla_nest_cancel(struct nl_msg *msg, struct nlattr *attr) +{ + ssize_t len; + + len = (void *) nlmsg_tail(msg->nm_nlh) - (void *) attr; + if (len < 0) + BUG(); + else if (len > 0) { + msg->nm_nlh->nlmsg_len -= len; + memset(nlmsg_tail(msg->nm_nlh), 0, len); + } +} + /** * Create attribute index based on nested attribute * @arg tb Index array to be filled (maxtype+1 elements).