Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp2267879pxa; Mon, 3 Aug 2020 11:37:57 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwZbAE3p+6rp9ee4taORbiaY15dUq6J0VXA8ZPGl4qNWS2E/BzkyLF7Q2Rj2S+9IAOQdc5S X-Received: by 2002:aa7:c1d4:: with SMTP id d20mr9524252edp.81.1596479876833; Mon, 03 Aug 2020 11:37:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1596479876; cv=none; d=google.com; s=arc-20160816; b=U79qGEKpXkBFAeQWR5FCgvvv7ktfdJn1MogAVeDVJZMlPhbvARTcLGsZWlYLLo2RBz wqx5BcC5uFeeloFB35a4yBcbSgmpc1Wdo4DwIWnX1m25s/RVommyh9v9q260TtCNFsDw adPES7osBxmAiAE3aurAlt2CijtE+sXWAkKcBm1Xlv06A2/1+EV+HLbe0ab3N0v+RgbS nEal6jHe7Fk+ZeIq558pZwwyX6A8d5mkk5y84LS1HVhmODAzJ73HM2WwrJOzV6RDCUED Oii4wzvnlkk4NWF92SLPZ717e0aEYrdF7fnpPeeUW+UI/hKykWyeZaSsskI68fiVbACH EJ+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=zdMJ/kZbjayYZu6hB78fKbxhGiXLwV0qHCv1i8H0pn8=; b=FC9TdUjiZaFKNWnn7RTpRxu+EH7g72fFtgh1yj/061Ud54fCfUdKQWMC/0tv2HGUyE Lvs3Ke0k0a5pdqT2Lu1ORs/bNBcDv83M4v9zqp3ujVwtRfmK2NqpfbBDBaNksD2eZ2L+ pbm9s2dgWK15hBF1dqME4Cqhi1Clm13qkO6ghhAXeK2sAKd0dSLbG+a42g9UKDh79rdQ O/wa2LP68S/IFANFvlisKBpnBFhbMmyoj3qCEDy6uG/z8tBxtmCAmX/5a9cVE7QULc3U m8WMtsKeboILx+jzN4hPDs3l+tDSiJ9dwqAglRtP0jv5e0olZAwr8NVVZe9y3wRf+sYU YVWA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id e26si9499058edr.226.2020.08.03.11.37.34; Mon, 03 Aug 2020 11:37:56 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728680AbgHCSex (ORCPT + 99 others); Mon, 3 Aug 2020 14:34:53 -0400 Received: from mail-lj1-f193.google.com ([209.85.208.193]:40816 "EHLO mail-lj1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727951AbgHCSew (ORCPT ); Mon, 3 Aug 2020 14:34:52 -0400 Received: by mail-lj1-f193.google.com with SMTP id 185so30535436ljj.7 for ; Mon, 03 Aug 2020 11:34:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zdMJ/kZbjayYZu6hB78fKbxhGiXLwV0qHCv1i8H0pn8=; b=EkJUa5VokX6/r3A8jqfjOO6D3gV9sD3kVhfChxE1M0V+JZZ+KXI2om/1m88x2JX+v0 QiFonV70eUdssTB1z1mjAmYvFSWrUA/8LheyKaHLxtDIyKcLmP5wSeJDZLtpKX6KEV5a DnkhfuAji+K/dxpTrRLQ7Lt8Y/82jznjvWeuZTYL1Az067Qz77y+KYw0mJNpt5CGVPK1 eUjp0L4H0y8lm/FS/keQTQ4x0hSNfahFZ0TA5deZz6feuiAX4/L+unMAlle4f0gS9Vrk rIX27e1IDYiyBBbRbcUdrF3ZDMZvvCG7AH6tV4+ZW1UKKaaPDFcwcNvOevLwkC+pDY/2 rDSg== X-Gm-Message-State: AOAM531pehLzVfDqjq9XC67b5iPGcnBkSWT+cTM/9N+vGyl8z0PlmQWN bRw89SxvQgg0BlheLSRpeSK7ltEw X-Received: by 2002:a2e:9996:: with SMTP id w22mr9050733lji.446.1596479689156; Mon, 03 Aug 2020 11:34:49 -0700 (PDT) Received: from localhost.localdomain (broadband-37-110-38-130.ip.moscow.rt.ru. [37.110.38.130]) by smtp.googlemail.com with ESMTPSA id a16sm5150029ljj.108.2020.08.03.11.34.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Aug 2020 11:34:48 -0700 (PDT) From: Denis Efremov To: Julia Lawall Cc: Denis Efremov , cocci@systeme.lip6.fr, linux-kernel@vger.kernel.org Subject: [PATCH v7] coccinelle: api: add kfree_mismatch script Date: Mon, 3 Aug 2020 21:34:38 +0300 Message-Id: <20200803183438.34685-1-efremov@linux.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200605204237.85055-1-efremov@linux.com> References: <20200605204237.85055-1-efremov@linux.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Check that alloc and free types of functions match each other. Signed-off-by: Denis Efremov --- Changes in v2: - Lines are limited to 80 characters where possible - Confidence changed from High to Medium because of fs/btrfs/send.c:1119 false-positive - __vmalloc_area_node() explicitly excluded from analysis instead of !(file in "mm/vmalloc.c") condition Changes in v3: - prints style in org && report modes changed for python2 Changes in v4: - missing msg argument to print_todo fixed Changes in v5: - fix position p in kfree rule - move @kok and @v positions in choice rule after the arguments - remove kvmalloc suggestions Changes in v6: - more asterisks added in context mode - second @kok added to the choice rule Changes in v7: - file renamed to kfree_mismatch.cocci - python function relevant() removed - additional rule for filtering free positions added - btrfs false-positive fixed - confidence level changed to high - kvfree_switch rule added - names for position variables changed to @a (alloc) and @f (free) scripts/coccinelle/api/kfree_mismatch.cocci | 229 ++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 scripts/coccinelle/api/kfree_mismatch.cocci diff --git a/scripts/coccinelle/api/kfree_mismatch.cocci b/scripts/coccinelle/api/kfree_mismatch.cocci new file mode 100644 index 000000000000..9e9ef9fd7a25 --- /dev/null +++ b/scripts/coccinelle/api/kfree_mismatch.cocci @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// +/// Check that kvmalloc'ed memory is freed by kfree functions, +/// vmalloc'ed by vfree functions and kvmalloc'ed by kvfree +/// functions. +/// +// Confidence: High +// Copyright: (C) 2020 Denis Efremov ISPRAS +// Options: --no-includes --include-headers +// + +virtual patch +virtual report +virtual org +virtual context + +@alloc@ +expression E, E1; +position kok, vok; +@@ + +( + if (...) { + ... + E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\| + kmalloc_node\|kzalloc_node\|kmalloc_array\| + kmalloc_array_node\|kcalloc_node\)(...)@kok + ... + } else { + ... + E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\| + vzalloc_node\|vmalloc_exec\|vmalloc_32\| + vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\| + __vmalloc_node\)(...)@vok + ... + } +| + E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\|kzalloc_node\| + kmalloc_array\|kmalloc_array_node\|kcalloc_node\)(...)@kok + ... when != E = E1 + when any + if (E == NULL) { + ... + E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\| + vzalloc_node\|vmalloc_exec\|vmalloc_32\| + vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\| + __vmalloc_node\)(...)@vok + ... + } +) + +@free@ +expression E; +position fok; +@@ + + E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\| + kvmalloc_array\)(...) + ... + kvfree(E)@fok + +@vfree depends on !patch@ +expression E; +position a != alloc.kok; +position f != free.fok; +@@ + +* E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\| +* kzalloc_node\|kmalloc_array\|kmalloc_array_node\| +* kcalloc_node\)(...)@a + ... when != if (...) { ... E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\|__vmalloc_node\)(...); ... } + when != is_vmalloc_addr(E) + when any +* \(vfree\|vfree_atomic\|kvfree\)(E)@f + +@depends on patch exists@ +expression E; +position a != alloc.kok; +position f != free.fok; +@@ + + E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\| + kzalloc_node\|kmalloc_array\|kmalloc_array_node\| + kcalloc_node\)(...)@a + ... when != if (...) { ... E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\|__vmalloc_node\)(...); ... } + when != is_vmalloc_addr(E) + when any +- \(vfree\|vfree_atomic\|kvfree\)(E)@f ++ kfree(E) + +@kfree depends on !patch@ +expression E; +position a != alloc.vok; +position f != free.fok; +@@ + +* E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\| +* vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\| +* __vmalloc_node_range\|__vmalloc_node\)(...)@a + ... when != is_vmalloc_addr(E) + when any +* \(kfree\|kzfree\|kvfree\)(E)@f + +@depends on patch exists@ +expression E; +position a != alloc.vok; +position f != free.fok; +@@ + + E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\| + vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\| + __vmalloc_node_range\|__vmalloc_node\)(...)@a + ... when != is_vmalloc_addr(E) + when any +- \(kfree\|kvfree\)(E)@f ++ vfree(E) + +@kvfree depends on !patch@ +expression E; +position a, f; +@@ + +* E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\| +* kvmalloc_array\)(...)@a + ... when != is_vmalloc_addr(E) + when any +* \(kfree\|kzfree\|vfree\|vfree_atomic\)(E)@f + +@depends on patch exists@ +expression E; +@@ + + E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\| + kvmalloc_array\)(...) + ... when != is_vmalloc_addr(E) + when any +- \(kfree\|vfree\)(E) ++ kvfree(E) + +@kvfree_switch depends on !patch@ +expression alloc.E; +position f != free.fok; +@@ + + ... when != is_vmalloc_addr(E) + when any +* \(kfree\|kzfree\|vfree\|vfree_atomic\)(E)@f + +@depends on patch exists@ +expression alloc.E; +position f != free.fok; +@@ + + ... when != is_vmalloc_addr(E) + when any +( +- \(kfree\|vfree\)(E)@f ++ kvfree(E) +| +- kzfree(E)@f ++ kvfree_sensitive(E) +) + +@script: python depends on report@ +a << vfree.a; +f << vfree.f; +@@ + +msg = "WARNING: kmalloc is used to allocate this memory at line %s" % (a[0].line) +coccilib.report.print_report(f[0], msg) + +@script: python depends on org@ +a << vfree.a; +f << vfree.f; +@@ + +msg = "WARNING: kmalloc is used to allocate this memory at line %s" % (a[0].line) +coccilib.org.print_todo(f[0], msg) + +@script: python depends on report@ +a << kfree.a; +f << kfree.f; +@@ + +msg = "WARNING: vmalloc is used to allocate this memory at line %s" % (a[0].line) +coccilib.report.print_report(f[0], msg) + +@script: python depends on org@ +a << kfree.a; +f << kfree.f; +@@ + +msg = "WARNING: vmalloc is used to allocate this memory at line %s" % (a[0].line) +coccilib.org.print_todo(f[0], msg) + +@script: python depends on report@ +a << kvfree.a; +f << kvfree.f; +@@ + +msg = "WARNING: kvmalloc is used to allocate this memory at line %s" % (a[0].line) +coccilib.report.print_report(f[0], msg) + +@script: python depends on org@ +a << kvfree.a; +f << kvfree.f; +@@ + +msg = "WARNING: kvmalloc is used to allocate this memory at line %s" % (a[0].line) +coccilib.org.print_todo(f[0], msg) + +@script: python depends on report@ +ka << alloc.kok; +va << alloc.vok; +f << kvfree_switch.f; +@@ + +msg = "WARNING: kmalloc (line %s) && vmalloc (line %s) are used to allocate this memory" % (ka[0].line, va[0].line) +coccilib.report.print_report(f[0], msg) + +@script: python depends on org@ +ka << alloc.kok; +va << alloc.vok; +f << kvfree_switch.f; +@@ + +msg = "WARNING: kmalloc (line %s) && vmalloc (line %s) are used to allocate this memory" % (ka[0].line, va[0].line) +coccilib.org.print_todo(f[0], msg) + -- 2.26.2