lkml.org 
[lkml]   [2014]   [Nov]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.16.y-ckt 066/254] netfilter: nf_log: release skbuff on nlmsg put failure
    Date
    3.16.7-ckt2 -stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Houcheng Lin <houcheng@gmail.com>

    commit b51d3fa364885a2c1e1668f88776c67c95291820 upstream.

    The kernel should reserve enough room in the skb so that the DONE
    message can always be appended. However, in case of e.g. new attribute
    erronously not being size-accounted for, __nfulnl_send() will still
    try to put next nlmsg into this full skbuf, causing the skb to be stuck
    forever and blocking delivery of further messages.

    Fix issue by releasing skb immediately after nlmsg_put error and
    WARN() so we can track down the cause of such size mismatch.

    [ fw@strlen.de: add tailroom/len info to WARN ]

    Signed-off-by: Houcheng Lin <houcheng@gmail.com>
    Signed-off-by: Florian Westphal <fw@strlen.de>
    Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
    Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
    ---
    net/netfilter/nfnetlink_log.c | 17 ++++++++---------
    1 file changed, 8 insertions(+), 9 deletions(-)

    diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
    index 8f415d6889fe..dd9fb9de9f1d 100644
    --- a/net/netfilter/nfnetlink_log.c
    +++ b/net/netfilter/nfnetlink_log.c
    @@ -346,26 +346,25 @@ nfulnl_alloc_skb(struct net *net, u32 peer_portid, unsigned int inst_size,
    return skb;
    }

    -static int
    +static void
    __nfulnl_send(struct nfulnl_instance *inst)
    {
    - int status = -1;
    -
    if (inst->qlen > 1) {
    struct nlmsghdr *nlh = nlmsg_put(inst->skb, 0, 0,
    NLMSG_DONE,
    sizeof(struct nfgenmsg),
    0);
    - if (!nlh)
    + if (WARN_ONCE(!nlh, "bad nlskb size: %u, tailroom %d\n",
    + inst->skb->len, skb_tailroom(inst->skb))) {
    + kfree_skb(inst->skb);
    goto out;
    + }
    }
    - status = nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid,
    - MSG_DONTWAIT);
    -
    + nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid,
    + MSG_DONTWAIT);
    +out:
    inst->qlen = 0;
    inst->skb = NULL;
    -out:
    - return status;
    }

    static void
    --
    2.1.0


    \
     
     \ /
      Last update: 2014-11-25 13:21    [W:2.259 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site