diff options
author | Thomas Haller <thaller@redhat.com> | 2019-02-17 19:24:11 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-02-21 21:02:51 +0100 |
commit | 8a8343c297307288b81d9f411389a2e1dcca47a8 (patch) | |
tree | 70a45d33335a81b504740684ec48de7da986afcf | |
parent | bdfba4b82ed533a803d6133f63f7424b55c03eca (diff) | |
download | NetworkManager-8a8343c297307288b81d9f411389a2e1dcca47a8.tar.gz |
platform/netlink: cleanup nla_memcpy()
- use size_t arguments for the memory sizes. While sizes from netlink
API currently are int typed and inherrently limited, use the more
appropriate data type.
- rename the arguments. The "count" is really the size of the
destination buffer.
- return how many bytes we wanted to write (like g_strlcpy()).
That makes more sense than how many bytes we actually wrote
because previously, we could not detect truncation.
Anyway, none of the callers cared about the return-value either
way.
-rw-r--r-- | src/platform/nm-netlink.c | 29 | ||||
-rw-r--r-- | src/platform/nm-netlink.h | 19 |
2 files changed, 40 insertions, 8 deletions
diff --git a/src/platform/nm-netlink.c b/src/platform/nm-netlink.c index 7118971448..d367df304d 100644 --- a/src/platform/nm-netlink.c +++ b/src/platform/nm-netlink.c @@ -420,18 +420,33 @@ nla_strlcpy (char *dst, return 0; } -int -nla_memcpy (void *dest, const struct nlattr *src, int count) +size_t +nla_memcpy (void *dst, const struct nlattr *nla, size_t dstsize) { - int minlen; + size_t len; + int srclen; + + if (!nla) + return 0; + + srclen = nla_len (nla); - if (!src) + if (srclen <= 0) { + nm_assert (srclen == 0); return 0; + } - minlen = NM_MIN (count, (int) nla_len (src)); - memcpy (dest, nla_data (src), minlen); + len = NM_MIN ((size_t) srclen, dstsize); + if (len > 0) { + /* there is a crucial difference between nla_strlcpy() and nla_memcpy(). + * The former always write @dstsize bytes (akin to strncpy()), here, we only + * write the bytes that we actually have (leaving the remainder undefined). */ + memcpy (dst, + nla_data (nla), + len); + } - return minlen; + return srclen; } int diff --git a/src/platform/nm-netlink.h b/src/platform/nm-netlink.h index df1c098d92..fc0b434f0d 100644 --- a/src/platform/nm-netlink.h +++ b/src/platform/nm-netlink.h @@ -195,7 +195,24 @@ nla_get_string (const struct nlattr *nla) size_t nla_strlcpy (char *dst, const struct nlattr *nla, size_t dstsize); -int nla_memcpy (void *dest, const struct nlattr *src, int count); +size_t nla_memcpy (void *dst, const struct nlattr *nla, size_t dstsize); + +#define nla_memcpy_checked_size(dst, nla, dstsize) \ + G_STMT_START { \ + void *const _dst = (dst); \ + const struct nlattr *const _nla = (nla); \ + const size_t _dstsize = (dstsize); \ + size_t _srcsize; \ + \ + /* assert that, if @nla is given, that it has the exact expected + * size. This implies that the caller previously verified the length + * of the attribute (via minlen/maxlen at nla_parse()). */ \ + \ + if (_nla) { \ + _srcsize = nla_memcpy (_dst, _nla, _dstsize); \ + nm_assert (_srcsize == _dstsize); \ + } \ + } G_STMT_END int nla_put (struct nl_msg *msg, int attrtype, int datalen, const void *data); |