aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2016-09-16 22:40:28 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-09-18 22:55:47 +0200
commit4ff86df861069e51ee796bac4e8ead942f8985f5 (patch)
treecd13a51bb4652cba3fddc3c21d1fc50debbe8e96
parent0ae0509679033c8c9b511b83027d5ef076b7bf2b (diff)
downloadbusybox-w32-4ff86df861069e51ee796bac4e8ead942f8985f5.tar.gz
busybox-w32-4ff86df861069e51ee796bac4e8ead942f8985f5.tar.bz2
busybox-w32-4ff86df861069e51ee796bac4e8ead942f8985f5.zip
libnetlink: fix alignment of netlink messages
A padding to align a message should not only be added between different attributes of a netlink message, but also at the end of the message to pad it to the correct size. Without this patch the following command does not work and returns an error code: ip link add type nlmon Without this ip from busybox sends this: sendmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base={{len=45, ...}, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\20\0\22\0\t\0\1nlmon"}, iov_len=45}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 45 return value: 2 The normal ip utile from iproute2 sends this: sendmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base={{len=48, ...}, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\20\0\22\0\t\0\1nlmon\0\0\0"}, iov_len=48}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 48 return value: 0 With this patch ip from busybox sends this: sendmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base={{len=48, ...}, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\20\0\22\0\t\0\1nlmon\0\0\0"}, iov_len=48}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 48 return value: 0 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/libiproute/libnetlink.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/networking/libiproute/libnetlink.c b/networking/libiproute/libnetlink.c
index 9d5c6416b..7e0ff1b6c 100644
--- a/networking/libiproute/libnetlink.c
+++ b/networking/libiproute/libnetlink.c
@@ -340,14 +340,14 @@ int FAST_FUNC addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data)
340 int len = RTA_LENGTH(4); 340 int len = RTA_LENGTH(4);
341 struct rtattr *rta; 341 struct rtattr *rta;
342 342
343 if ((int)(NLMSG_ALIGN(n->nlmsg_len) + len) > maxlen) { 343 if ((int)(NLMSG_ALIGN(n->nlmsg_len + len)) > maxlen) {
344 return -1; 344 return -1;
345 } 345 }
346 rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len)); 346 rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len));
347 rta->rta_type = type; 347 rta->rta_type = type;
348 rta->rta_len = len; 348 rta->rta_len = len;
349 move_to_unaligned32(RTA_DATA(rta), data); 349 move_to_unaligned32(RTA_DATA(rta), data);
350 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len; 350 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len + len);
351 return 0; 351 return 0;
352} 352}
353 353
@@ -356,14 +356,14 @@ int FAST_FUNC addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, in
356 int len = RTA_LENGTH(alen); 356 int len = RTA_LENGTH(alen);
357 struct rtattr *rta; 357 struct rtattr *rta;
358 358
359 if ((int)(NLMSG_ALIGN(n->nlmsg_len) + len) > maxlen) { 359 if ((int)(NLMSG_ALIGN(n->nlmsg_len + len)) > maxlen) {
360 return -1; 360 return -1;
361 } 361 }
362 rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len)); 362 rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len));
363 rta->rta_type = type; 363 rta->rta_type = type;
364 rta->rta_len = len; 364 rta->rta_len = len;
365 memcpy(RTA_DATA(rta), data, alen); 365 memcpy(RTA_DATA(rta), data, alen);
366 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len; 366 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len + len);
367 return 0; 367 return 0;
368} 368}
369 369
@@ -372,14 +372,14 @@ int FAST_FUNC rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t d
372 int len = RTA_LENGTH(4); 372 int len = RTA_LENGTH(4);
373 struct rtattr *subrta; 373 struct rtattr *subrta;
374 374
375 if (RTA_ALIGN(rta->rta_len) + len > maxlen) { 375 if (RTA_ALIGN(rta->rta_len + len) > maxlen) {
376 return -1; 376 return -1;
377 } 377 }
378 subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len)); 378 subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len));
379 subrta->rta_type = type; 379 subrta->rta_type = type;
380 subrta->rta_len = len; 380 subrta->rta_len = len;
381 move_to_unaligned32(RTA_DATA(subrta), data); 381 move_to_unaligned32(RTA_DATA(subrta), data);
382 rta->rta_len = NLMSG_ALIGN(rta->rta_len) + len; 382 rta->rta_len = NLMSG_ALIGN(rta->rta_len + len);
383 return 0; 383 return 0;
384} 384}
385 385
@@ -388,14 +388,14 @@ int FAST_FUNC rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data
388 struct rtattr *subrta; 388 struct rtattr *subrta;
389 int len = RTA_LENGTH(alen); 389 int len = RTA_LENGTH(alen);
390 390
391 if (RTA_ALIGN(rta->rta_len) + len > maxlen) { 391 if (RTA_ALIGN(rta->rta_len + len) > maxlen) {
392 return -1; 392 return -1;
393 } 393 }
394 subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len)); 394 subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len));
395 subrta->rta_type = type; 395 subrta->rta_type = type;
396 subrta->rta_len = len; 396 subrta->rta_len = len;
397 memcpy(RTA_DATA(subrta), data, alen); 397 memcpy(RTA_DATA(subrta), data, alen);
398 rta->rta_len = NLMSG_ALIGN(rta->rta_len) + len; 398 rta->rta_len = NLMSG_ALIGN(rta->rta_len + len);
399 return 0; 399 return 0;
400} 400}
401 401