ACK: [PATCH 1/1][SRU][X] l2tp: pass tunnel pointer to ->session_create()

Stefan Bader stefan.bader at canonical.com
Fri Feb 22 09:52:17 UTC 2019


On 18.02.19 16:19, AceLan Kao wrote:
> From: Guillaume Nault <g.nault at alphalink.fr>
> 
> Using l2tp_tunnel_find() in pppol2tp_session_create() and
> l2tp_eth_create() is racy, because no reference is held on the
> returned session. These functions are only used to implement the
> ->session_create callback which is run by l2tp_nl_cmd_session_create().
> Therefore searching for the parent tunnel isn't necessary because
> l2tp_nl_cmd_session_create() already has a pointer to it and holds a
> reference.
> 
> This patch modifies ->session_create()'s prototype to directly pass the
> the parent tunnel as parameter, thus avoiding searching for it in
> pppol2tp_session_create() and l2tp_eth_create().
> 
> Since we have to touch the ->session_create() call in
> l2tp_nl_cmd_session_create(), let's also remove the useless conditional:
> we know that ->session_create isn't NULL at this point because it's
> already been checked earlier in this same function.
> 
> Finally, one might be tempted to think that the removed
> l2tp_tunnel_find() calls were harmless because they would return the
> same tunnel as the one held by l2tp_nl_cmd_session_create() anyway.
> But that tunnel might be removed and a new one created with same tunnel
> Id before the l2tp_tunnel_find() call. In this case l2tp_tunnel_find()
> would return the new tunnel which wouldn't be protected by the
> reference held by l2tp_nl_cmd_session_create().
> 
> CVE-2018-9517
> 
> Fixes: 309795f4bec2 ("l2tp: Add netlink control API for L2TP")
> Fixes: d9e31d17ceba ("l2tp: Add L2TP ethernet pseudowire support")
> Signed-off-by: Guillaume Nault <g.nault at alphalink.fr>
> Signed-off-by: David S. Miller <davem at davemloft.net>
> (backported from commit f026bc29a8e093edfbb2a77700454b285c97e8ad)
> Signed-off-by: AceLan Kao <acelan.kao at canonical.com>
Acked-by: Stefan Bader <stefan.bader at canonical.com>
> ---
>  net/l2tp/l2tp_core.h    |  4 +++-
>  net/l2tp/l2tp_eth.c     | 11 +++--------
>  net/l2tp/l2tp_netlink.c |  8 ++++----
>  net/l2tp/l2tp_ppp.c     | 19 +++++++------------
>  4 files changed, 17 insertions(+), 25 deletions(-)
> 
> diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
> index 9cf546846edb..03602df06f4e 100644
> --- a/net/l2tp/l2tp_core.h
> +++ b/net/l2tp/l2tp_core.h
> @@ -209,7 +209,9 @@ struct l2tp_tunnel {
>  };
>  
>  struct l2tp_nl_cmd_ops {
> -	int (*session_create)(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg);
> +	int (*session_create)(struct net *net, struct l2tp_tunnel *tunnel,
> +			      u32 session_id, u32 peer_session_id,
> +			      struct l2tp_session_cfg *cfg);
>  	int (*session_delete)(struct l2tp_session *session);
>  };
>  
> diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
> index e253c26f31ac..f116d969416b 100644
> --- a/net/l2tp/l2tp_eth.c
> +++ b/net/l2tp/l2tp_eth.c
> @@ -206,23 +206,18 @@ static void l2tp_eth_show(struct seq_file *m, void *arg)
>  }
>  #endif
>  
> -static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg)
> +static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel,
> +			   u32 session_id, u32 peer_session_id,
> +			   struct l2tp_session_cfg *cfg)
>  {
>  	struct net_device *dev;
>  	char name[IFNAMSIZ];
> -	struct l2tp_tunnel *tunnel;
>  	struct l2tp_session *session;
>  	struct l2tp_eth *priv;
>  	struct l2tp_eth_sess *spriv;
>  	int rc;
>  	struct l2tp_eth_net *pn;
>  
> -	tunnel = l2tp_tunnel_find(net, tunnel_id);
> -	if (!tunnel) {
> -		rc = -ENODEV;
> -		goto out;
> -	}
> -
>  	session = l2tp_session_find(net, tunnel, session_id);
>  	if (session) {
>  		rc = -EEXIST;
> diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
> index fb3248ff8b48..5a68b776a226 100644
> --- a/net/l2tp/l2tp_netlink.c
> +++ b/net/l2tp/l2tp_netlink.c
> @@ -620,10 +620,10 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
>  		break;
>  	}
>  
> -	ret = -EPROTONOSUPPORT;
> -	if (l2tp_nl_cmd_ops[cfg.pw_type]->session_create)
> -		ret = (*l2tp_nl_cmd_ops[cfg.pw_type]->session_create)(net, tunnel_id,
> -			session_id, peer_session_id, &cfg);
> +	ret = l2tp_nl_cmd_ops[cfg.pw_type]->session_create(net, tunnel,
> +							   session_id,
> +							   peer_session_id,
> +							   &cfg);
>  
>  	if (ret >= 0) {
>  		session = l2tp_session_find(net, tunnel, session_id);
> diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
> index 2764c4bd072c..783da2550d7b 100644
> --- a/net/l2tp/l2tp_ppp.c
> +++ b/net/l2tp/l2tp_ppp.c
> @@ -809,25 +809,20 @@ end:
>  
>  #ifdef CONFIG_L2TP_V3
>  
> -/* Called when creating sessions via the netlink interface.
> - */
> -static int pppol2tp_session_create(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg)
> +/* Called when creating sessions via the netlink interface. */
> +static int pppol2tp_session_create(struct net *net, struct l2tp_tunnel *tunnel,
> +				   u32 session_id, u32 peer_session_id,
> +				   struct l2tp_session_cfg *cfg)
>  {
>  	int error;
> -	struct l2tp_tunnel *tunnel;
>  	struct l2tp_session *session;
>  	struct pppol2tp_session *ps;
>  
> -	tunnel = l2tp_tunnel_find(net, tunnel_id);
> -
> -	/* Error if we can't find the tunnel */
> -	error = -ENOENT;
> -	if (tunnel == NULL)
> -		goto out;
> -
>  	/* Error if tunnel socket is not prepped */
> -	if (tunnel->sock == NULL)
> +	if (!tunnel->sock) {
> +		error = -ENOENT;
>  		goto out;
> +	}
>  
>  	/* Check that this session doesn't already exist */
>  	error = -EEXIST;
> 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20190222/892848cd/attachment-0001.sig>


More information about the kernel-team mailing list