Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp2258799ybi; Mon, 17 Jun 2019 01:30:06 -0700 (PDT) X-Google-Smtp-Source: APXvYqw8ueT7VfA052W6bMIMCjI6Ljx3jjyECHOtHglOYThtq4BUxYtLQqUtoumxfdUM607wJcAu X-Received: by 2002:a17:902:d70a:: with SMTP id w10mr95420221ply.251.1560760206298; Mon, 17 Jun 2019 01:30:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560760206; cv=none; d=google.com; s=arc-20160816; b=zZZGwaCYoK0C1KjtpEDNrq/zSkNrAqmXbQ0J6YPVllJ0otP3vgEd8eN8H2m8Vb+ZzS cItqi4Qvde9jdnbRWTE6K9njKhkePq6OjQ7f1NRRTkYUwnMvDGchk15ajji0Sr3CjQkC PPOgqxFfhAFBb4ZY3nZaoZmt5HDASA9QEmZgEIV+sLKeeatxnYci4MrSFPy7GPPX0ttv YzBTLK9Jv0qmdg0oYjwZgbI/FgggLEOcFCG7xJvJzhNHxzd3nGMXAcLa0BxOcobss+Vr ENFEmS0wuCNVCrVyY7MiA4fPXCN63Y9X/gXzjTPcopOvosYTQrxpvrl19uNnO28ooAK7 PBBQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:dkim-signature; bh=/ISQXW436cOn3WhRGLbJ9YXLmMenEcf9xF+hXPXYF5c=; b=GAhaUkUw16SRcalCOqCOcmmtz6OF48twC3GM30L6XlaQjrFijwpk0YrvDEHCm4V5GX +pYcAXew761eZHVHar+XQbjev3cEN3AvRpjuQvWB8oBw8MKonZTb8e3joc4jWNwBuqMH 574kParAlIEfWeoyESotCngP93B4vJurTSf9NkYq0/k0NmoPhPCMureaE1UHsvVoAbvi Z5SLmaYen/7Pr5Di+TWZeD3PIyfF6ePOu9bqFOSfVlLQOFmUVXFovh2ixqAurPm/hgED QDHxpU3AP2il6oAwLS/hDAMtgBhRVOmOn93SXp805FUZLL6quEX9yEijzDFfn9UqvmQo gFbA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=q9hs4lJs; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t16si9837972pfh.100.2019.06.17.01.29.50; Mon, 17 Jun 2019 01:30:06 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=q9hs4lJs; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727627AbfFQI2G (ORCPT + 99 others); Mon, 17 Jun 2019 04:28:06 -0400 Received: from mail-vk1-f202.google.com ([209.85.221.202]:49907 "EHLO mail-vk1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728030AbfFQI2F (ORCPT ); Mon, 17 Jun 2019 04:28:05 -0400 Received: by mail-vk1-f202.google.com with SMTP id o202so4463181vko.16 for ; Mon, 17 Jun 2019 01:28:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=/ISQXW436cOn3WhRGLbJ9YXLmMenEcf9xF+hXPXYF5c=; b=q9hs4lJsRGRSrGfE4K7tsV6gzrKS8xRXv1xpeVXbTzg4iEF4Iy+z+LD294eu5AwX1u FVpUsarXkEqAn3XiMqwgQZ7VxJeit0iFOVCHVA21OmDcCLkEocIRMX/or7b3EyBeFDeV wb8JAlM/uHgm5InnMAV4ub0ijyPHcDqX6vCYkS3wto9ioInrPF6hRpccN7cJsAzLkJJl PfjqwGKW6yAMH4VjC6Dx9+eI56bXkGHRZYwLkZoS1+d4wKqJN/lHDubNmzQ6M3kPgZiI 6TB7GcqnFdVyUDNsCnwka+5MWH2TmznvwPE9sEieSXfmMOGw/9ePUvHVayr2Z7X6Rqpi QUow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=/ISQXW436cOn3WhRGLbJ9YXLmMenEcf9xF+hXPXYF5c=; b=h92Bx+Sv9KdTq2Z4XNwbbqIhMBG2wZCA9wAkoIxMlMt9/nFbcHWTQX5M4Wmg8X/vAv jfdtqdHP0ooPTOiJMrJ1UffwtwfOaSjovHjfrfedAl0C0x4dDh5Kc5VXqfxgahwOa2Pt t4y0ObbSWkZ1AYMEWvLgWPV/zUN0PKjZatbIZxHIC7RfT9qU1p5rKgB4Kt1GXV8rfY7T xrQTRnYXy92ORcS/ytVbCQoh+cTehnAKPVtmRDUUsuBIMFvZdRlu0Yvksj9tEvW8Kcdy gfl3v7HtGaDM58WMWPuqlsQH9neH5r8wymwNY+w6vhFEQN07McxVz6/IRyyQh1AJ1bND mB1w== X-Gm-Message-State: APjAAAVKe6W8vL5lthINyslMI3JNCeyFlYXFFNl8EsA3aDPHjWicOFPa 7Vns2fMhok+D8GhGzMOuvjxjC4hJJK23mUB7LLStfQ== X-Received: by 2002:a1f:3692:: with SMTP id d140mr21991020vka.88.1560760083990; Mon, 17 Jun 2019 01:28:03 -0700 (PDT) Date: Mon, 17 Jun 2019 01:26:12 -0700 In-Reply-To: <20190617082613.109131-1-brendanhiggins@google.com> Message-Id: <20190617082613.109131-18-brendanhiggins@google.com> Mime-Version: 1.0 References: <20190617082613.109131-1-brendanhiggins@google.com> X-Mailer: git-send-email 2.22.0.410.gd8fdbe21b5-goog Subject: [PATCH v5 17/18] kernel/sysctl-test: Add null pointer test for sysctl.c:proc_dointvec() From: Brendan Higgins To: frowand.list@gmail.com, gregkh@linuxfoundation.org, jpoimboe@redhat.com, keescook@google.com, kieran.bingham@ideasonboard.com, mcgrof@kernel.org, peterz@infradead.org, robh@kernel.org, sboyd@kernel.org, shuah@kernel.org, tytso@mit.edu, yamada.masahiro@socionext.com Cc: devicetree@vger.kernel.org, dri-devel@lists.freedesktop.org, kunit-dev@googlegroups.com, linux-doc@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-nvdimm@lists.01.org, linux-um@lists.infradead.org, Alexander.Levin@microsoft.com, Tim.Bird@sony.com, amir73il@gmail.com, dan.carpenter@oracle.com, daniel@ffwll.ch, jdike@addtoit.com, joel@jms.id.au, julia.lawall@lip6.fr, khilman@baylibre.com, knut.omang@oracle.com, logang@deltatee.com, mpe@ellerman.id.au, pmladek@suse.com, rdunlap@infradead.org, richard@nod.at, rientjes@google.com, rostedt@goodmis.org, wfg@linux.intel.com, Iurii Zaikin , Brendan Higgins Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Iurii Zaikin KUnit tests for initialized data behavior of proc_dointvec that is explicitly checked in the code. Includes basic parsing tests including int min/max overflow. Signed-off-by: Iurii Zaikin Signed-off-by: Brendan Higgins Reviewed-by: Greg Kroah-Hartman Reviewed-by: Logan Gunthorpe --- Changes Since Last Revision: - Iurii did some clean up (thanks Iurii!) as suggested by Stephen Boyd. --- kernel/Makefile | 2 + kernel/sysctl-test.c | 242 +++++++++++++++++++++++++++++++++++++++++++ lib/Kconfig.debug | 10 ++ 3 files changed, 254 insertions(+) create mode 100644 kernel/sysctl-test.c diff --git a/kernel/Makefile b/kernel/Makefile index a8d923b5481ba..50fd511cd0ee0 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -114,6 +114,8 @@ obj-$(CONFIG_HAS_IOMEM) += iomem.o obj-$(CONFIG_ZONE_DEVICE) += memremap.o obj-$(CONFIG_RSEQ) += rseq.o +obj-$(CONFIG_SYSCTL_KUNIT_TEST) += sysctl-test.o + obj-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak.o KASAN_SANITIZE_stackleak.o := n KCOV_INSTRUMENT_stackleak.o := n diff --git a/kernel/sysctl-test.c b/kernel/sysctl-test.c new file mode 100644 index 0000000000000..cb61ad3c7db63 --- /dev/null +++ b/kernel/sysctl-test.c @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KUnit test of proc sysctl. + */ + +#include +#include + +static int i_zero; +static int i_one_hundred = 100; + +struct test_sysctl_data { + int int_0001; + int int_0002; + int int_0003[4]; + + unsigned int uint_0001; + + char string_0001[65]; +}; + +static struct test_sysctl_data test_data = { + .int_0001 = 60, + .int_0002 = 1, + + .int_0003[0] = 0, + .int_0003[1] = 1, + .int_0003[2] = 2, + .int_0003[3] = 3, + + .uint_0001 = 314, + + .string_0001 = "(none)", +}; + +static void sysctl_test_dointvec_null_tbl_data(struct kunit *test) +{ + struct ctl_table table = { + .procname = "foo", + .data = NULL, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + .extra1 = &i_zero, + .extra2 = &i_one_hundred, + }; + void *buffer = kunit_kzalloc(test, sizeof(int), GFP_USER); + size_t len; + loff_t pos; + + len = 1234; + KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, 0, buffer, &len, &pos)); + KUNIT_EXPECT_EQ(test, (size_t)0, len); + len = 1234; + KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, 1, buffer, &len, &pos)); + KUNIT_EXPECT_EQ(test, (size_t)0, len); +} + +static void sysctl_test_dointvec_table_maxlen_unset(struct kunit *test) +{ + struct ctl_table table = { + .procname = "foo", + .data = &test_data.int_0001, + .maxlen = 0, + .mode = 0644, + .proc_handler = proc_dointvec, + .extra1 = &i_zero, + .extra2 = &i_one_hundred, + }; + void *buffer = kunit_kzalloc(test, sizeof(int), GFP_USER); + size_t len; + loff_t pos; + + len = 1234; + KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, 0, buffer, &len, &pos)); + KUNIT_EXPECT_EQ(test, (size_t)0, len); + len = 1234; + KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, 1, buffer, &len, &pos)); + KUNIT_EXPECT_EQ(test, (size_t)0, len); +} + +static void sysctl_test_dointvec_table_len_is_zero(struct kunit *test) +{ + struct ctl_table table = { + .procname = "foo", + .data = &test_data.int_0001, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + .extra1 = &i_zero, + .extra2 = &i_one_hundred, + }; + void *buffer = kunit_kzalloc(test, sizeof(int), GFP_USER); + size_t len; + loff_t pos; + + len = 0; + KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, 0, buffer, &len, &pos)); + KUNIT_EXPECT_EQ(test, (size_t)0, len); + KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, 1, buffer, &len, &pos)); + KUNIT_EXPECT_EQ(test, (size_t)0, len); +} + +static void sysctl_test_dointvec_table_read_but_position_set(struct kunit *test) +{ + struct ctl_table table = { + .procname = "foo", + .data = &test_data.int_0001, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + .extra1 = &i_zero, + .extra2 = &i_one_hundred, + }; + void *buffer = kunit_kzalloc(test, sizeof(int), GFP_USER); + size_t len; + loff_t pos; + + len = 1234; + pos = 1; + KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, 0, buffer, &len, &pos)); + KUNIT_EXPECT_EQ(test, (size_t)0, len); +} + +static void sysctl_test_dointvec_happy_single_positive(struct kunit *test) +{ + struct ctl_table table = { + .procname = "foo", + .data = &test_data.int_0001, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + .extra1 = &i_zero, + .extra2 = &i_one_hundred, + }; + char input[] = "9"; + size_t len = sizeof(input) - 1; + loff_t pos = 0; + + table.data = kunit_kzalloc(test, sizeof(int), GFP_USER); + KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, 1, input, &len, &pos)); + KUNIT_EXPECT_EQ(test, sizeof(input) - 1, len); + KUNIT_EXPECT_EQ(test, sizeof(input) - 1, (size_t)pos); + KUNIT_EXPECT_EQ(test, 9, ((int *)table.data)[0]); +} + +static void sysctl_test_dointvec_happy_single_negative(struct kunit *test) +{ + struct ctl_table table = { + .procname = "foo", + .data = &test_data.int_0001, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + .extra1 = &i_zero, + .extra2 = &i_one_hundred, + }; + char input[] = "-9"; + size_t len = sizeof(input) - 1; + loff_t pos = 0; + + table.data = kunit_kzalloc(test, sizeof(int), GFP_USER); + KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&table, 1, input, &len, &pos)); + KUNIT_EXPECT_EQ(test, sizeof(input) - 1, len); + KUNIT_EXPECT_EQ(test, sizeof(input) - 1, (size_t)pos); + KUNIT_EXPECT_EQ(test, -9, ((int *)table.data)[0]); +} + +static void sysctl_test_dointvec_single_less_int_min(struct kunit *test) +{ + struct ctl_table table = { + .procname = "foo", + .data = &test_data.int_0001, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + .extra1 = &i_zero, + .extra2 = &i_one_hundred, + }; + char input[32]; + size_t len = sizeof(input) - 1; + loff_t pos = 0; + unsigned long abs_of_less_than_min = (unsigned long)INT_MAX + - (INT_MAX + INT_MIN) + 1; + + KUNIT_EXPECT_LT(test, + (size_t)snprintf(input, sizeof(input), "-%lu", + abs_of_less_than_min), + sizeof(input)); + + table.data = kunit_kzalloc(test, sizeof(int), GFP_USER); + KUNIT_EXPECT_EQ(test, -EINVAL, + proc_dointvec(&table, 1, input, &len, &pos)); + KUNIT_EXPECT_EQ(test, sizeof(input) - 1, len); + KUNIT_EXPECT_EQ(test, 0, ((int *)table.data)[0]); +} + +static void sysctl_test_dointvec_single_greater_int_max(struct kunit *test) +{ + struct ctl_table table = { + .procname = "foo", + .data = &test_data.int_0001, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + .extra1 = &i_zero, + .extra2 = &i_one_hundred, + }; + char input[32]; + size_t len = sizeof(input) - 1; + loff_t pos = 0; + unsigned long greater_than_max = (unsigned long)INT_MAX + 1; + + KUNIT_EXPECT_GT(test, greater_than_max, (unsigned long)INT_MAX); + KUNIT_EXPECT_LT(test, (size_t)snprintf(input, sizeof(input), "%lu", + greater_than_max), + sizeof(input)); + table.data = kunit_kzalloc(test, sizeof(int), GFP_USER); + KUNIT_EXPECT_EQ(test, -EINVAL, + proc_dointvec(&table, 1, input, &len, &pos)); + KUNIT_EXPECT_EQ(test, sizeof(input) - 1, len); + KUNIT_EXPECT_EQ(test, 0, ((int *)table.data)[0]); +} + +static struct kunit_case sysctl_test_cases[] = { + KUNIT_CASE(sysctl_test_dointvec_null_tbl_data), + KUNIT_CASE(sysctl_test_dointvec_table_maxlen_unset), + KUNIT_CASE(sysctl_test_dointvec_table_len_is_zero), + KUNIT_CASE(sysctl_test_dointvec_table_read_but_position_set), + KUNIT_CASE(sysctl_test_dointvec_happy_single_positive), + KUNIT_CASE(sysctl_test_dointvec_happy_single_negative), + KUNIT_CASE(sysctl_test_dointvec_single_less_int_min), + KUNIT_CASE(sysctl_test_dointvec_single_greater_int_max), + {} +}; + +static struct kunit_module sysctl_test_module = { + .name = "sysctl_test", + .test_cases = sysctl_test_cases, +}; + +module_test(sysctl_test_module); diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index cbdfae3798965..389b8986f5b77 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1939,6 +1939,16 @@ config TEST_SYSCTL If unsure, say N. +config SYSCTL_KUNIT_TEST + bool "KUnit test for sysctl" + depends on KUNIT + help + This builds the proc sysctl unit test, which runs on boot. For more + information on KUnit and unit tests in general please refer to the + KUnit documentation in Documentation/dev-tools/kunit/. + + If unsure, say N. + config TEST_UDELAY tristate "udelay test driver" help -- 2.22.0.410.gd8fdbe21b5-goog