get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/808761/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 808761,
    "url": "http://patchwork.ozlabs.org/api/patches/808761/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/7d7d80950bd0456de42dbf015785688680165f3f.1504277892.git.g.nault@alphalink.fr/",
    "project": {
        "id": 7,
        "url": "http://patchwork.ozlabs.org/api/projects/7/?format=api",
        "name": "Linux network development",
        "link_name": "netdev",
        "list_id": "netdev.vger.kernel.org",
        "list_email": "netdev@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<7d7d80950bd0456de42dbf015785688680165f3f.1504277892.git.g.nault@alphalink.fr>",
    "list_archive_url": null,
    "date": "2017-09-01T15:58:48",
    "name": "[net,1/2] l2tp: prevent creation of sessions on terminated tunnels",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "5e0b3fcb62edc288d221f1bbe54adf779eab54a1",
    "submitter": {
        "id": 22975,
        "url": "http://patchwork.ozlabs.org/api/people/22975/?format=api",
        "name": "Guillaume Nault",
        "email": "g.nault@alphalink.fr"
    },
    "delegate": {
        "id": 34,
        "url": "http://patchwork.ozlabs.org/api/users/34/?format=api",
        "username": "davem",
        "first_name": "David",
        "last_name": "Miller",
        "email": "davem@davemloft.net"
    },
    "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/7d7d80950bd0456de42dbf015785688680165f3f.1504277892.git.g.nault@alphalink.fr/mbox/",
    "series": [
        {
            "id": 1055,
            "url": "http://patchwork.ozlabs.org/api/series/1055/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=1055",
            "date": "2017-09-01T15:58:48",
            "name": "l2tp: session creation fixes",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/1055/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/808761/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/808761/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<netdev-owner@vger.kernel.org>",
        "X-Original-To": "patchwork-incoming@ozlabs.org",
        "Delivered-To": "patchwork-incoming@ozlabs.org",
        "Authentication-Results": "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)",
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xkP733R82z9t3k\n\tfor <patchwork-incoming@ozlabs.org>;\n\tSat,  2 Sep 2017 01:58:55 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1752127AbdIAP6x (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tFri, 1 Sep 2017 11:58:53 -0400",
            "from zimbra.alphalink.fr ([217.15.80.77]:46000 \"EHLO\n\tzimbra.alphalink.fr\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751968AbdIAP6w (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Fri, 1 Sep 2017 11:58:52 -0400",
            "from localhost (localhost [127.0.0.1])\n\tby mail-2-cbv2.admin.alphalink.fr (Postfix) with ESMTP id\n\t7C1C62B52068; Fri,  1 Sep 2017 17:58:50 +0200 (CEST)",
            "from zimbra.alphalink.fr ([127.0.0.1])\n\tby localhost (mail-2-cbv2.admin.alphalink.fr [127.0.0.1])\n\t(amavisd-new, port 10032)\n\twith ESMTP id vOdAUsY7iME3; Fri,  1 Sep 2017 17:58:48 +0200 (CEST)",
            "from localhost (localhost [127.0.0.1])\n\tby mail-2-cbv2.admin.alphalink.fr (Postfix) with ESMTP id\n\t5E7702B52120; Fri,  1 Sep 2017 17:58:48 +0200 (CEST)",
            "from zimbra.alphalink.fr ([127.0.0.1])\n\tby localhost (mail-2-cbv2.admin.alphalink.fr [127.0.0.1])\n\t(amavisd-new, port 10026)\n\twith ESMTP id 9agnyHItgoJd; Fri,  1 Sep 2017 17:58:48 +0200 (CEST)",
            "from c-dev-0.admin.alphalink.fr (94-84-15-217.reverse.alphalink.fr\n\t[217.15.84.94])\n\tby mail-2-cbv2.admin.alphalink.fr (Postfix) with ESMTP id\n\t328402B52068; Fri,  1 Sep 2017 17:58:48 +0200 (CEST)",
            "by c-dev-0.admin.alphalink.fr (Postfix, from userid 1000)\n\tid 152EE60141; Fri,  1 Sep 2017 17:58:48 +0200 (CEST)"
        ],
        "X-Virus-Scanned": "amavisd-new at mail-2-cbv2.admin.alphalink.fr",
        "Date": "Fri, 1 Sep 2017 17:58:48 +0200",
        "From": "Guillaume Nault <g.nault@alphalink.fr>",
        "To": "netdev@vger.kernel.org",
        "Cc": "James Chapman <jchapman@katalix.com>",
        "Subject": "[PATCH net 1/2] l2tp: prevent creation of sessions on terminated\n\ttunnels",
        "Message-ID": "<7d7d80950bd0456de42dbf015785688680165f3f.1504277892.git.g.nault@alphalink.fr>",
        "References": "<cover.1504277892.git.g.nault@alphalink.fr>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=us-ascii",
        "Content-Disposition": "inline",
        "In-Reply-To": "<cover.1504277892.git.g.nault@alphalink.fr>",
        "X-Mutt-Fcc": "=Sent",
        "User-Agent": "NeoMutt/20170609 (1.8.3)",
        "Sender": "netdev-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<netdev.vger.kernel.org>",
        "X-Mailing-List": "netdev@vger.kernel.org"
    },
    "content": "l2tp_tunnel_destruct() sets tunnel->sock to NULL, then removes the\ntunnel from the pernet list and finally closes all its sessions.\nTherefore, it's possible to add a session to a tunnel that is still\nreachable, but for which tunnel->sock has already been reset. This can\nmake l2tp_session_create() dereference a NULL pointer when calling\nsock_hold(tunnel->sock).\n\nThis patch adds the .acpt_newsess field to struct l2tp_tunnel, which is\nused by l2tp_tunnel_closeall() to prevent addition of new sessions to\ntunnels. Resetting tunnel->sock is done after l2tp_tunnel_closeall()\nreturned, so that l2tp_session_add_to_tunnel() can safely take a\nreference on it when .acpt_newsess is true.\n\nThe .acpt_newsess field is modified in l2tp_tunnel_closeall(), rather\nthan in l2tp_tunnel_destruct(), so that it benefits all tunnel removal\nmechanisms. E.g. on UDP tunnels, a session could be added to a tunnel\nafter l2tp_udp_encap_destroy() proceeded. This would prevent the tunnel\nfrom being removed because of the references held by this new session\non the tunnel and its socket. Even though the session could be removed\nmanually later on, this defeats the purpose of\ncommit 9980d001cec8 (\"l2tp: add udp encap socket destroy handler\").\n\nFixes: fd558d186df2 (\"l2tp: Split pppol2tp patch into separate l2tp and ppp parts\")\nSigned-off-by: Guillaume Nault <g.nault@alphalink.fr>\n---\n net/l2tp/l2tp_core.c | 41 ++++++++++++++++++++++++++++-------------\n net/l2tp/l2tp_core.h |  4 ++++\n 2 files changed, 32 insertions(+), 13 deletions(-)",
    "diff": "diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c\nindex 90165a6874bc..ee485df73ccd 100644\n--- a/net/l2tp/l2tp_core.c\n+++ b/net/l2tp/l2tp_core.c\n@@ -329,13 +329,21 @@ static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel,\n \tstruct hlist_head *g_head;\n \tstruct hlist_head *head;\n \tstruct l2tp_net *pn;\n+\tint err;\n \n \thead = l2tp_session_id_hash(tunnel, session->session_id);\n \n \twrite_lock_bh(&tunnel->hlist_lock);\n+\tif (!tunnel->acpt_newsess) {\n+\t\terr = -ENODEV;\n+\t\tgoto err_tlock;\n+\t}\n+\n \thlist_for_each_entry(session_walk, head, hlist)\n-\t\tif (session_walk->session_id == session->session_id)\n-\t\t\tgoto exist;\n+\t\tif (session_walk->session_id == session->session_id) {\n+\t\t\terr = -EEXIST;\n+\t\t\tgoto err_tlock;\n+\t\t}\n \n \tif (tunnel->version == L2TP_HDR_VER_3) {\n \t\tpn = l2tp_pernet(tunnel->l2tp_net);\n@@ -343,12 +351,21 @@ static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel,\n \t\t\t\t\t\tsession->session_id);\n \n \t\tspin_lock_bh(&pn->l2tp_session_hlist_lock);\n+\n \t\thlist_for_each_entry(session_walk, g_head, global_hlist)\n-\t\t\tif (session_walk->session_id == session->session_id)\n-\t\t\t\tgoto exist_glob;\n+\t\t\tif (session_walk->session_id == session->session_id) {\n+\t\t\t\terr = -EEXIST;\n+\t\t\t\tgoto err_tlock_pnlock;\n+\t\t\t}\n \n+\t\tl2tp_tunnel_inc_refcount(tunnel);\n+\t\tsock_hold(tunnel->sock);\n \t\thlist_add_head_rcu(&session->global_hlist, g_head);\n+\n \t\tspin_unlock_bh(&pn->l2tp_session_hlist_lock);\n+\t} else {\n+\t\tl2tp_tunnel_inc_refcount(tunnel);\n+\t\tsock_hold(tunnel->sock);\n \t}\n \n \thlist_add_head(&session->hlist, head);\n@@ -356,12 +373,12 @@ static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel,\n \n \treturn 0;\n \n-exist_glob:\n+err_tlock_pnlock:\n \tspin_unlock_bh(&pn->l2tp_session_hlist_lock);\n-exist:\n+err_tlock:\n \twrite_unlock_bh(&tunnel->hlist_lock);\n \n-\treturn -EEXIST;\n+\treturn err;\n }\n \n /* Lookup a tunnel by id\n@@ -1251,7 +1268,6 @@ static void l2tp_tunnel_destruct(struct sock *sk)\n \t/* Remove hooks into tunnel socket */\n \tsk->sk_destruct = tunnel->old_sk_destruct;\n \tsk->sk_user_data = NULL;\n-\ttunnel->sock = NULL;\n \n \t/* Remove the tunnel struct from the tunnel list */\n \tpn = l2tp_pernet(tunnel->l2tp_net);\n@@ -1261,6 +1277,8 @@ static void l2tp_tunnel_destruct(struct sock *sk)\n \tatomic_dec(&l2tp_tunnel_count);\n \n \tl2tp_tunnel_closeall(tunnel);\n+\n+\ttunnel->sock = NULL;\n \tl2tp_tunnel_dec_refcount(tunnel);\n \n \t/* Call the original destructor */\n@@ -1285,6 +1303,7 @@ void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel)\n \t\t  tunnel->name);\n \n \twrite_lock_bh(&tunnel->hlist_lock);\n+\ttunnel->acpt_newsess = false;\n \tfor (hash = 0; hash < L2TP_HASH_SIZE; hash++) {\n again:\n \t\thlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {\n@@ -1581,6 +1600,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32\n \ttunnel->magic = L2TP_TUNNEL_MAGIC;\n \tsprintf(&tunnel->name[0], \"tunl %u\", tunnel_id);\n \trwlock_init(&tunnel->hlist_lock);\n+\ttunnel->acpt_newsess = true;\n \n \t/* The net we belong to */\n \ttunnel->l2tp_net = net;\n@@ -1829,11 +1849,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn\n \t\t\treturn ERR_PTR(err);\n \t\t}\n \n-\t\tl2tp_tunnel_inc_refcount(tunnel);\n-\n-\t\t/* Ensure tunnel socket isn't deleted */\n-\t\tsock_hold(tunnel->sock);\n-\n \t\t/* Ignore management session in session count value */\n \t\tif (session->session_id != 0)\n \t\t\tatomic_inc(&l2tp_session_count);\ndiff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h\nindex 9101297f27ad..4593d48df953 100644\n--- a/net/l2tp/l2tp_core.h\n+++ b/net/l2tp/l2tp_core.h\n@@ -162,6 +162,10 @@ struct l2tp_tunnel {\n \tint\t\t\tmagic;\t\t/* Should be L2TP_TUNNEL_MAGIC */\n \tstruct rcu_head rcu;\n \trwlock_t\t\thlist_lock;\t/* protect session_hlist */\n+\tbool\t\t\tacpt_newsess;\t/* Indicates whether this\n+\t\t\t\t\t\t * tunnel accepts new sessions.\n+\t\t\t\t\t\t * Protected by hlist_lock.\n+\t\t\t\t\t\t */\n \tstruct hlist_head\tsession_hlist[L2TP_HASH_SIZE];\n \t\t\t\t\t\t/* hashed list of sessions,\n \t\t\t\t\t\t * hashed by id */\n",
    "prefixes": [
        "net",
        "1/2"
    ]
}