diff options
author | David S. Miller <davem@davemloft.net> | 2012-03-29 23:31:16 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-04-01 18:43:44 -0400 |
commit | 1db20a52950e329f308900f1c603bf05bb1bebc3 (patch) | |
tree | cb9c829ee8eed6c49029b2c75b50824b10952004 /net | |
parent | a447189e073bf603e335f20f924b71d385d6b2ef (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.c | 100 |
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; |