Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp5420516rwb; Mon, 21 Nov 2022 22:56:06 -0800 (PST) X-Google-Smtp-Source: AA0mqf4oZGWqw79DlU+RHls6M4y5x40l2FavpAdl6KrLRnMLHI5KBvK4KhO/dS/uPrfs/vhyKw1e X-Received: by 2002:a05:6402:c6:b0:468:3d69:ace0 with SMTP id i6-20020a05640200c600b004683d69ace0mr2670969edu.356.1669100166639; Mon, 21 Nov 2022 22:56:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669100166; cv=none; d=google.com; s=arc-20160816; b=SobkQ8A61N7VmDmopNv2ajZUOjedGI9KlMm9zG1zBzai+OqG7wdKXcVBGQNuX0COHh z7Y1lQxh1ppa2QyOlkvA3cm7ZKztFVR12Hvas/NyaMR9I7I88AK6faxuCZB7K6ZJAzjX Ayb+nrVpG7rm37/gJ4B/E804cXynk0g00ojLk3aIVIjA3ELq23abz2KjP+6Q3j/qIC35 /QOkSp1Iv1E9G2y3kK+Ncjx03S6zuvWgBWeDKnL1+F70GpaR5WazfsMX4U3WBJKeyTf+ XByCNMr6rQ1JW4hSmuRfDocL6+DfUPZh6PuTezIHYs5N/KHiVewtO6IXXx4UXTdFFaJE s+6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to :organization:from:references:cc:to:content-language:subject :user-agent:mime-version:date:message-id:dkim-signature; bh=nygFvcCyEa3LQ0HMu22VlGtyNHOIl6bbcNe2rVT6CC0=; b=FGPaiSu1KU5Qd2Xg8oj9t4UOgwiNLHX5ibHxWMD7i2bQUS5Tid+MAp1p6RLHe7Rqgg N+MVMO9ippk0mI4mxKJxVU56ZrvFiRYSa2POyy8xLvv1zXgUL6JyjhoDzKGdWYEoLSZ0 xU9uCUM8ZFO67vco4LcpNd7Dj0b0S4NviAUUMs4598VV90S4cM9nWDhOERfGAEvDGutF SV+AV/f/POU3R8yNHpPr1/z6F9/chgUkAEMedct1hmwDg2AT6qHy38f94wrAX+XGS/j1 40sGCWJLlnIWZDfWgfRiNxMVJOcV+zkX3z9ohVRuMTldKAsVYzmAUjdU/iQa96CuxHo7 O2cQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@canonical.com header.s=20210705 header.b=UGwtQGzD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=canonical.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b25-20020a1709065e5900b00730aa841c5bsi9003792eju.964.2022.11.21.22.55.44; Mon, 21 Nov 2022 22:56:06 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@canonical.com header.s=20210705 header.b=UGwtQGzD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=canonical.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230070AbiKVGU3 (ORCPT + 91 others); Tue, 22 Nov 2022 01:20:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38614 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229468AbiKVGU1 (ORCPT ); Tue, 22 Nov 2022 01:20:27 -0500 Received: from smtp-relay-canonical-0.canonical.com (smtp-relay-canonical-0.canonical.com [185.125.188.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DD4192B616; Mon, 21 Nov 2022 22:20:25 -0800 (PST) Received: from [192.168.192.83] (unknown [50.47.159.196]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by smtp-relay-canonical-0.canonical.com (Postfix) with ESMTPSA id 80CE73FA82; Tue, 22 Nov 2022 06:20:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1669098024; bh=nygFvcCyEa3LQ0HMu22VlGtyNHOIl6bbcNe2rVT6CC0=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=UGwtQGzD6AaLz7y76fkaSksLivBzoOPNdiCEnoHah3MIda/cMtMEAfpWru8JF5A7/ dhAFZn3IFh79cU2frI9uOeAc1JGgg/5TSMqXUaH+SQrhEzh7mbrOOfvE8m4i0PALuq AWy770kRoc1G6lUUr5JUDLJON1sTUrfLmUj6cxynA0ZHvj114ieyzK3trdzuuoAvLe za1DroiKBQSUrzNMdj7BU049sSnIcYjFMJEnReoWkjqlPJvGng3tKGGPJUXKYpxU9k XSNj+ySobO62I38sV/pG8rQ9aUc2IH+jvRcaTjPaanC5hS0q7FU2uEgoT2pvjg4oCK TL5MUnLynMxdQ== Message-ID: <3fbf707a-fc9e-18c6-dc40-ec266bd524e5@canonical.com> Date: Mon, 21 Nov 2022 22:20:20 -0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.2 Subject: Re: [PATCH v1 2/2] apparmor: test: make static symbols visible during kunit testing Content-Language: en-US To: Rae Moar , brendanhiggins@google.com, davidgow@google.com, dlatypov@google.com Cc: skhan@linuxfoundation.org, tales.aparecida@gmail.com, kunit-dev@googlegroups.com, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, apparmor@lists.ubuntu.com References: <20221102175959.2921063-1-rmoar@google.com> <20221102175959.2921063-3-rmoar@google.com> From: John Johansen Organization: Canonical In-Reply-To: <20221102175959.2921063-3-rmoar@google.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NICE_REPLY_A, RCVD_IN_DNSWL_MED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 11/2/22 10:59, Rae Moar wrote: > Use macros, VISIBLE_IF_KUNIT and EXPORT_SYMBOL_IF_KUNIT, to allow > static symbols to be conditionally set to be visible during KUnit > testing. Remove the need to include testing file in the implementation > file. Provide example of how static symbols can be dealt with in > testing. > > Signed-off-by: Rae Moar > --- > security/apparmor/Kconfig | 4 +- > security/apparmor/Makefile | 2 + > security/apparmor/include/policy_unpack.h | 50 ++++++++++++++++ > security/apparmor/policy_unpack.c | 72 +++++++---------------- > security/apparmor/policy_unpack_test.c | 5 ++ > 5 files changed, 80 insertions(+), 53 deletions(-) > > diff --git a/security/apparmor/Kconfig b/security/apparmor/Kconfig > index cb3496e00d8a..f334e7cccf2d 100644 > --- a/security/apparmor/Kconfig > +++ b/security/apparmor/Kconfig > @@ -106,8 +106,8 @@ config SECURITY_APPARMOR_PARANOID_LOAD > Disabling the check will speed up policy loads. > > config SECURITY_APPARMOR_KUNIT_TEST > - bool "Build KUnit tests for policy_unpack.c" if !KUNIT_ALL_TESTS > - depends on KUNIT=y && SECURITY_APPARMOR > + tristate "Build KUnit tests for policy_unpack.c" if !KUNIT_ALL_TESTS > + depends on KUNIT && SECURITY_APPARMOR > default KUNIT_ALL_TESTS > help > This builds the AppArmor KUnit tests. > diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile > index ff23fcfefe19..6a92428375eb 100644 > --- a/security/apparmor/Makefile > +++ b/security/apparmor/Makefile > @@ -8,6 +8,8 @@ apparmor-y := apparmorfs.o audit.o capability.o task.o ipc.o lib.o match.o \ > resource.o secid.o file.o policy_ns.o label.o mount.o net.o > apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o > > +obj-$(CONFIG_SECURITY_APPARMOR_KUNIT_TEST) += policy_unpack_test.o > + > clean-files := capability_names.h rlim_names.h net_names.h > > # Build a lower case string table of address family names > diff --git a/security/apparmor/include/policy_unpack.h b/security/apparmor/include/policy_unpack.h > index eb5f7d7f132b..a963687bcc9b 100644 > --- a/security/apparmor/include/policy_unpack.h > +++ b/security/apparmor/include/policy_unpack.h > @@ -48,6 +48,43 @@ enum { > AAFS_LOADDATA_NDENTS /* count of entries */ > }; > > +/* > + * The AppArmor interface treats data as a type byte followed by the > + * actual data. The interface has the notion of a named entry > + * which has a name (AA_NAME typecode followed by name string) followed by > + * the entries typecode and data. Named types allow for optional > + * elements and extensions to be added and tested for without breaking > + * backwards compatibility. > + */ > + > +enum aa_code { > + AA_U8, > + AA_U16, > + AA_U32, > + AA_U64, > + AA_NAME, /* same as string except it is items name */ > + AA_STRING, > + AA_BLOB, > + AA_STRUCT, > + AA_STRUCTEND, > + AA_LIST, > + AA_LISTEND, > + AA_ARRAY, > + AA_ARRAYEND, > +}; > + > +/* > + * aa_ext is the read of the buffer containing the serialized profile. The > + * data is copied into a kernel buffer in apparmorfs and then handed off to > + * the unpack routines. > + */ > +struct aa_ext { > + void *start; > + void *end; > + void *pos; /* pointer to current position in the buffer */ > + u32 version; > +}; > + hrmmm, I prefer these symbols to be only available to the unpack code but can live with them being more widely available. > /* > * struct aa_loaddata - buffer of policy raw_data set > * > @@ -126,4 +163,17 @@ static inline void aa_put_loaddata(struct aa_loaddata *data) > kref_put(&data->count, aa_loaddata_kref); > } > > +#if IS_ENABLED(CONFIG_KUNIT) > +bool inbounds(struct aa_ext *e, size_t size); > +size_t unpack_u16_chunk(struct aa_ext *e, char **chunk); > +bool unpack_X(struct aa_ext *e, enum aa_code code); > +bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name); > +bool unpack_u32(struct aa_ext *e, u32 *data, const char *name); > +bool unpack_u64(struct aa_ext *e, u64 *data, const char *name); > +size_t unpack_array(struct aa_ext *e, const char *name); > +size_t unpack_blob(struct aa_ext *e, char **blob, const char *name); > +int unpack_str(struct aa_ext *e, const char **string, const char *name); > +int unpack_strdup(struct aa_ext *e, char **string, const char *name); So this is a problem. If this symbols are going to be visible outside of the unpack code they need to be prefixed with aa_ to help avoid collisions with other kernel code. > +#endif > + > #endif /* __POLICY_INTERFACE_H */ > diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c > index 55d31bac4f35..c23aa70349aa 100644 > --- a/security/apparmor/policy_unpack.c > +++ b/security/apparmor/policy_unpack.c > @@ -14,6 +14,7 @@ > */ > > #include > +#include > #include > #include > #include > @@ -37,43 +38,6 @@ > #define v7 7 > #define v8 8 /* full network masking */ > > -/* > - * The AppArmor interface treats data as a type byte followed by the > - * actual data. The interface has the notion of a named entry > - * which has a name (AA_NAME typecode followed by name string) followed by > - * the entries typecode and data. Named types allow for optional > - * elements and extensions to be added and tested for without breaking > - * backwards compatibility. > - */ > - > -enum aa_code { > - AA_U8, > - AA_U16, > - AA_U32, > - AA_U64, > - AA_NAME, /* same as string except it is items name */ > - AA_STRING, > - AA_BLOB, > - AA_STRUCT, > - AA_STRUCTEND, > - AA_LIST, > - AA_LISTEND, > - AA_ARRAY, > - AA_ARRAYEND, > -}; > - > -/* > - * aa_ext is the read of the buffer containing the serialized profile. The > - * data is copied into a kernel buffer in apparmorfs and then handed off to > - * the unpack routines. > - */ > -struct aa_ext { > - void *start; > - void *end; > - void *pos; /* pointer to current position in the buffer */ > - u32 version; > -}; > - > /* audit callback for unpack fields */ > static void audit_cb(struct audit_buffer *ab, void *va) > { > @@ -199,10 +163,11 @@ struct aa_loaddata *aa_loaddata_alloc(size_t size) > } > > /* test if read will be in packed data bounds */ > -static bool inbounds(struct aa_ext *e, size_t size) > +VISIBLE_IF_KUNIT bool inbounds(struct aa_ext *e, size_t size) > { > return (size <= e->end - e->pos); > } > +EXPORT_SYMBOL_IF_KUNIT(inbounds); > > static void *kvmemdup(const void *src, size_t len) > { > @@ -220,7 +185,7 @@ static void *kvmemdup(const void *src, size_t len) > * > * Returns: the size of chunk found with the read head at the end of the chunk. > */ > -static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk) > +VISIBLE_IF_KUNIT size_t unpack_u16_chunk(struct aa_ext *e, char **chunk) > { > size_t size = 0; > void *pos = e->pos; > @@ -239,9 +204,10 @@ static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk) > e->pos = pos; > return 0; > } > +EXPORT_SYMBOL_IF_KUNIT(unpack_u16_chunk); > > /* unpack control byte */ > -static bool unpack_X(struct aa_ext *e, enum aa_code code) > +VISIBLE_IF_KUNIT bool unpack_X(struct aa_ext *e, enum aa_code code) > { > if (!inbounds(e, 1)) > return false; > @@ -250,6 +216,7 @@ static bool unpack_X(struct aa_ext *e, enum aa_code code) > e->pos++; > return true; > } > +EXPORT_SYMBOL_IF_KUNIT(unpack_X); > > /** > * unpack_nameX - check is the next element is of type X with a name of @name > @@ -267,7 +234,7 @@ static bool unpack_X(struct aa_ext *e, enum aa_code code) > * > * Returns: false if either match fails, the read head does not move > */ > -static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name) > +VISIBLE_IF_KUNIT bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name) > { > /* > * May need to reset pos if name or type doesn't match > @@ -296,6 +263,7 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name) > e->pos = pos; > return false; > } > +EXPORT_SYMBOL_IF_KUNIT(unpack_nameX); > > static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name) > { > @@ -315,7 +283,7 @@ static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name) > return false; > } > > -static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) > +VISIBLE_IF_KUNIT bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) > { > void *pos = e->pos; > > @@ -332,8 +300,9 @@ static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) > e->pos = pos; > return false; > } > +EXPORT_SYMBOL_IF_KUNIT(unpack_u32); > > -static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name) > +VISIBLE_IF_KUNIT bool unpack_u64(struct aa_ext *e, u64 *data, const char *name) > { > void *pos = e->pos; > > @@ -350,8 +319,9 @@ static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name) > e->pos = pos; > return false; > } > +EXPORT_SYMBOL_IF_KUNIT(unpack_u64); > > -static size_t unpack_array(struct aa_ext *e, const char *name) > +VISIBLE_IF_KUNIT size_t unpack_array(struct aa_ext *e, const char *name) > { > void *pos = e->pos; > > @@ -368,8 +338,9 @@ static size_t unpack_array(struct aa_ext *e, const char *name) > e->pos = pos; > return 0; > } > +EXPORT_SYMBOL_IF_KUNIT(unpack_array); > > -static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name) > +VISIBLE_IF_KUNIT size_t unpack_blob(struct aa_ext *e, char **blob, const char *name) > { > void *pos = e->pos; > > @@ -390,8 +361,9 @@ static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name) > e->pos = pos; > return 0; > } > +EXPORT_SYMBOL_IF_KUNIT(unpack_blob); > > -static int unpack_str(struct aa_ext *e, const char **string, const char *name) > +VISIBLE_IF_KUNIT int unpack_str(struct aa_ext *e, const char **string, const char *name) > { > char *src_str; > size_t size = 0; > @@ -413,8 +385,9 @@ static int unpack_str(struct aa_ext *e, const char **string, const char *name) > e->pos = pos; > return 0; > } > +EXPORT_SYMBOL_IF_KUNIT(unpack_str); > > -static int unpack_strdup(struct aa_ext *e, char **string, const char *name) > +VISIBLE_IF_KUNIT int unpack_strdup(struct aa_ext *e, char **string, const char *name) > { > const char *tmp; > void *pos = e->pos; > @@ -432,6 +405,7 @@ static int unpack_strdup(struct aa_ext *e, char **string, const char *name) > > return res; > } > +EXPORT_SYMBOL_IF_KUNIT(unpack_strdup); > Again if the symbols are going to be exported they need the aa_ prefix But I am not sure this is worth doing, exporting a lot of symbols just so the test code can be built as a module doesn't seem worth it to me. > > /** > @@ -1251,7 +1225,3 @@ int aa_unpack(struct aa_loaddata *udata, struct list_head *lh, > > return error; > } > - > -#ifdef CONFIG_SECURITY_APPARMOR_KUNIT_TEST > -#include "policy_unpack_test.c" > -#endif /* CONFIG_SECURITY_APPARMOR_KUNIT_TEST */ > diff --git a/security/apparmor/policy_unpack_test.c b/security/apparmor/policy_unpack_test.c > index 0a969b2e03db..3474fe2cd922 100644 > --- a/security/apparmor/policy_unpack_test.c > +++ b/security/apparmor/policy_unpack_test.c > @@ -4,6 +4,7 @@ > */ > > #include > +#include > > #include "include/policy.h" > #include "include/policy_unpack.h" > @@ -43,6 +44,8 @@ > #define TEST_ARRAY_BUF_OFFSET \ > (TEST_NAMED_ARRAY_BUF_OFFSET + 3 + strlen(TEST_ARRAY_NAME) + 1) > > +MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); > + > struct policy_unpack_fixture { > struct aa_ext *e; > size_t e_size; > @@ -605,3 +608,5 @@ static struct kunit_suite apparmor_policy_unpack_test_module = { > }; > > kunit_test_suite(apparmor_policy_unpack_test_module); > + > +MODULE_LICENSE("GPL");