Show a cover letter.

GET /api/covers/110565/?format=api
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 110565,
    "url": "http://patches.dpdk.org/api/covers/110565/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/cover/20220502192238.348172-1-quentin@armitage.org.uk/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20220502192238.348172-1-quentin@armitage.org.uk>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220502192238.348172-1-quentin@armitage.org.uk",
    "date": "2022-05-02T19:22:37",
    "name": "[0/1] tap: fix write-after-free and double free of intr_handle",
    "submitter": {
        "id": 2676,
        "url": "http://patches.dpdk.org/api/people/2676/?format=api",
        "name": "Quentin Armitage",
        "email": "quentin@armitage.org.uk"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/cover/20220502192238.348172-1-quentin@armitage.org.uk/mbox/",
    "series": [
        {
            "id": 22761,
            "url": "http://patches.dpdk.org/api/series/22761/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=22761",
            "date": "2022-05-02T19:22:37",
            "name": "tap: fix write-after-free and double free of intr_handle",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/22761/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/covers/110565/comments/",
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 76445A00C2;\n\tMon,  2 May 2022 21:23:06 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 2530340C35;\n\tMon,  2 May 2022 21:23:06 +0200 (CEST)",
            "from nabal.armitage.org.uk (host-92-27-6-192.static.as13285.net\n [92.27.6.192]) by mails.dpdk.org (Postfix) with ESMTP id EFCF44069D\n for <dev@dpdk.org>; Mon,  2 May 2022 21:23:04 +0200 (CEST)",
            "from localhost (nabal.armitage.org.uk [127.0.0.1])\n by nabal.armitage.org.uk (Postfix) with ESMTP id 85B3A2E42D2;\n Mon,  2 May 2022 20:23:04 +0100 (BST)",
            "from samson.armitage.org.uk (samson.armitage.org.uk\n [IPv6:2001:470:69dd:35::210])\n by nabal.armitage.org.uk (Postfix) with ESMTPSA id 65DE92E40A4;\n Mon,  2 May 2022 20:22:47 +0100 (BST)"
        ],
        "Authentication-Results": "nabal.armitage.org.uk (amavisd-new);\n dkim=pass (1024-bit key) reason=\"pass (just generated, assumed good)\"\n header.d=armitage.org.uk",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=armitage.org.uk;\n h=content-transfer-encoding:mime-version:x-mailer:message-id\n :date:date:subject:subject:from:from:received; s=20200110; t=\n 1651519367; x=1652383368; bh=O0/gkYCGQ4ya8w+F/Y0URbtQiPQLujsvP35\n jIlphe0Y=; b=US6xVZMGxyZiZrBuOxahyYsN1vfwk5mSbzaMhRUdFg++k+Z9G9s\n dnJ4doOSVzWLU2nvUxSvAefE+xQacqiiRIIQB9P9RmTUfYnFS+DaBn6iglBkMlXE\n +MgK49AIIbwMV93jz8iBygHVcmBLz9+TJCj6ldlWqD3A5zArrYlGZ1aE=",
        "X-Virus-Scanned": "amavisd-new at armitage.org.uk",
        "From": "Quentin Armitage <quentin@armitage.org.uk>",
        "To": "dev@dpdk.org",
        "Cc": "Quentin Armitage <quentin@armitage.org.uk>",
        "Subject": "[PATCH 0/1] tap: fix write-after-free and double free of intr_handle",
        "Date": "Mon,  2 May 2022 20:22:37 +0100",
        "Message-Id": "<20220502192238.348172-1-quentin@armitage.org.uk>",
        "X-Mailer": "git-send-email 2.34.1",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "Starting and stopping a tap device results in the following output:\n  tap_lsc_intr_handle_set(): intr callback unregister failed: -2\n  free(): invalid pointer\nand a core dump is generated due to abort() being called.\n\nAlthough the stack backtrace below gives line numbers for dpdk-21.11, this problem\nstill occurs with the current HEAD of the development tree (commit 7615ec581).\n\nThe stack backtrace is:\n\n#0  0x00007f80741d12a2 in raise () from /lib64/libc.so.6\n#1  0x00007f80741ba8a4 in abort () from /lib64/libc.so.6\n#2  0x00007f8074213ac7 in __libc_message () from /lib64/libc.so.6\n#3  0x00007f807421b73c in malloc_printerr () from /lib64/libc.so.6\n#4  0x00007f807421c97c in _int_free () from /lib64/libc.so.6\n#5  0x00007f80742207a8 in free () from /lib64/libc.so.6\n#6  0x00007f8074374bf5 in rte_intr_instance_free (intr_handle=intr_handle@entry=0x1003b2480) at ../lib/eal/common/eal_common_interrupts.c:184\n#7  0x00007f8072bf16ce in tap_rx_intr_vec_uninstall (dev=dev@entry=0x7f80744ed480 <rte_eth_devices>) at ../drivers/net/tap/tap_intr.c:38\n#8  0x00007f8072bf18d3 in tap_rx_intr_vec_set (dev=dev@entry=0x7f80744ed480 <rte_eth_devices>, set=set@entry=0) at ../drivers/net/tap/tap_intr.c:111\n#9  0x00007f8072bea742 in tap_intr_handle_set (dev=dev@entry=0x7f80744ed480 <rte_eth_devices>, set=set@entry=0) at ../drivers/net/tap/rte_eth_tap.c:1727\n#10 0x00007f8072bea7d0 in tap_dev_stop (dev=0x7f80744ed480 <rte_eth_devices>) at ../drivers/net/tap/rte_eth_tap.c:916\n#11 0x00007f80744875a4 in rte_eth_dev_stop (port_id=<optimized out>) at ../lib/ethdev/rte_ethdev.c:1883\n#12 0x000000000040158b in main (argc=4, argv=0x7ffd13cfc368) at tap_free.c:59\n\nA sample program to demonstrate the problem is\n=======================================================================\n// Run as: build/tap_free --vdev=net_tap0,remote=PORT -l 0,1\n\n#include <stdio.h>\n\n#include <rte_eal.h>\n#include <rte_ethdev.h>\n#include <rte_mbuf.h>\n\nint\nmain(int argc, char *argv[])\n{\n\tuint16_t port_id;\n\tstruct rte_mempool *mbuf_pool;\n\tstruct rte_eth_conf port_conf;\n\tstruct rte_eth_dev_info dev_info;\n\tuint16_t nb_rxd = 1024;\n\tuint16_t nb_txd = 1024;\n\tstruct rte_eth_txconf txconf;\n\n\tif (rte_eal_init(argc, argv) < 0)\n\t\trte_exit(EXIT_FAILURE, \"Error with EAL initialization\\n\");\n\n\tif (rte_eth_dev_count_avail() < 1)\n\t\trte_exit(EXIT_FAILURE, \"Error: should have at least 1 port\\n\");\n\n\tport_id = rte_eth_find_next_owned_by(0, RTE_ETH_DEV_NO_OWNER);\n\n\tmbuf_pool = rte_pktmbuf_pool_create(\"mbuf_pool\", 1023, 256, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());\n\n\tif (!rte_eth_dev_is_valid_port(port_id))\n\t\trte_exit(1, \"a\\n\");\n\n\tmemset(&port_conf, 0, sizeof(struct rte_eth_conf));\n\n\tif (rte_eth_dev_info_get(port_id, &dev_info))\n\t\trte_exit(1, \"b\\n\");\n\n\tif (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)\n                port_conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;\n\n\tif (rte_eth_dev_configure(port_id, 1, 1, &port_conf))\n\t\trte_exit(1, \"c\\n\");\n\n\tif (rte_eth_dev_adjust_nb_rx_tx_desc(port_id, &nb_rxd, &nb_txd))\n\t\trte_exit(1, \"d\\n\");\n\n\tif (rte_eth_rx_queue_setup(port_id, 0, nb_rxd, rte_eth_dev_socket_id(port_id), NULL, mbuf_pool) < 0)\n\t\trte_exit(1, \"e\\n\");\n\n\ttxconf = dev_info.default_txconf;\n        txconf.offloads = port_conf.txmode.offloads;\n\tif (rte_eth_tx_queue_setup(port_id, 0, nb_txd, rte_eth_dev_socket_id(port_id), &txconf) < 0)\n\t\trte_exit(1, \"f\\n\");\n\n\tif (rte_eth_dev_start(port_id) < 0)\n\t\trte_exit(1, \"g\\n\");\n\n\tprintf(\"Calling rte_eth_dev_stop - will error without patch\\n\"); fflush(stdout);\n\trte_eth_dev_stop(port_id);\n\tprintf(\"Returned from rte_eth_dev_stop\\n\"); fflush(stdout);\n\trte_eth_dev_close(port_id);\n\n\trte_eal_cleanup();\n}\n=======================================\n\nThis problem is caused by tap_tx_intr_vec_uninstall() calling\nrte_intr_instance_free() which frees pmd->intr_handle (and it doesn't\nset pmd->intr_handle to NULL, although this is not the cause of the issue).\n\nWhen tap_rx_intr_vec_uninstall() is called from tap_rx_intr_vec_set() with\nthe set parameter != 0, which occurs when rte_eth_dev_start() is called,\nit frees pmd->intr_handle, and tap_rx_intr_vec_install() is subsequently\ncalled. If intr_conf.rxq is not set, this does not cause an immediate\nproblem, but if it is set, it will write to (the now) unallocated memory.\n\nThe main problem occurs when tap_dev_stop() is called which in turn calls\ntap_intr_handle_set() and tap_lsc_intr_handle_set(). This uses\npmd->intr_handle which has now been overwritten due to being previously\nfreed. When rte_intr_instance_free() is called via tap_rx_intr_vec_uninstall(),\ndue to intr_handle->alloc_flags having been overwritten by a subsequent\nuser of that memory, it enters the wrong block and calls free() rather\nthan rte_free(). This causes free() to call abort().\n\n\n Quentin Armitage (1):\n   tap: fix write-after-free and double free of intr_handle\n\n drivers/net/tap/rte_eth_tap.c | 5 +++++\n drivers/net/tap/tap_intr.c    | 2 --\n 2 files changed, 5 insertions(+), 2 deletions(-)"
}