aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-03-29 23:31:16 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-01 18:43:44 -0400
commit1db20a52950e329f308900f1c603bf05bb1bebc3 (patch)
treecb9c829ee8eed6c49029b2c75b50824b10952004 /net
parenta447189e073bf603e335f20f924b71d385d6b2ef (diff)
nfnetlink_log: Stop using NLA_PUT*().
These macros contain a hidden goto, and are thus extremely error prone and make code hard to audit. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nfnetlink_log.c100
1 files changed, 58 insertions, 42 deletions
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 66b2c54c544f..3c3cfc0cc9b5 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -391,67 +391,78 @@ __build_packet_message(struct nfulnl_instance *inst,
391 pmsg.hw_protocol = skb->protocol; 391 pmsg.hw_protocol = skb->protocol;
392 pmsg.hook = hooknum; 392 pmsg.hook = hooknum;
393 393
394 NLA_PUT(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg); 394 if (nla_put(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg))
395 goto nla_put_failure;
395 396
396 if (prefix) 397 if (prefix &&
397 NLA_PUT(inst->skb, NFULA_PREFIX, plen, prefix); 398 nla_put(inst->skb, NFULA_PREFIX, plen, prefix))
399 goto nla_put_failure;
398 400
399 if (indev) { 401 if (indev) {
400#ifndef CONFIG_BRIDGE_NETFILTER 402#ifndef CONFIG_BRIDGE_NETFILTER
401 NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV, 403 if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
402 htonl(indev->ifindex)); 404 htonl(indev->ifindex)))
405 goto nla_put_failure;
403#else 406#else
404 if (pf == PF_BRIDGE) { 407 if (pf == PF_BRIDGE) {
405 /* Case 1: outdev is physical input device, we need to 408 /* Case 1: outdev is physical input device, we need to
406 * look for bridge group (when called from 409 * look for bridge group (when called from
407 * netfilter_bridge) */ 410 * netfilter_bridge) */
408 NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSINDEV, 411 if (nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
409 htonl(indev->ifindex)); 412 htonl(indev->ifindex)) ||
410 /* this is the bridge group "brX" */ 413 /* this is the bridge group "brX" */
411 /* rcu_read_lock()ed by nf_hook_slow or nf_log_packet */ 414 /* rcu_read_lock()ed by nf_hook_slow or nf_log_packet */
412 NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV, 415 nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
413 htonl(br_port_get_rcu(indev)->br->dev->ifindex)); 416 htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
417 goto nla_put_failure;
414 } else { 418 } else {
415 /* Case 2: indev is bridge group, we need to look for 419 /* Case 2: indev is bridge group, we need to look for
416 * physical device (when called from ipv4) */ 420 * physical device (when called from ipv4) */
417 NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV, 421 if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
418 htonl(indev->ifindex)); 422 htonl(indev->ifindex)))
419 if (skb->nf_bridge && skb->nf_bridge->physindev) 423 goto nla_put_failure;
420 NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSINDEV, 424 if (skb->nf_bridge && skb->nf_bridge->physindev &&
421 htonl(skb->nf_bridge->physindev->ifindex)); 425 nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
426 htonl(skb->nf_bridge->physindev->ifindex)))
427 goto nla_put_failure;
422 } 428 }
423#endif 429#endif
424 } 430 }
425 431
426 if (outdev) { 432 if (outdev) {
427#ifndef CONFIG_BRIDGE_NETFILTER 433#ifndef CONFIG_BRIDGE_NETFILTER
428 NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV, 434 if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
429 htonl(outdev->ifindex)); 435 htonl(outdev->ifindex)))
436 goto nla_put_failure;
430#else 437#else
431 if (pf == PF_BRIDGE) { 438 if (pf == PF_BRIDGE) {
432 /* Case 1: outdev is physical output device, we need to 439 /* Case 1: outdev is physical output device, we need to
433 * look for bridge group (when called from 440 * look for bridge group (when called from
434 * netfilter_bridge) */ 441 * netfilter_bridge) */
435 NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, 442 if (nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
436 htonl(outdev->ifindex)); 443 htonl(outdev->ifindex)) ||
437 /* this is the bridge group "brX" */ 444 /* this is the bridge group "brX" */
438 /* rcu_read_lock()ed by nf_hook_slow or nf_log_packet */ 445 /* rcu_read_lock()ed by nf_hook_slow or nf_log_packet */
439 NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV, 446 nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
440 htonl(br_port_get_rcu(outdev)->br->dev->ifindex)); 447 htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
448 goto nla_put_failure;
441 } else { 449 } else {
442 /* Case 2: indev is a bridge group, we need to look 450 /* Case 2: indev is a bridge group, we need to look
443 * for physical device (when called from ipv4) */ 451 * for physical device (when called from ipv4) */
444 NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV, 452 if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
445 htonl(outdev->ifindex)); 453 htonl(outdev->ifindex)))
446 if (skb->nf_bridge && skb->nf_bridge->physoutdev) 454 goto nla_put_failure;
447 NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, 455 if (skb->nf_bridge && skb->nf_bridge->physoutdev &&
448 htonl(skb->nf_bridge->physoutdev->ifindex)); 456 nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
457 htonl(skb->nf_bridge->physoutdev->ifindex)))
458 goto nla_put_failure;
449 } 459 }
450#endif 460#endif
451 } 461 }
452 462
453 if (skb->mark) 463 if (skb->mark &&
454 NLA_PUT_BE32(inst->skb, NFULA_MARK, htonl(skb->mark)); 464 nla_put_be32(inst->skb, NFULA_MARK, htonl(skb->mark)))
465 goto nla_put_failure;
455 466
456 if (indev && skb->dev && 467 if (indev && skb->dev &&
457 skb->mac_header != skb->network_header) { 468 skb->mac_header != skb->network_header) {
@@ -459,16 +470,18 @@ __build_packet_message(struct nfulnl_instance *inst,
459 int len = dev_parse_header(skb, phw.hw_addr); 470 int len = dev_parse_header(skb, phw.hw_addr);
460 if (len > 0) { 471 if (len > 0) {
461 phw.hw_addrlen = htons(len); 472 phw.hw_addrlen = htons(len);
462 NLA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw); 473 if (nla_put(inst->skb, NFULA_HWADDR, sizeof(phw), &phw))
474 goto nla_put_failure;
463 } 475 }
464 } 476 }
465 477
466 if (indev && skb_mac_header_was_set(skb)) { 478 if (indev && skb_mac_header_was_set(skb)) {
467 NLA_PUT_BE16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)); 479 if (nla_put_be32(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) ||
468 NLA_PUT_BE16(inst->skb, NFULA_HWLEN, 480 nla_put_be16(inst->skb, NFULA_HWLEN,
469 htons(skb->dev->hard_header_len)); 481 htons(skb->dev->hard_header_len)) ||
470 NLA_PUT(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len, 482 nla_put(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len,
471 skb_mac_header(skb)); 483 skb_mac_header(skb)))
484 goto nla_put_failure;
472 } 485 }
473 486
474 if (skb->tstamp.tv64) { 487 if (skb->tstamp.tv64) {
@@ -477,7 +490,8 @@ __build_packet_message(struct nfulnl_instance *inst,
477 ts.sec = cpu_to_be64(tv.tv_sec); 490 ts.sec = cpu_to_be64(tv.tv_sec);
478 ts.usec = cpu_to_be64(tv.tv_usec); 491 ts.usec = cpu_to_be64(tv.tv_usec);
479 492
480 NLA_PUT(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts); 493 if (nla_put(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts))
494 goto nla_put_failure;
481 } 495 }
482 496
483 /* UID */ 497 /* UID */
@@ -487,22 +501,24 @@ __build_packet_message(struct nfulnl_instance *inst,
487 struct file *file = skb->sk->sk_socket->file; 501 struct file *file = skb->sk->sk_socket->file;
488 __be32 uid = htonl(file->f_cred->fsuid); 502 __be32 uid = htonl(file->f_cred->fsuid);
489 __be32 gid = htonl(file->f_cred->fsgid); 503 __be32 gid = htonl(file->f_cred->fsgid);
490 /* need to unlock here since NLA_PUT may goto */
491 read_unlock_bh(&skb->sk->sk_callback_lock); 504 read_unlock_bh(&skb->sk->sk_callback_lock);
492 NLA_PUT_BE32(inst->skb, NFULA_UID, uid); 505 if (nla_put_be32(inst->skb, NFULA_UID, uid) ||
493 NLA_PUT_BE32(inst->skb, NFULA_GID, gid); 506 nla_put_be32(inst->skb, NFULA_GID, gid))
507 goto nla_put_failure;
494 } else 508 } else
495 read_unlock_bh(&skb->sk->sk_callback_lock); 509 read_unlock_bh(&skb->sk->sk_callback_lock);
496 } 510 }
497 511
498 /* local sequence number */ 512 /* local sequence number */
499 if (inst->flags & NFULNL_CFG_F_SEQ) 513 if ((inst->flags & NFULNL_CFG_F_SEQ) &&
500 NLA_PUT_BE32(inst->skb, NFULA_SEQ, htonl(inst->seq++)); 514 nla_put_be32(inst->skb, NFULA_SEQ, htonl(inst->seq++)))
515 goto nla_put_failure;
501 516
502 /* global sequence number */ 517 /* global sequence number */
503 if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) 518 if ((inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) &&
504 NLA_PUT_BE32(inst->skb, NFULA_SEQ_GLOBAL, 519 nla_put_be32(inst->skb, NFULA_SEQ_GLOBAL,
505 htonl(atomic_inc_return(&global_seq))); 520 htonl(atomic_inc_return(&global_seq))))
521 goto nla_put_failure;
506 522
507 if (data_len) { 523 if (data_len) {
508 struct nlattr *nla; 524 struct nlattr *nla;