From nobody Tue Jun 30 11:48:50 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81BD4C433EF for ; Mon, 17 Jan 2022 15:37:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234964AbiAQPhB (ORCPT ); Mon, 17 Jan 2022 10:37:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53750 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240516AbiAQPg7 (ORCPT ); Mon, 17 Jan 2022 10:36:59 -0500 Received: from mail-wm1-x349.google.com (mail-wm1-x349.google.com [IPv6:2a00:1450:4864:20::349]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84851C06161C for ; Mon, 17 Jan 2022 07:36:59 -0800 (PST) Received: by mail-wm1-x349.google.com with SMTP id p14-20020a1c544e000000b003490705086bso5364694wmi.7 for ; Mon, 17 Jan 2022 07:36:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=7DEaDOOzB1jAF1TPQvu7T4yVYcqfdELQFZk+rb6P+EE=; b=gGqm3c743gc+OxwlnzfyzsrMNdp8PEjKXHnHWIAoaPZgRaXyUT9Ka1fMKpsb4K6csI pbkCj8YnWSzX5gKSnhTAi9lLIHZaFBOdaJWabL4wd03YyJekI7agFrT9LcwZBqdslvh1 7cjnP/SpkCkNWy0h6Gfy9ffA7XCgqTrIh0eyAYLzvzcyQzYtiDgRo0xDOxcka4IlhDz8 ZDPm4mYyFmbGmvWIlPo3WOwVt031r2syrYpDZao2jQjgOsh4+0VKn2NnGwdTRSHR48EJ 0FrzeKXGxIEWMZdI6125z/+VnO5wAEAD2RtJolFyy55yC+iA44msasVJLnkyyOF+F2EP 23CA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=7DEaDOOzB1jAF1TPQvu7T4yVYcqfdELQFZk+rb6P+EE=; b=11YcENv9Nk4JG5/i/UrtICXSjkfUPwcYDXpJ29bhKhTe2wjLVVxjNzuVEF3csOD6dz 7qV36j3kP73mf+13wM6WU14zGo878cZI/y6t3jYdp83wfAq5z3RBcPOYwuomIoarEmzc 3JvX9Oe7hThdfCUXEm+I1JP6JeIB98rVDVgXadTmaIUcfkcr2/6PA4Mu83pLeHY/VWo4 PPGyWBZ+YgmrenrIo/InjZGMCkmsC/TVK2DIvJKQuj1GcW3vc4ZnC6uspg5/NLUXnygX 4AMohHLKLKssXEs9PGTknSICAOV1kFoOLBaN/hCYJZ97LgiqY9UaZrnKS6WFe/1eJMk5 JLJA== X-Gm-Message-State: AOAM533ya2KR/vdccPC1XySGPz5ME6S/H0Mp5fo6T5LICQ4yQIVl26R9 GNRCjY0TogPPxr/rtgQYPeRi5f1eWWw= X-Google-Smtp-Source: ABdhPJw94eVN6v05Qb6SLTmmPo9/f2iZyqc3QCp1wgQYcc5H97QS8wStMmt3kP/n6MBaM6ESzadOcsQSA6Y= X-Received: from nogikh-hp.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:200d]) (user=nogikh job=sendgmr) by 2002:a05:600c:1908:: with SMTP id j8mr6340226wmq.155.1642433817868; Mon, 17 Jan 2022 07:36:57 -0800 (PST) Date: Mon, 17 Jan 2022 15:36:33 +0000 In-Reply-To: <20220117153634.150357-1-nogikh@google.com> Message-Id: <20220117153634.150357-2-nogikh@google.com> Mime-Version: 1.0 References: <20220117153634.150357-1-nogikh@google.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog Subject: [PATCH v3 1/2] kcov: split ioctl handling into locked and unlocked parts From: Aleksandr Nogikh To: kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org, akpm@linux-foundation.org Cc: dvyukov@google.com, andreyknvl@gmail.com, elver@google.com, glider@google.com, tarasmadan@google.com, bigeasy@linutronix.de, nogikh@google.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Currently all ioctls are de facto processed under a spinlock in order to serialise them. This, however, prohibits the use of vmalloc and other memory management functions in the implementations of those ioctls, unnecessary complicating any further changes to the code. Let all ioctls first be processed inside the kcov_ioctl() function which should execute the ones that are not compatible with spinlock and then pass control to kcov_ioctl_locked() for all other ones. KCOV_REMOTE_ENABLE is processed both in kcov_ioctl() and kcov_ioctl_locked() as the steps are easily separable. Although it is still compatible with a spinlock, move KCOV_INIT_TRACE handling to kcov_ioctl(), so that the changes from the next commit are easier to follow. Signed-off-by: Aleksandr Nogikh Reviewed-by: Andrey Konovalov Reviewed-by: Dmitry Vyukov --- kernel/kcov.c | 68 ++++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/kernel/kcov.c b/kernel/kcov.c index 36ca640c4f8e..e1be7301500b 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -564,31 +564,12 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsig= ned int cmd, unsigned long arg) { struct task_struct *t; - unsigned long size, unused; + unsigned long flags, unused; int mode, i; struct kcov_remote_arg *remote_arg; struct kcov_remote *remote; - unsigned long flags; =20 switch (cmd) { - case KCOV_INIT_TRACE: - /* - * Enable kcov in trace mode and setup buffer size. - * Must happen before anything else. - */ - if (kcov->mode !=3D KCOV_MODE_DISABLED) - return -EBUSY; - /* - * Size must be at least 2 to hold current position and one PC. - * Later we allocate size * sizeof(unsigned long) memory, - * that must not overflow. - */ - size =3D arg; - if (size < 2 || size > INT_MAX / sizeof(unsigned long)) - return -EINVAL; - kcov->size =3D size; - kcov->mode =3D KCOV_MODE_INIT; - return 0; case KCOV_ENABLE: /* * Enable coverage for the current task. @@ -692,9 +673,32 @@ static long kcov_ioctl(struct file *filep, unsigned in= t cmd, unsigned long arg) struct kcov_remote_arg *remote_arg =3D NULL; unsigned int remote_num_handles; unsigned long remote_arg_size; - unsigned long flags; + unsigned long size, flags; =20 - if (cmd =3D=3D KCOV_REMOTE_ENABLE) { + kcov =3D filep->private_data; + switch (cmd) { + case KCOV_INIT_TRACE: + /* + * Enable kcov in trace mode and setup buffer size. + * Must happen before anything else. + * + * First check the size argument - it must be at least 2 + * to hold the current position and one PC. Later we allocate + * size * sizeof(unsigned long) memory, that must not overflow. + */ + size =3D arg; + if (size < 2 || size > INT_MAX / sizeof(unsigned long)) + return -EINVAL; + spin_lock_irqsave(&kcov->lock, flags); + if (kcov->mode !=3D KCOV_MODE_DISABLED) { + spin_unlock_irqrestore(&kcov->lock, flags); + return -EBUSY; + } + kcov->size =3D size; + kcov->mode =3D KCOV_MODE_INIT; + spin_unlock_irqrestore(&kcov->lock, flags); + return 0; + case KCOV_REMOTE_ENABLE: if (get_user(remote_num_handles, (unsigned __user *)(arg + offsetof(struct kcov_remote_arg, num_handles)))) return -EFAULT; @@ -710,16 +714,18 @@ static long kcov_ioctl(struct file *filep, unsigned i= nt cmd, unsigned long arg) return -EINVAL; } arg =3D (unsigned long)remote_arg; + fallthrough; + default: + /* + * All other commands can be normally executed under a spin lock, so we + * obtain and release it here in order to simplify kcov_ioctl_locked(). + */ + spin_lock_irqsave(&kcov->lock, flags); + res =3D kcov_ioctl_locked(kcov, cmd, arg); + spin_unlock_irqrestore(&kcov->lock, flags); + kfree(remote_arg); + return res; } - - kcov =3D filep->private_data; - spin_lock_irqsave(&kcov->lock, flags); - res =3D kcov_ioctl_locked(kcov, cmd, arg); - spin_unlock_irqrestore(&kcov->lock, flags); - - kfree(remote_arg); - - return res; } =20 static const struct file_operations kcov_fops =3D { --=20 2.34.1.703.g22d0c6ccf7-goog From nobody Tue Jun 30 11:48:50 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A7DA4C433F5 for ; Mon, 17 Jan 2022 15:37:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240530AbiAQPhE (ORCPT ); Mon, 17 Jan 2022 10:37:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53762 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237296AbiAQPhC (ORCPT ); Mon, 17 Jan 2022 10:37:02 -0500 Received: from mail-wm1-x349.google.com (mail-wm1-x349.google.com [IPv6:2a00:1450:4864:20::349]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2FE20C061574 for ; Mon, 17 Jan 2022 07:37:02 -0800 (PST) Received: by mail-wm1-x349.google.com with SMTP id w5-20020a1cf605000000b0034b8cb1f55eso5190179wmc.0 for ; Mon, 17 Jan 2022 07:37:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=1thsq464ntZ1Q6hN1oNhhbpxlas4Ufptak2u+5NaEgg=; b=Mu/4nG9MsWYJC0F8RgjvHauRdNem04cKRH+xztrPCTh8xwBL3zS9lULs+kndSOLPeg DCY1B7EiOfqzKPw5+gzRCFB/kqf1/Et/m0GCDDjCDo1KKkYmkFqlBfmhol/1RO4PGsFX vQy2wtJu4HzXh/XG1T88ibpsyL3WkYqxxDegotZDOkoy4Kuo+Q4JUBj+xxxXkDXHX8o+ oWmfg+Ou3VNd9Rwlk6zCBxYsLyi+l7Fhn9N7jhCWMHMNVN0/Nf7Hicrr+Jjb7sRWm/oZ to02tjLEO5wgUISZBZwXTyP6AzT4h6LjKeNTeIQqlHAStRY89nm5+gNWCHzz6wdtjpBe RPtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=1thsq464ntZ1Q6hN1oNhhbpxlas4Ufptak2u+5NaEgg=; b=E8z51Rzyggk9LxFrArQ1TzxrAW9wyZV5G+QxH5WSy/vtPuuHzDVhhUWZLRI2oPfgsn tp7df144i/V5Nti5xwE7SKLq3LQwceni+yEhklMbEFGVNE2GbI9SrQNgdZR2I8Y4Y4UA zqWKo6SMHPLEPdM0af5qsbRRvABwCFO6ng/SZ614DZUwmsLjOLOnbzJGgligbgRLc/gz VboT8hH+C9mR7etUELI2/h1HuH3Px8/oL35LE8Tug+SFv37ju0r4CoZqrmNe4EDHJvMy itR9Zw6ElOfT/7hAdVk2OmdrL7iC56pp/sb0YVNIAFCO/rLygejXvZOKpQx/cE63BzsN Cu2A== X-Gm-Message-State: AOAM533+mJmYQzdHYNBLJCtykqczJVSUxY+t6H7h7BQMyJBE21uCmzSK lvYRWple/6mRSU9z6zv/rp10d32Er9A= X-Google-Smtp-Source: ABdhPJyeOOYVbaUb669nA1YMRKxEqaGjPJjSEmytoc6GRzTaslfSLpD5JOlE0QEasuDhzg3ORCJRsiGtLYc= X-Received: from nogikh-hp.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:200d]) (user=nogikh job=sendgmr) by 2002:a05:600c:33a7:: with SMTP id o39mr20091461wmp.6.1642433820772; Mon, 17 Jan 2022 07:37:00 -0800 (PST) Date: Mon, 17 Jan 2022 15:36:34 +0000 In-Reply-To: <20220117153634.150357-1-nogikh@google.com> Message-Id: <20220117153634.150357-3-nogikh@google.com> Mime-Version: 1.0 References: <20220117153634.150357-1-nogikh@google.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog Subject: [PATCH v3 2/2] kcov: properly handle subsequent mmap calls From: Aleksandr Nogikh To: kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org, akpm@linux-foundation.org Cc: dvyukov@google.com, andreyknvl@gmail.com, elver@google.com, glider@google.com, tarasmadan@google.com, bigeasy@linutronix.de, nogikh@google.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allocate the kcov buffer during KCOV_MODE_INIT in order to untie mmapping of a kcov instance and the actual coverage collection process. Modify kcov_mmap, so that it can be reliably used any number of times once KCOV_MODE_INIT has succeeded. These changes to the user-facing interface of the tool only weaken the preconditions, so all existing user space code should remain compatible with the new version. Signed-off-by: Aleksandr Nogikh --- kernel/kcov.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/kernel/kcov.c b/kernel/kcov.c index e1be7301500b..475524bd900a 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -459,37 +459,28 @@ void kcov_task_exit(struct task_struct *t) static int kcov_mmap(struct file *filep, struct vm_area_struct *vma) { int res =3D 0; - void *area; struct kcov *kcov =3D vma->vm_file->private_data; unsigned long size, off; struct page *page; unsigned long flags; =20 - area =3D vmalloc_user(vma->vm_end - vma->vm_start); - if (!area) - return -ENOMEM; - spin_lock_irqsave(&kcov->lock, flags); size =3D kcov->size * sizeof(unsigned long); - if (kcov->mode !=3D KCOV_MODE_INIT || vma->vm_pgoff !=3D 0 || + if (kcov->area =3D=3D NULL || vma->vm_pgoff !=3D 0 || vma->vm_end - vma->vm_start !=3D size) { res =3D -EINVAL; goto exit; } - if (!kcov->area) { - kcov->area =3D area; - vma->vm_flags |=3D VM_DONTEXPAND; - spin_unlock_irqrestore(&kcov->lock, flags); - for (off =3D 0; off < size; off +=3D PAGE_SIZE) { - page =3D vmalloc_to_page(kcov->area + off); - if (vm_insert_page(vma, vma->vm_start + off, page)) - WARN_ONCE(1, "vm_insert_page() failed"); - } - return 0; + spin_unlock_irqrestore(&kcov->lock, flags); + vma->vm_flags |=3D VM_DONTEXPAND; + for (off =3D 0; off < size; off +=3D PAGE_SIZE) { + page =3D vmalloc_to_page(kcov->area + off); + if (vm_insert_page(vma, vma->vm_start + off, page)) + WARN_ONCE(1, "vm_insert_page() failed"); } + return 0; exit: spin_unlock_irqrestore(&kcov->lock, flags); - vfree(area); return res; } =20 @@ -674,6 +665,7 @@ static long kcov_ioctl(struct file *filep, unsigned int= cmd, unsigned long arg) unsigned int remote_num_handles; unsigned long remote_arg_size; unsigned long size, flags; + void *area; =20 kcov =3D filep->private_data; switch (cmd) { @@ -683,17 +675,21 @@ static long kcov_ioctl(struct file *filep, unsigned i= nt cmd, unsigned long arg) * Must happen before anything else. * * First check the size argument - it must be at least 2 - * to hold the current position and one PC. Later we allocate - * size * sizeof(unsigned long) memory, that must not overflow. + * to hold the current position and one PC. */ size =3D arg; if (size < 2 || size > INT_MAX / sizeof(unsigned long)) return -EINVAL; + area =3D vmalloc_user(size * sizeof(unsigned long)); + if (area =3D=3D NULL) + return -ENOMEM; spin_lock_irqsave(&kcov->lock, flags); if (kcov->mode !=3D KCOV_MODE_DISABLED) { spin_unlock_irqrestore(&kcov->lock, flags); + vfree(area); return -EBUSY; } + kcov->area =3D area; kcov->size =3D size; kcov->mode =3D KCOV_MODE_INIT; spin_unlock_irqrestore(&kcov->lock, flags); --=20 2.34.1.703.g22d0c6ccf7-goog