summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-02-17 19:24:11 +0100
committerThomas Haller <thaller@redhat.com>2019-02-21 21:02:51 +0100
commit8a8343c297307288b81d9f411389a2e1dcca47a8 (patch)
tree70a45d33335a81b504740684ec48de7da986afcf
parentbdfba4b82ed533a803d6133f63f7424b55c03eca (diff)
downloadNetworkManager-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.c29
-rw-r--r--src/platform/nm-netlink.h19
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);