lkml.org 
[lkml]   [2018]   [Apr]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.16 42/81] l2tp: hold reference on tunnels printed in pppol2tp proc file
    Date
    4.16-stable review patch.  If anyone has any objections, please let me know.

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

    From: Guillaume Nault <g.nault@alphalink.fr>


    [ Upstream commit 0e0c3fee3a59a387aeecc4fca6f3a2e9615a5443 ]

    Use l2tp_tunnel_get_nth() instead of l2tp_tunnel_find_nth(), to be safe
    against concurrent tunnel deletion.

    Unlike sessions, we can't drop the reference held on tunnels in
    pppol2tp_seq_show(). Tunnels are reused across several calls to
    pppol2tp_seq_start() when iterating over sessions. These iterations
    need the tunnel for accessing the next session. Therefore the only safe
    moment for dropping the reference is just before searching for the next
    tunnel.

    Normally, the last invocation of pppol2tp_next_tunnel() doesn't find
    any new tunnel, so it drops the last tunnel without taking any new
    reference. However, in case of error, pppol2tp_seq_stop() is called
    directly, so we have to drop the reference there.

    Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts")
    Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/l2tp/l2tp_ppp.c | 24 +++++++++++++++++-------
    1 file changed, 17 insertions(+), 7 deletions(-)

    --- a/net/l2tp/l2tp_ppp.c
    +++ b/net/l2tp/l2tp_ppp.c
    @@ -1559,16 +1559,19 @@ struct pppol2tp_seq_data {

    static void pppol2tp_next_tunnel(struct net *net, struct pppol2tp_seq_data *pd)
    {
    + /* Drop reference taken during previous invocation */
    + if (pd->tunnel)
    + l2tp_tunnel_dec_refcount(pd->tunnel);
    +
    for (;;) {
    - pd->tunnel = l2tp_tunnel_find_nth(net, pd->tunnel_idx);
    + pd->tunnel = l2tp_tunnel_get_nth(net, pd->tunnel_idx);
    pd->tunnel_idx++;

    - if (pd->tunnel == NULL)
    - break;
    + /* Only accept L2TPv2 tunnels */
    + if (!pd->tunnel || pd->tunnel->version == 2)
    + return;

    - /* Ignore L2TPv3 tunnels */
    - if (pd->tunnel->version < 3)
    - break;
    + l2tp_tunnel_dec_refcount(pd->tunnel);
    }
    }

    @@ -1617,7 +1620,14 @@ static void *pppol2tp_seq_next(struct se

    static void pppol2tp_seq_stop(struct seq_file *p, void *v)
    {
    - /* nothing to do */
    + struct pppol2tp_seq_data *pd = v;
    +
    + if (!pd || pd == SEQ_START_TOKEN)
    + return;
    +
    + /* Drop reference taken by last invocation of pppol2tp_next_tunnel() */
    + if (pd->tunnel)
    + l2tp_tunnel_dec_refcount(pd->tunnel);
    }

    static void pppol2tp_seq_tunnel_show(struct seq_file *m, void *v)

    \
     
     \ /
      Last update: 2018-04-27 16:21    [W:3.134 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site