From patchwork Tue Nov 15 17:56:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 13044036 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 5458EC4332F for ; Tue, 15 Nov 2022 17:57:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229877AbiKOR5p (ORCPT ); Tue, 15 Nov 2022 12:57:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50396 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231415AbiKOR5m (ORCPT ); Tue, 15 Nov 2022 12:57:42 -0500 Received: from frasgout13.his.huawei.com (frasgout13.his.huawei.com [14.137.139.46]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E10CB2F3A6; Tue, 15 Nov 2022 09:57:39 -0800 (PST) Received: from mail02.huawei.com (unknown [172.18.147.229]) by frasgout13.his.huawei.com (SkyGuard) with ESMTP id 4NBYcv13TDz9xtmS; Wed, 16 Nov 2022 01:50:55 +0800 (CST) Received: from huaweicloud.com (unknown [10.204.63.22]) by APP1 (Coremail) with SMTP id LxC2BwCHcW7o0nNj73dpAA--.16599S3; Tue, 15 Nov 2022 18:57:16 +0100 (CET) From: Roberto Sassu To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yhs@fb.com, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, revest@chromium.org, jackmanb@chromium.org, paul@paul-moore.com, jmorris@namei.org, serge@hallyn.com Cc: bpf@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, Roberto Sassu Subject: [RFC][PATCH 1/4] lsm: Clarify documentation of vm_enough_memory hook Date: Tue, 15 Nov 2022 18:56:49 +0100 Message-Id: <20221115175652.3836811-2-roberto.sassu@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221115175652.3836811-1-roberto.sassu@huaweicloud.com> References: <20221115175652.3836811-1-roberto.sassu@huaweicloud.com> MIME-Version: 1.0 X-CM-TRANSID: LxC2BwCHcW7o0nNj73dpAA--.16599S3 X-Coremail-Antispam: 1UD129KBjvdXoWruFy8GF18ZrWxtw17KrWUCFg_yoWkZrX_u3 4fG348Xw4fXF4xKa1IkF9aqryrK3yfXr1qgF1Yq39IqFWDAas5Gw4IgF9xX3Wqgwn293s5 uF97trWxAwnIgjkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8Yxn0WfASr-VFAUDa7-sFnT 9fnUUIcSsGvfJTRUUUbg8YFVCjjxCrM7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20E Y4v20xvaj40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r18M2 8IrcIa0xkI8VCY1x0267AKxVW8JVW5JwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK 021l84ACjcxK6xIIjxv20xvE14v26r1I6r4UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r 4UJVWxJr1l84ACjcxK6I8E87Iv67AKxVW8JVWxJwA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_ Gr1j6F4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ew Av7VC0I7IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY 6r1j6r4UM4x0Y48IcxkI7VAKI48JM4IIrI8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14 v26r4a6rW5MxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8C rVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVW8ZVWrXw CIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1I6r4UMIIF0xvE2Ix0cI8IcVCY1x02 67AKxVW8Jr0_Cr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxV WUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7I U0GYLDUUUUU== X-CM-SenderInfo: purev21wro2thvvxqx5xdzvxpfor3voofrz/1tbiAgARBF1jj4F5bQAAsz X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-State: RFC From: Roberto Sassu include/linux/lsm_hooks.h reports the result of the LSM infrastructure to the callers, not what LSMs should return to the LSM infrastructure. Clarify that and add that returning 1 from the LSMs means calling __vm_enough_memory() with cap_sys_admin set, 0 without. Signed-off-by: Roberto Sassu Reviewed-by: KP Singh --- include/linux/lsm_hooks.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 4ec80b96c22e..f40b82ca91e7 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1411,7 +1411,9 @@ * Check permissions for allocating a new virtual mapping. * @mm contains the mm struct it is being added to. * @pages contains the number of pages. - * Return 0 if permission is granted. + * Return 0 if permission is granted by LSMs to the caller. LSMs should + * return 1 if __vm_enough_memory() should be called with + * cap_sys_admin set, 0 if not. * * @ismaclabel: * Check if the extended attribute specified by @name From patchwork Tue Nov 15 17:56:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 13044037 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 A8657C433FE for ; Tue, 15 Nov 2022 17:58:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231628AbiKOR6H (ORCPT ); Tue, 15 Nov 2022 12:58:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50510 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231674AbiKOR6C (ORCPT ); Tue, 15 Nov 2022 12:58:02 -0500 Received: from frasgout11.his.huawei.com (frasgout11.his.huawei.com [14.137.139.23]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 530112F3BC; Tue, 15 Nov 2022 09:57:50 -0800 (PST) Received: from mail02.huawei.com (unknown [172.18.147.227]) by frasgout11.his.huawei.com (SkyGuard) with ESMTP id 4NBYd21gn6z9xqwT; Wed, 16 Nov 2022 01:51:02 +0800 (CST) Received: from huaweicloud.com (unknown [10.204.63.22]) by APP1 (Coremail) with SMTP id LxC2BwCHcW7o0nNj73dpAA--.16599S4; Tue, 15 Nov 2022 18:57:26 +0100 (CET) From: Roberto Sassu To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yhs@fb.com, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, revest@chromium.org, jackmanb@chromium.org, paul@paul-moore.com, jmorris@namei.org, serge@hallyn.com Cc: bpf@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, Roberto Sassu Subject: [RFC][PATCH 2/4] lsm: Add missing return values doc in lsm_hooks.h and fix formatting Date: Tue, 15 Nov 2022 18:56:50 +0100 Message-Id: <20221115175652.3836811-3-roberto.sassu@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221115175652.3836811-1-roberto.sassu@huaweicloud.com> References: <20221115175652.3836811-1-roberto.sassu@huaweicloud.com> MIME-Version: 1.0 X-CM-TRANSID: LxC2BwCHcW7o0nNj73dpAA--.16599S4 X-Coremail-Antispam: 1UD129KBjvAXoW3Kr48CrW8Cr1rCF1kAry5Jwb_yoW8Ar18Ko WF9w47Xw1UKr17Ca1q9wn7Ga97u3ZY9F48CrsYq3s0yF9aqry5WayrA3W7Ja15Ar4UKa4D Xas7Aa4IvF4Ut3Wfn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUO57kC6x804xWl14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK 8VAvwI8IcIk0rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jr yl82xGYIkIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_JFI_Gr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIE14v26r4j6F4UM28EF7xvwVC2z280aVCY1x0267AK xVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7 xfMcIj6xIIjxv20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Y z7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lFIxGxcIEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2 AFwI0_GFv_Wryl42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAq x4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r4a6r W5MIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_JFI_Gr1lIxAIcVC0I7IYx2IY6xkF 7I0E14v26r4UJVWxJr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14 v26r1j6r4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuY vjxUxeHqDUUUU X-CM-SenderInfo: purev21wro2thvvxqx5xdzvxpfor3voofrz/1tbiAgARBF1jj4F5bQABsy X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-State: RFC From: Roberto Sassu Ensure that for non-void LSM hooks there is a description of the return values. Also replace spaces with tab for indentation, remove empty lines between the hook description and the list of parameters and add the period at the end of the parameter description. Finally, replace the description of the sb_parse_opts_str hook, which was removed with commit 757cbe597fe8 ("LSM: new method: ->sb_add_mnt_opt()"), with one for the new hook sb_add_mnt_opt. Signed-off-by: Roberto Sassu --- include/linux/lsm_hooks.h | 123 ++++++++++++++++++++++++++------------ 1 file changed, 86 insertions(+), 37 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index f40b82ca91e7..c0c570b7eabd 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -92,6 +92,7 @@ * is initialised to NULL by the caller. * @fc indicates the new filesystem context. * @src_fc indicates the original filesystem context. + * Return 0 on success or a negative error code on failure. * @fs_context_parse_param: * Userspace provided a parameter to configure a superblock. The LSM may * reject it with an error and may use it for itself, in which case it @@ -99,6 +100,9 @@ * the filesystem. * @fc indicates the filesystem context. * @param The parameter + * Return 0 to indicate that the parameter should be passed on to the + * filesystem, 1 to indicate that the parameter should be discarded or an + * error to indicate that the parameter should be rejected. * * Security hooks for filesystem operations. * @@ -118,6 +122,7 @@ * Free memory associated with @mnt_ops. * @sb_eat_lsm_opts: * Eat (scan @orig options) and save them in @mnt_opts. + * Return 0 if permission is granted. * @sb_statfs: * Check permission before obtaining filesystem statistics for the @mnt * mountpoint. @@ -158,9 +163,11 @@ * @data contains the filesystem-specific data. * Return 0 if permission is granted. * @sb_kern_mount: - * Mount this @sb if allowed by permissions. + * Mount this @sb if allowed by permissions. + * Return 0 if permission is granted. * @sb_show_options: * Show (print on @m) mount options for this @sb. + * Return 0 if permission is granted. * @sb_umount: * Check permission before the @mnt file system is unmounted. * @mnt contains the mounted file system. @@ -176,18 +183,22 @@ * Set the security relevant mount options used for a superblock * @sb the superblock to set security mount options for * @opts binary data structure containing all lsm mount data + * Return 0 on success, error on failure. * @sb_clone_mnt_opts: * Copy all security options from a given superblock to another * @oldsb old superblock which contain information to clone * @newsb new superblock which needs filled in - * @sb_parse_opts_str: - * Parse a string of security data filling in the opts structure - * @options string containing all mount options known by the LSM - * @opts binary data structure usable by the LSM + * Return 0 on success, error on failure. + * @add_mnt_opt: + * Add a new mount option @option with value @val and length @len to the + * existing mount options @mnt_opts. + * Return 0 if the option was successfully added, a negative value + * otherwise. * @move_mount: * Check permission before a mount is moved. * @from_path indicates the mount that is going to be moved. * @to_path indicates the mountpoint that will be mounted upon. + * Return 0 if permission is granted. * @dentry_init_security: * Compute a context for a dentry as the inode is not yet available * since NFSv4 has no label backed by an EA anyway. @@ -199,6 +210,7 @@ * a pointer to static string. * @ctx pointer to place the pointer to the resulting context in. * @ctxlen point to place the length of the resulting context. + * Return 0 if permission is granted. * @dentry_create_files_as: * Compute a context for a dentry as the inode is not yet available * and set that context in passed in creds so that new files are @@ -209,6 +221,7 @@ * @name name of the last path component used to create file * @old creds which should be used for context calculation * @new creds to modify + * Return 0 if permission is granted. * * * Security hooks for inode operations. @@ -380,6 +393,7 @@ * @path_notify: * Check permissions before setting a watch on events as defined by @mask, * on an object at @path, whose type is defined by @obj_type. + * Return 0 if permission is granted. * @inode_readlink: * Check the permission to read the symbolic link. * @dentry contains the dentry structure for the file link. @@ -439,9 +453,9 @@ * Retrieve a copy of the extended attribute representation of the * security label associated with @name for @inode via @buffer. Note that * @name is the remainder of the attribute name after the security prefix - * has been removed. @alloc is used to specify of the call should return a - * value via the buffer or just the value length Return size of buffer on - * success. + * has been removed. @alloc is used to specify if the call should return a + * value via the buffer or just the value length. + * Return size of buffer on success. * @inode_setsecurity: * Set the security label associated with @name for @inode from the * extended attribute value @value. @size indicates the size of the @@ -491,20 +505,22 @@ * to abort the copy up. Note that the caller is responsible for reading * and writing the xattrs as this hook is merely a filter. * @d_instantiate: - * Fill in @inode security information for a @dentry if allowed. + * Fill in @inode security information for a @dentry if allowed. * @getprocattr: - * Read attribute @name for process @p and store it into @value if allowed. + * Read attribute @name for process @p and store it into @value if allowed. + * Return the length of @value on success, a negative value otherwise. * @setprocattr: - * Write (set) attribute @name to @value, size @size if allowed. + * Write (set) attribute @name to @value, size @size if allowed. + * Return written bytes on success, a negative value otherwise. * * Security hooks for kernfs node operations * * @kernfs_init_security: * Initialize the security context of a newly created kernfs node based * on its own and its parent's attributes. - * * @kn_dir the parent kernfs node * @kn the new child kernfs node + * Return 0 if permission is granted. * * Security hooks for file operations * @@ -602,6 +618,7 @@ * Save open-time permission checking state for later use upon * file_permission, and recheck access if anything has changed * since inode_permission. + * Return 0 if permission is granted. * * Security hooks for task operations. * @@ -619,6 +636,7 @@ * @gfp indicates the atomicity of any memory allocations. * Only allocate sufficient memory and attach to @cred such that * cred_transfer() will not get ENOMEM. + * Return 0 on success, negative values on failure. * @cred_free: * @cred points to the credentials. * Deallocate and clear the cred->security field in a set of credentials. @@ -627,6 +645,7 @@ * @old points to the original credentials. * @gfp indicates the atomicity of any memory allocations. * Prepare a new set of credentials by copying the data from the old set. + * Return 0 on success, negative values on failure. * @cred_transfer: * @new points to the new credentials. * @old points to the original credentials. @@ -873,6 +892,7 @@ * @type contains the requested communications type. * @protocol contains the requested protocol. * @kern set to 1 if a kernel socket. + * Return 0 if permission is granted. * @socket_socketpair: * Check permissions before creating a fresh pair of sockets. * @socka contains the first socket structure. @@ -956,6 +976,7 @@ * Must not sleep inside this hook because some callers hold spinlocks. * @sk contains the sock (not socket) associated with the incoming sk_buff. * @skb contains the incoming network data. + * Return 0 if permission is granted. * @socket_getpeersec_stream: * This hook allows the security module to provide peer socket security * state for unix or connected tcp sockets to userspace via getsockopt @@ -983,6 +1004,7 @@ * @sk_alloc_security: * Allocate and attach a security structure to the sk->sk_security field, * which is used to copy security attributes between local stream sockets. + * Return 0 on success, error on failure. * @sk_free_security: * Deallocate security structure. * @sk_clone_security: @@ -995,17 +1017,19 @@ * @inet_conn_request: * Sets the openreq's sid to socket's sid with MLS portion taken * from peer sid. + * Return 0 if permission is granted. * @inet_csk_clone: * Sets the new child socket's sid to the openreq sid. * @inet_conn_established: * Sets the connection's peersid to the secmark on skb. * @secmark_relabel_packet: - * check if the process should be allowed to relabel packets to - * the given secid + * Check if the process should be allowed to relabel packets to + * the given secid. + * Return 0 if permission is granted. * @secmark_refcount_inc: - * tells the LSM to increment the number of secmark labeling rules loaded + * Tells the LSM to increment the number of secmark labeling rules loaded. * @secmark_refcount_dec: - * tells the LSM to decrement the number of secmark labeling rules loaded + * Tells the LSM to decrement the number of secmark labeling rules loaded. * @req_classify_flow: * Sets the flow's sid to the openreq sid. * @tun_dev_alloc_security: @@ -1019,18 +1043,22 @@ * @security pointer to the TUN device's security structure * @tun_dev_create: * Check permissions prior to creating a new TUN device. + * Return 0 if permission is granted. * @tun_dev_attach_queue: * Check permissions prior to attaching to a TUN device queue. * @security pointer to the TUN device's security structure. + * Return 0 if permission is granted. * @tun_dev_attach: * This hook can be used by the module to update any security state * associated with the TUN device's sock structure. * @sk contains the existing sock structure. * @security pointer to the TUN device's security structure. + * Return 0 if permission is granted. * @tun_dev_open: * This hook can be used by the module to update any security state * associated with the TUN device's security structure. * @security pointer to the TUN devices's security structure. + * Return 0 if permission is granted. * * Security hooks for SCTP * @@ -1063,6 +1091,7 @@ * to the security module. * @asoc pointer to sctp association structure. * @skb pointer to skbuff of association packet. + * Return 0 on success, error on failure. * * Security hooks for Infiniband * @@ -1071,15 +1100,17 @@ * @subnet_prefix the subnet prefix of the port being used. * @pkey the pkey to be accessed. * @sec pointer to a security structure. + * Return 0 if permission is granted. * @ib_endport_manage_subnet: * Check permissions to send and receive SMPs on a end port. * @dev_name the IB device name (i.e. mlx4_0). * @port_num the port number. * @sec pointer to a security structure. + * Return 0 if permission is granted. * @ib_alloc_security: * Allocate a security structure for Infiniband objects. * @sec pointer to a security structure pointer. - * Returns 0 on success, non-zero on failure + * Returns 0 on success, non-zero on failure. * @ib_free_security: * Deallocate an Infiniband security structure. * @sec contains the security structure to be freed. @@ -1107,6 +1138,7 @@ * @xfrm_policy_delete_security: * @ctx contains the xfrm_sec_ctx. * Authorize deletion of xp->security. + * Return 0 if permission is granted. * @xfrm_state_alloc: * @x contains the xfrm_state being added to the Security Association * Database by the XFRM system. @@ -1132,6 +1164,7 @@ * @xfrm_state_delete_security: * @x contains the xfrm_state. * Authorize deletion of x->security. + * Return 0 if permission is granted. * @xfrm_policy_lookup: * @ctx contains the xfrm_sec_ctx for which the access control is being * checked. @@ -1432,10 +1465,12 @@ * @secdata contains the pointer that stores the converted security * context. * @seclen pointer which contains the length of the data + * Return 0 on success, error on failure. * @secctx_to_secid: * Convert security context to secid. * @secid contains the pointer to the generated security ID. * @secdata contains the security context. + * Return 0 on success, error on failure. * * @release_secctx: * Release the security context. @@ -1489,6 +1524,7 @@ * @inode we wish to set the security context of. * @ctx contains the string which we wish to set in the inode. * @ctxlen contains the length of @ctx. + * Return 0 on success, error on failure. * * @inode_setsecctx: * Change the security context of an inode. Updates the @@ -1502,6 +1538,7 @@ * @dentry contains the inode we wish to set the security context of. * @ctx contains the string which we wish to set in the inode. * @ctxlen contains the length of @ctx. + * Return 0 on success, error on failure. * * @inode_getsecctx: * On success, returns 0 and fills out @ctx and @ctxlen with the security @@ -1509,6 +1546,7 @@ * @inode we wish to get the security context of. * @ctx is a pointer in which to place the allocated security context. * @ctxlen points to the place to put the length of @ctx. + * Return 0 on success, error on failure. * * Security hooks for the general notification queue: * @@ -1518,11 +1556,13 @@ * @w_cred: The credentials of the whoever set the watch. * @cred: The event-triggerer's credentials * @n: The notification being posted + * Return 0 if permission is granted. * * @watch_key: * Check to see if a process is allowed to watch for event notifications * from a key or keyring. * @key: The key to watch. + * Return 0 if permission is granted. * * Security hooks for using the eBPF maps and programs functionalities through * eBPF syscalls. @@ -1531,65 +1571,74 @@ * Do a initial check for all bpf syscalls after the attribute is copied * into the kernel. The actual security module can implement their own * rules to check the specific cmd they need. + * Return 0 if permission is granted. * * @bpf_map: * Do a check when the kernel generate and return a file descriptor for * eBPF maps. - * - * @map: bpf map that we want to access - * @mask: the access flags + * @map: bpf map that we want to access. + * @mask: the access flags. + * Return 0 if permission is granted. * * @bpf_prog: * Do a check when the kernel generate and return a file descriptor for * eBPF programs. - * * @prog: bpf prog that userspace want to use. + * Return 0 if permission is granted. * * @bpf_map_alloc_security: * Initialize the security field inside bpf map. + * Return 0 on success, error on failure. * * @bpf_map_free_security: * Clean up the security information stored inside bpf map. * * @bpf_prog_alloc_security: * Initialize the security field inside bpf program. + * Return 0 on success, error on failure. * * @bpf_prog_free_security: * Clean up the security information stored inside bpf prog. * * @locked_down: - * Determine whether a kernel feature that potentially enables arbitrary - * code execution in kernel space should be permitted. - * - * @what: kernel feature being accessed + * Determine whether a kernel feature that potentially enables arbitrary + * code execution in kernel space should be permitted. + * @what: kernel feature being accessed. + * Return 0 if permission is granted. * * Security hooks for perf events * * @perf_event_open: - * Check whether the @type of perf_event_open syscall is allowed. + * Check whether the @type of perf_event_open syscall is allowed. + * Return 0 if permission is granted. * @perf_event_alloc: - * Allocate and save perf_event security info. + * Allocate and save perf_event security info. + * Return 0 on success, error on failure. * @perf_event_free: - * Release (free) perf_event security info. + * Release (free) perf_event security info. * @perf_event_read: - * Read perf_event security info if allowed. + * Read perf_event security info if allowed. + * Return 0 if permission is granted. * @perf_event_write: - * Write perf_event security info if allowed. + * Write perf_event security info if allowed. + * Return 0 if permission is granted. * * Security hooks for io_uring * * @uring_override_creds: - * Check if the current task, executing an io_uring operation, is allowed - * to override it's credentials with @new. - * - * @new: the new creds to use + * Check if the current task, executing an io_uring operation, is allowed + * to override it's credentials with @new. + * @new: the new creds to use. + * Return 0 if permission is granted. * * @uring_sqpoll: - * Check whether the current task is allowed to spawn a io_uring polling - * thread (IORING_SETUP_SQPOLL). + * Check whether the current task is allowed to spawn a io_uring polling + * thread (IORING_SETUP_SQPOLL). + * Return 0 if permission is granted. * * @uring_cmd: - * Check whether the file_operations uring_cmd is allowed to run. + * Check whether the file_operations uring_cmd is allowed to run. + * Return 0 if permission is granted. * */ union security_list_options { From patchwork Tue Nov 15 17:56:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 13044038 X-Patchwork-Delegate: bpf@iogearbox.net 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 3A646C43217 for ; Tue, 15 Nov 2022 17:58:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237857AbiKOR6g (ORCPT ); Tue, 15 Nov 2022 12:58:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50734 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231475AbiKOR6F (ORCPT ); Tue, 15 Nov 2022 12:58:05 -0500 Received: from frasgout11.his.huawei.com (frasgout11.his.huawei.com [14.137.139.23]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E1C62F382; Tue, 15 Nov 2022 09:57:59 -0800 (PST) Received: from mail02.huawei.com (unknown [172.18.147.227]) by frasgout11.his.huawei.com (SkyGuard) with ESMTP id 4NBYdD5Dt0z9xqpp; Wed, 16 Nov 2022 01:51:12 +0800 (CST) Received: from huaweicloud.com (unknown [10.204.63.22]) by APP1 (Coremail) with SMTP id LxC2BwCHcW7o0nNj73dpAA--.16599S5; Tue, 15 Nov 2022 18:57:36 +0100 (CET) From: Roberto Sassu To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yhs@fb.com, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, revest@chromium.org, jackmanb@chromium.org, paul@paul-moore.com, jmorris@namei.org, serge@hallyn.com Cc: bpf@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, Roberto Sassu , stable@vger.kernel.org Subject: [RFC][PATCH 3/4] lsm: Redefine LSM_HOOK() macro to add return value flags as argument Date: Tue, 15 Nov 2022 18:56:51 +0100 Message-Id: <20221115175652.3836811-4-roberto.sassu@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221115175652.3836811-1-roberto.sassu@huaweicloud.com> References: <20221115175652.3836811-1-roberto.sassu@huaweicloud.com> MIME-Version: 1.0 X-CM-TRANSID: LxC2BwCHcW7o0nNj73dpAA--.16599S5 X-Coremail-Antispam: 1UD129KBjvAXoWfKrW7tr45uryUJw48uFyxuFg_yoW7CF4xCo W2gasrZw4rKw1kAay5Kr4fJFZ2v34UZr48tr1DW34DXFs2kw1DCws3tr1UJF47XFs5G398 AFy7A3s5CF4DX3Z8n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUO57kC6x804xWl14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK 8VAvwI8IcIk0rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jr Wl82xGYIkIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_JFI_Gr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIE14v26r4j6F4UM28EF7xvwVC2z280aVCY1x0267AK xVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7 xfMcIj6xIIjxv20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Y z7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lFIxGxcIEc7CjxVA2Y2ka0xkIwI1lc7CjxVAaw2 AFwI0_GFv_Wryl42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAq x4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r4a6r W5MIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_JFI_Gr1lIxAIcVC0I7IYx2IY6xkF 7I0E14v26r4UJVWxJr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14 v26r1j6r4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuY vjxU4R6zUUUUU X-CM-SenderInfo: purev21wro2thvvxqx5xdzvxpfor3voofrz/1tbiAQARBF1jj4V5bgAAs3 X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC From: Roberto Sassu Define four return value flags (LSM_RET_NEG, LSM_RET_ZERO, LSM_RET_ONE, LSM_RET_GT_ONE), one for each interval of interest (< 0, = 0, = 1, > 1). Redefine the LSM_HOOK() macro to add return value flags as argument, and set the correct flags for each LSM hook. Implementors of new LSM hooks should do the same as well. Cc: stable@vger.kernel.org # 5.7.x Fixes: 9d3fdea789c8 ("bpf: lsm: Provide attachment points for BPF LSM programs") Signed-off-by: Roberto Sassu --- include/linux/bpf_lsm.h | 2 +- include/linux/lsm_hook_defs.h | 779 ++++++++++++++++++++-------------- include/linux/lsm_hooks.h | 9 +- kernel/bpf/bpf_lsm.c | 5 +- security/bpf/hooks.c | 2 +- security/security.c | 4 +- 6 files changed, 466 insertions(+), 335 deletions(-) diff --git a/include/linux/bpf_lsm.h b/include/linux/bpf_lsm.h index 4bcf76a9bb06..650ab044e705 100644 --- a/include/linux/bpf_lsm.h +++ b/include/linux/bpf_lsm.h @@ -13,7 +13,7 @@ #ifdef CONFIG_BPF_LSM -#define LSM_HOOK(RET, DEFAULT, NAME, ...) \ +#define LSM_HOOK(RET, DEFAULT, RET_FLAGS, NAME, ...) \ RET bpf_lsm_##NAME(__VA_ARGS__); #include #undef LSM_HOOK diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index ec119da1d89b..ed8336a5a0d8 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -18,395 +18,520 @@ * The macro LSM_HOOK is used to define the data structures required by * the LSM framework using the pattern: * - * LSM_HOOK(, , , args...) + * LSM_HOOK(, , , , args...) * * struct security_hook_heads { - * #define LSM_HOOK(RET, DEFAULT, NAME, ...) struct hlist_head NAME; + * #define LSM_HOOK(RET, DEFAULT, RET_FLAGS, NAME, ...) struct hlist_head NAME; * #include * #undef LSM_HOOK * }; */ -LSM_HOOK(int, 0, binder_set_context_mgr, const struct cred *mgr) -LSM_HOOK(int, 0, binder_transaction, const struct cred *from, - const struct cred *to) -LSM_HOOK(int, 0, binder_transfer_binder, const struct cred *from, - const struct cred *to) -LSM_HOOK(int, 0, binder_transfer_file, const struct cred *from, - const struct cred *to, struct file *file) -LSM_HOOK(int, 0, ptrace_access_check, struct task_struct *child, - unsigned int mode) -LSM_HOOK(int, 0, ptrace_traceme, struct task_struct *parent) -LSM_HOOK(int, 0, capget, struct task_struct *target, kernel_cap_t *effective, - kernel_cap_t *inheritable, kernel_cap_t *permitted) -LSM_HOOK(int, 0, capset, struct cred *new, const struct cred *old, - const kernel_cap_t *effective, const kernel_cap_t *inheritable, - const kernel_cap_t *permitted) -LSM_HOOK(int, 0, capable, const struct cred *cred, struct user_namespace *ns, - int cap, unsigned int opts) -LSM_HOOK(int, 0, quotactl, int cmds, int type, int id, struct super_block *sb) -LSM_HOOK(int, 0, quota_on, struct dentry *dentry) -LSM_HOOK(int, 0, syslog, int type) -LSM_HOOK(int, 0, settime, const struct timespec64 *ts, - const struct timezone *tz) -LSM_HOOK(int, 0, vm_enough_memory, struct mm_struct *mm, long pages) -LSM_HOOK(int, 0, bprm_creds_for_exec, struct linux_binprm *bprm) -LSM_HOOK(int, 0, bprm_creds_from_file, struct linux_binprm *bprm, struct file *file) -LSM_HOOK(int, 0, bprm_check_security, struct linux_binprm *bprm) -LSM_HOOK(void, LSM_RET_VOID, bprm_committing_creds, struct linux_binprm *bprm) -LSM_HOOK(void, LSM_RET_VOID, bprm_committed_creds, struct linux_binprm *bprm) -LSM_HOOK(int, 0, fs_context_dup, struct fs_context *fc, - struct fs_context *src_sc) -LSM_HOOK(int, -ENOPARAM, fs_context_parse_param, struct fs_context *fc, + +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, binder_set_context_mgr, + const struct cred *mgr) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, binder_transaction, + const struct cred *from, const struct cred *to) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, binder_transfer_binder, + const struct cred *from, const struct cred *to) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, binder_transfer_file, + const struct cred *from, const struct cred *to, struct file *file) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, ptrace_access_check, + struct task_struct *child, unsigned int mode) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, ptrace_traceme, + struct task_struct *parent) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, capget, struct task_struct *target, + kernel_cap_t *effective, kernel_cap_t *inheritable, + kernel_cap_t *permitted) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, capset, struct cred *new, + const struct cred *old, const kernel_cap_t *effective, + const kernel_cap_t *inheritable, const kernel_cap_t *permitted) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, capable, const struct cred *cred, + struct user_namespace *ns, int cap, unsigned int opts) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, quotactl, int cmds, int type, + int id, struct super_block *sb) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, quota_on, struct dentry *dentry) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, syslog, int type) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, settime, + const struct timespec64 *ts, const struct timezone *tz) +LSM_HOOK(int, 0, LSM_RET_ZERO | LSM_RET_ONE, vm_enough_memory, + struct mm_struct *mm, long pages) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, bprm_creds_for_exec, + struct linux_binprm *bprm) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, bprm_creds_from_file, + struct linux_binprm *bprm, struct file *file) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, bprm_check_security, + struct linux_binprm *bprm) +LSM_HOOK(void, LSM_RET_VOID, 0, bprm_committing_creds, struct linux_binprm *bprm) +LSM_HOOK(void, LSM_RET_VOID, 0, bprm_committed_creds, struct linux_binprm *bprm) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, fs_context_dup, + struct fs_context *fc, struct fs_context *src_sc) +LSM_HOOK(int, -ENOPARAM, LSM_RET_NEG | LSM_RET_ZERO | LSM_RET_ONE, + fs_context_parse_param, struct fs_context *fc, struct fs_parameter *param) -LSM_HOOK(int, 0, sb_alloc_security, struct super_block *sb) -LSM_HOOK(void, LSM_RET_VOID, sb_delete, struct super_block *sb) -LSM_HOOK(void, LSM_RET_VOID, sb_free_security, struct super_block *sb) -LSM_HOOK(void, LSM_RET_VOID, sb_free_mnt_opts, void *mnt_opts) -LSM_HOOK(int, 0, sb_eat_lsm_opts, char *orig, void **mnt_opts) -LSM_HOOK(int, 0, sb_mnt_opts_compat, struct super_block *sb, void *mnt_opts) -LSM_HOOK(int, 0, sb_remount, struct super_block *sb, void *mnt_opts) -LSM_HOOK(int, 0, sb_kern_mount, struct super_block *sb) -LSM_HOOK(int, 0, sb_show_options, struct seq_file *m, struct super_block *sb) -LSM_HOOK(int, 0, sb_statfs, struct dentry *dentry) -LSM_HOOK(int, 0, sb_mount, const char *dev_name, const struct path *path, - const char *type, unsigned long flags, void *data) -LSM_HOOK(int, 0, sb_umount, struct vfsmount *mnt, int flags) -LSM_HOOK(int, 0, sb_pivotroot, const struct path *old_path, - const struct path *new_path) -LSM_HOOK(int, 0, sb_set_mnt_opts, struct super_block *sb, void *mnt_opts, - unsigned long kern_flags, unsigned long *set_kern_flags) -LSM_HOOK(int, 0, sb_clone_mnt_opts, const struct super_block *oldsb, - struct super_block *newsb, unsigned long kern_flags, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sb_alloc_security, + struct super_block *sb) +LSM_HOOK(void, LSM_RET_VOID, 0, sb_delete, struct super_block *sb) +LSM_HOOK(void, LSM_RET_VOID, 0, sb_free_security, struct super_block *sb) +LSM_HOOK(void, LSM_RET_VOID, 0, sb_free_mnt_opts, void *mnt_opts) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sb_eat_lsm_opts, char *orig, + void **mnt_opts) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sb_mnt_opts_compat, + struct super_block *sb, void *mnt_opts) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sb_remount, struct super_block *sb, + void *mnt_opts) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sb_kern_mount, + struct super_block *sb) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sb_show_options, + struct seq_file *m, struct super_block *sb) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sb_statfs, struct dentry *dentry) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sb_mount, const char *dev_name, + const struct path *path, const char *type, unsigned long flags, + void *data) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sb_umount, struct vfsmount *mnt, + int flags) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sb_pivotroot, + const struct path *old_path, const struct path *new_path) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sb_set_mnt_opts, + struct super_block *sb, void *mnt_opts, unsigned long kern_flags, unsigned long *set_kern_flags) -LSM_HOOK(int, 0, move_mount, const struct path *from_path, - const struct path *to_path) -LSM_HOOK(int, -EOPNOTSUPP, dentry_init_security, struct dentry *dentry, - int mode, const struct qstr *name, const char **xattr_name, - void **ctx, u32 *ctxlen) -LSM_HOOK(int, 0, dentry_create_files_as, struct dentry *dentry, int mode, - struct qstr *name, const struct cred *old, struct cred *new) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sb_clone_mnt_opts, + const struct super_block *oldsb, struct super_block *newsb, + unsigned long kern_flags, unsigned long *set_kern_flags) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, move_mount, + const struct path *from_path, const struct path *to_path) +LSM_HOOK(int, -EOPNOTSUPP, LSM_RET_NEG | LSM_RET_ZERO, dentry_init_security, + struct dentry *dentry, int mode, const struct qstr *name, + const char **xattr_name, void **ctx, u32 *ctxlen) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, dentry_create_files_as, + struct dentry *dentry, int mode, struct qstr *name, + const struct cred *old, struct cred *new) #ifdef CONFIG_SECURITY_PATH -LSM_HOOK(int, 0, path_unlink, const struct path *dir, struct dentry *dentry) -LSM_HOOK(int, 0, path_mkdir, const struct path *dir, struct dentry *dentry, - umode_t mode) -LSM_HOOK(int, 0, path_rmdir, const struct path *dir, struct dentry *dentry) -LSM_HOOK(int, 0, path_mknod, const struct path *dir, struct dentry *dentry, - umode_t mode, unsigned int dev) -LSM_HOOK(int, 0, path_truncate, const struct path *path) -LSM_HOOK(int, 0, path_symlink, const struct path *dir, struct dentry *dentry, - const char *old_name) -LSM_HOOK(int, 0, path_link, struct dentry *old_dentry, - const struct path *new_dir, struct dentry *new_dentry) -LSM_HOOK(int, 0, path_rename, const struct path *old_dir, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, path_unlink, + const struct path *dir, struct dentry *dentry) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, path_mkdir, const struct path *dir, + struct dentry *dentry, umode_t mode) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, path_rmdir, const struct path *dir, + struct dentry *dentry) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, path_mknod, const struct path *dir, + struct dentry *dentry, umode_t mode, unsigned int dev) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, path_truncate, + const struct path *path) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, path_symlink, + const struct path *dir, struct dentry *dentry, const char *old_name) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, path_link, struct dentry *old_dentry, const struct path *new_dir, - struct dentry *new_dentry, unsigned int flags) -LSM_HOOK(int, 0, path_chmod, const struct path *path, umode_t mode) -LSM_HOOK(int, 0, path_chown, const struct path *path, kuid_t uid, kgid_t gid) -LSM_HOOK(int, 0, path_chroot, const struct path *path) + struct dentry *new_dentry) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, path_rename, + const struct path *old_dir, struct dentry *old_dentry, + const struct path *new_dir, struct dentry *new_dentry, + unsigned int flags) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, path_chmod, + const struct path *path, umode_t mode) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, path_chown, + const struct path *path, kuid_t uid, kgid_t gid) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, path_chroot, + const struct path *path) #endif /* CONFIG_SECURITY_PATH */ /* Needed for inode based security check */ -LSM_HOOK(int, 0, path_notify, const struct path *path, u64 mask, - unsigned int obj_type) -LSM_HOOK(int, 0, inode_alloc_security, struct inode *inode) -LSM_HOOK(void, LSM_RET_VOID, inode_free_security, struct inode *inode) -LSM_HOOK(int, 0, inode_init_security, struct inode *inode, - struct inode *dir, const struct qstr *qstr, const char **name, - void **value, size_t *len) -LSM_HOOK(int, 0, inode_init_security_anon, struct inode *inode, - const struct qstr *name, const struct inode *context_inode) -LSM_HOOK(int, 0, inode_create, struct inode *dir, struct dentry *dentry, - umode_t mode) -LSM_HOOK(int, 0, inode_link, struct dentry *old_dentry, struct inode *dir, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, path_notify, + const struct path *path, u64 mask, unsigned int obj_type) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_alloc_security, + struct inode *inode) +LSM_HOOK(void, LSM_RET_VOID, 0, inode_free_security, struct inode *inode) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_init_security, + struct inode *inode, struct inode *dir, const struct qstr *qstr, + const char **name, void **value, size_t *len) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_init_security_anon, + struct inode *inode, const struct qstr *name, + const struct inode *context_inode) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_create, struct inode *dir, + struct dentry *dentry, umode_t mode) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_link, + struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) -LSM_HOOK(int, 0, inode_unlink, struct inode *dir, struct dentry *dentry) -LSM_HOOK(int, 0, inode_symlink, struct inode *dir, struct dentry *dentry, - const char *old_name) -LSM_HOOK(int, 0, inode_mkdir, struct inode *dir, struct dentry *dentry, - umode_t mode) -LSM_HOOK(int, 0, inode_rmdir, struct inode *dir, struct dentry *dentry) -LSM_HOOK(int, 0, inode_mknod, struct inode *dir, struct dentry *dentry, - umode_t mode, dev_t dev) -LSM_HOOK(int, 0, inode_rename, struct inode *old_dir, struct dentry *old_dentry, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_unlink, struct inode *dir, + struct dentry *dentry) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_symlink, struct inode *dir, + struct dentry *dentry, const char *old_name) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_mkdir, struct inode *dir, + struct dentry *dentry, umode_t mode) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_rmdir, struct inode *dir, + struct dentry *dentry) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_mknod, struct inode *dir, + struct dentry *dentry, umode_t mode, dev_t dev) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_rename, + struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) -LSM_HOOK(int, 0, inode_readlink, struct dentry *dentry) -LSM_HOOK(int, 0, inode_follow_link, struct dentry *dentry, struct inode *inode, - bool rcu) -LSM_HOOK(int, 0, inode_permission, struct inode *inode, int mask) -LSM_HOOK(int, 0, inode_setattr, struct dentry *dentry, struct iattr *attr) -LSM_HOOK(int, 0, inode_getattr, const struct path *path) -LSM_HOOK(int, 0, inode_setxattr, struct user_namespace *mnt_userns, - struct dentry *dentry, const char *name, const void *value, - size_t size, int flags) -LSM_HOOK(void, LSM_RET_VOID, inode_post_setxattr, struct dentry *dentry, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_readlink, + struct dentry *dentry) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_follow_link, + struct dentry *dentry, struct inode *inode, bool rcu) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_permission, + struct inode *inode, int mask) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_setattr, + struct dentry *dentry, struct iattr *attr) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_getattr, + const struct path *path) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_setxattr, + struct user_namespace *mnt_userns, struct dentry *dentry, + const char *name, const void *value, size_t size, int flags) +LSM_HOOK(void, LSM_RET_VOID, 0, inode_post_setxattr, struct dentry *dentry, const char *name, const void *value, size_t size, int flags) -LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name) -LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry) -LSM_HOOK(int, 0, inode_removexattr, struct user_namespace *mnt_userns, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_getxattr, struct dentry *dentry, const char *name) -LSM_HOOK(int, 0, inode_need_killpriv, struct dentry *dentry) -LSM_HOOK(int, 0, inode_killpriv, struct user_namespace *mnt_userns, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_listxattr, struct dentry *dentry) -LSM_HOOK(int, -EOPNOTSUPP, inode_getsecurity, struct user_namespace *mnt_userns, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_removexattr, + struct user_namespace *mnt_userns, struct dentry *dentry, + const char *name) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO | LSM_RET_ONE | LSM_RET_GT_ONE, + inode_need_killpriv, struct dentry *dentry) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_killpriv, + struct user_namespace *mnt_userns, struct dentry *dentry) +LSM_HOOK(int, -EOPNOTSUPP, + LSM_RET_NEG | LSM_RET_ZERO | LSM_RET_ONE | LSM_RET_GT_ONE, + inode_getsecurity, struct user_namespace *mnt_userns, struct inode *inode, const char *name, void **buffer, bool alloc) -LSM_HOOK(int, -EOPNOTSUPP, inode_setsecurity, struct inode *inode, - const char *name, const void *value, size_t size, int flags) -LSM_HOOK(int, 0, inode_listsecurity, struct inode *inode, char *buffer, +LSM_HOOK(int, -EOPNOTSUPP, LSM_RET_NEG | LSM_RET_ZERO, inode_setsecurity, + struct inode *inode, const char *name, const void *value, size_t size, + int flags) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO | LSM_RET_ONE | LSM_RET_GT_ONE, + inode_listsecurity, struct inode *inode, char *buffer, size_t buffer_size) -LSM_HOOK(void, LSM_RET_VOID, inode_getsecid, struct inode *inode, u32 *secid) -LSM_HOOK(int, 0, inode_copy_up, struct dentry *src, struct cred **new) -LSM_HOOK(int, -EOPNOTSUPP, inode_copy_up_xattr, const char *name) -LSM_HOOK(int, 0, kernfs_init_security, struct kernfs_node *kn_dir, - struct kernfs_node *kn) -LSM_HOOK(int, 0, file_permission, struct file *file, int mask) -LSM_HOOK(int, 0, file_alloc_security, struct file *file) -LSM_HOOK(void, LSM_RET_VOID, file_free_security, struct file *file) -LSM_HOOK(int, 0, file_ioctl, struct file *file, unsigned int cmd, - unsigned long arg) -LSM_HOOK(int, 0, mmap_addr, unsigned long addr) -LSM_HOOK(int, 0, mmap_file, struct file *file, unsigned long reqprot, - unsigned long prot, unsigned long flags) -LSM_HOOK(int, 0, file_mprotect, struct vm_area_struct *vma, - unsigned long reqprot, unsigned long prot) -LSM_HOOK(int, 0, file_lock, struct file *file, unsigned int cmd) -LSM_HOOK(int, 0, file_fcntl, struct file *file, unsigned int cmd, - unsigned long arg) -LSM_HOOK(void, LSM_RET_VOID, file_set_fowner, struct file *file) -LSM_HOOK(int, 0, file_send_sigiotask, struct task_struct *tsk, - struct fown_struct *fown, int sig) -LSM_HOOK(int, 0, file_receive, struct file *file) -LSM_HOOK(int, 0, file_open, struct file *file) -LSM_HOOK(int, 0, task_alloc, struct task_struct *task, - unsigned long clone_flags) -LSM_HOOK(void, LSM_RET_VOID, task_free, struct task_struct *task) -LSM_HOOK(int, 0, cred_alloc_blank, struct cred *cred, gfp_t gfp) -LSM_HOOK(void, LSM_RET_VOID, cred_free, struct cred *cred) -LSM_HOOK(int, 0, cred_prepare, struct cred *new, const struct cred *old, - gfp_t gfp) -LSM_HOOK(void, LSM_RET_VOID, cred_transfer, struct cred *new, +LSM_HOOK(void, LSM_RET_VOID, 0, inode_getsecid, struct inode *inode, u32 *secid) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_copy_up, struct dentry *src, + struct cred **new) +LSM_HOOK(int, -EOPNOTSUPP, LSM_RET_NEG | LSM_RET_ZERO | LSM_RET_ONE, + inode_copy_up_xattr, const char *name) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, kernfs_init_security, + struct kernfs_node *kn_dir, struct kernfs_node *kn) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, file_permission, struct file *file, + int mask) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, file_alloc_security, + struct file *file) +LSM_HOOK(void, LSM_RET_VOID, 0, file_free_security, struct file *file) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, file_ioctl, struct file *file, + unsigned int cmd, unsigned long arg) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, mmap_addr, unsigned long addr) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, mmap_file, struct file *file, + unsigned long reqprot, unsigned long prot, unsigned long flags) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, file_mprotect, + struct vm_area_struct *vma, unsigned long reqprot, unsigned long prot) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, file_lock, struct file *file, + unsigned int cmd) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, file_fcntl, struct file *file, + unsigned int cmd, unsigned long arg) +LSM_HOOK(void, LSM_RET_VOID, 0, file_set_fowner, struct file *file) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, file_send_sigiotask, + struct task_struct *tsk, struct fown_struct *fown, int sig) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, file_receive, struct file *file) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, file_open, struct file *file) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_alloc, + struct task_struct *task, unsigned long clone_flags) +LSM_HOOK(void, LSM_RET_VOID, 0, task_free, struct task_struct *task) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, cred_alloc_blank, + struct cred *cred, gfp_t gfp) +LSM_HOOK(void, LSM_RET_VOID, 0, cred_free, struct cred *cred) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, cred_prepare, struct cred *new, + const struct cred *old, gfp_t gfp) +LSM_HOOK(void, LSM_RET_VOID, 0, cred_transfer, struct cred *new, const struct cred *old) -LSM_HOOK(void, LSM_RET_VOID, cred_getsecid, const struct cred *c, u32 *secid) -LSM_HOOK(int, 0, kernel_act_as, struct cred *new, u32 secid) -LSM_HOOK(int, 0, kernel_create_files_as, struct cred *new, struct inode *inode) -LSM_HOOK(int, 0, kernel_module_request, char *kmod_name) -LSM_HOOK(int, 0, kernel_load_data, enum kernel_load_data_id id, bool contents) -LSM_HOOK(int, 0, kernel_post_load_data, char *buf, loff_t size, - enum kernel_load_data_id id, char *description) -LSM_HOOK(int, 0, kernel_read_file, struct file *file, - enum kernel_read_file_id id, bool contents) -LSM_HOOK(int, 0, kernel_post_read_file, struct file *file, char *buf, - loff_t size, enum kernel_read_file_id id) -LSM_HOOK(int, 0, task_fix_setuid, struct cred *new, const struct cred *old, - int flags) -LSM_HOOK(int, 0, task_fix_setgid, struct cred *new, const struct cred * old, - int flags) -LSM_HOOK(int, 0, task_fix_setgroups, struct cred *new, const struct cred * old) -LSM_HOOK(int, 0, task_setpgid, struct task_struct *p, pid_t pgid) -LSM_HOOK(int, 0, task_getpgid, struct task_struct *p) -LSM_HOOK(int, 0, task_getsid, struct task_struct *p) -LSM_HOOK(void, LSM_RET_VOID, current_getsecid_subj, u32 *secid) -LSM_HOOK(void, LSM_RET_VOID, task_getsecid_obj, +LSM_HOOK(void, LSM_RET_VOID, 0, cred_getsecid, const struct cred *c, u32 *secid) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, kernel_act_as, struct cred *new, + u32 secid) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, kernel_create_files_as, + struct cred *new, struct inode *inode) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, kernel_module_request, + char *kmod_name) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, kernel_load_data, + enum kernel_load_data_id id, bool contents) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, kernel_post_load_data, char *buf, + loff_t size, enum kernel_load_data_id id, char *description) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, kernel_read_file, + struct file *file, enum kernel_read_file_id id, bool contents) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, kernel_post_read_file, + struct file *file, char *buf, loff_t size, enum kernel_read_file_id id) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_fix_setuid, struct cred *new, + const struct cred *old, int flags) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_fix_setgid, struct cred *new, + const struct cred *old, int flags) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_fix_setgroups, + struct cred *new, const struct cred *old) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_setpgid, + struct task_struct *p, pid_t pgid) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_getpgid, + struct task_struct *p) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_getsid, struct task_struct *p) +LSM_HOOK(void, LSM_RET_VOID, 0, current_getsecid_subj, u32 *secid) +LSM_HOOK(void, LSM_RET_VOID, 0, task_getsecid_obj, struct task_struct *p, u32 *secid) -LSM_HOOK(int, 0, task_setnice, struct task_struct *p, int nice) -LSM_HOOK(int, 0, task_setioprio, struct task_struct *p, int ioprio) -LSM_HOOK(int, 0, task_getioprio, struct task_struct *p) -LSM_HOOK(int, 0, task_prlimit, const struct cred *cred, - const struct cred *tcred, unsigned int flags) -LSM_HOOK(int, 0, task_setrlimit, struct task_struct *p, unsigned int resource, - struct rlimit *new_rlim) -LSM_HOOK(int, 0, task_setscheduler, struct task_struct *p) -LSM_HOOK(int, 0, task_getscheduler, struct task_struct *p) -LSM_HOOK(int, 0, task_movememory, struct task_struct *p) -LSM_HOOK(int, 0, task_kill, struct task_struct *p, struct kernel_siginfo *info, - int sig, const struct cred *cred) -LSM_HOOK(int, -ENOSYS, task_prctl, int option, unsigned long arg2, - unsigned long arg3, unsigned long arg4, unsigned long arg5) -LSM_HOOK(void, LSM_RET_VOID, task_to_inode, struct task_struct *p, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_setnice, + struct task_struct *p, int nice) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_setioprio, + struct task_struct *p, int ioprio) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_getioprio, + struct task_struct *p) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_prlimit, + const struct cred *cred, const struct cred *tcred, unsigned int flags) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_setrlimit, + struct task_struct *p, unsigned int resource, struct rlimit *new_rlim) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_setscheduler, + struct task_struct *p) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_getscheduler, + struct task_struct *p) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_movememory, + struct task_struct *p) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, task_kill, struct task_struct *p, + struct kernel_siginfo *info, int sig, const struct cred *cred) +LSM_HOOK(int, -ENOSYS, + LSM_RET_NEG | LSM_RET_ZERO | LSM_RET_ONE | LSM_RET_GT_ONE, task_prctl, + int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, + unsigned long arg5) +LSM_HOOK(void, LSM_RET_VOID, 0, task_to_inode, struct task_struct *p, struct inode *inode) -LSM_HOOK(int, 0, userns_create, const struct cred *cred) -LSM_HOOK(int, 0, ipc_permission, struct kern_ipc_perm *ipcp, short flag) -LSM_HOOK(void, LSM_RET_VOID, ipc_getsecid, struct kern_ipc_perm *ipcp, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, userns_create, + const struct cred *cred) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, ipc_permission, + struct kern_ipc_perm *ipcp, short flag) +LSM_HOOK(void, LSM_RET_VOID, 0, ipc_getsecid, struct kern_ipc_perm *ipcp, u32 *secid) -LSM_HOOK(int, 0, msg_msg_alloc_security, struct msg_msg *msg) -LSM_HOOK(void, LSM_RET_VOID, msg_msg_free_security, struct msg_msg *msg) -LSM_HOOK(int, 0, msg_queue_alloc_security, struct kern_ipc_perm *perm) -LSM_HOOK(void, LSM_RET_VOID, msg_queue_free_security, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, msg_msg_alloc_security, + struct msg_msg *msg) +LSM_HOOK(void, LSM_RET_VOID, 0, msg_msg_free_security, struct msg_msg *msg) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, msg_queue_alloc_security, + struct kern_ipc_perm *perm) +LSM_HOOK(void, LSM_RET_VOID, 0, msg_queue_free_security, + struct kern_ipc_perm *perm) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, msg_queue_associate, + struct kern_ipc_perm *perm, int msqflg) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, msg_queue_msgctl, + struct kern_ipc_perm *perm, int cmd) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, msg_queue_msgsnd, + struct kern_ipc_perm *perm, struct msg_msg *msg, int msqflg) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, msg_queue_msgrcv, + struct kern_ipc_perm *perm, struct msg_msg *msg, + struct task_struct *target, long type, int mode) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, shm_alloc_security, struct kern_ipc_perm *perm) -LSM_HOOK(int, 0, msg_queue_associate, struct kern_ipc_perm *perm, int msqflg) -LSM_HOOK(int, 0, msg_queue_msgctl, struct kern_ipc_perm *perm, int cmd) -LSM_HOOK(int, 0, msg_queue_msgsnd, struct kern_ipc_perm *perm, - struct msg_msg *msg, int msqflg) -LSM_HOOK(int, 0, msg_queue_msgrcv, struct kern_ipc_perm *perm, - struct msg_msg *msg, struct task_struct *target, long type, int mode) -LSM_HOOK(int, 0, shm_alloc_security, struct kern_ipc_perm *perm) -LSM_HOOK(void, LSM_RET_VOID, shm_free_security, struct kern_ipc_perm *perm) -LSM_HOOK(int, 0, shm_associate, struct kern_ipc_perm *perm, int shmflg) -LSM_HOOK(int, 0, shm_shmctl, struct kern_ipc_perm *perm, int cmd) -LSM_HOOK(int, 0, shm_shmat, struct kern_ipc_perm *perm, char __user *shmaddr, - int shmflg) -LSM_HOOK(int, 0, sem_alloc_security, struct kern_ipc_perm *perm) -LSM_HOOK(void, LSM_RET_VOID, sem_free_security, struct kern_ipc_perm *perm) -LSM_HOOK(int, 0, sem_associate, struct kern_ipc_perm *perm, int semflg) -LSM_HOOK(int, 0, sem_semctl, struct kern_ipc_perm *perm, int cmd) -LSM_HOOK(int, 0, sem_semop, struct kern_ipc_perm *perm, struct sembuf *sops, - unsigned nsops, int alter) -LSM_HOOK(int, 0, netlink_send, struct sock *sk, struct sk_buff *skb) -LSM_HOOK(void, LSM_RET_VOID, d_instantiate, struct dentry *dentry, +LSM_HOOK(void, LSM_RET_VOID, 0, shm_free_security, struct kern_ipc_perm *perm) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, shm_associate, + struct kern_ipc_perm *perm, int shmflg) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, shm_shmctl, + struct kern_ipc_perm *perm, int cmd) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, shm_shmat, + struct kern_ipc_perm *perm, char __user *shmaddr, int shmflg) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sem_alloc_security, + struct kern_ipc_perm *perm) +LSM_HOOK(void, LSM_RET_VOID, 0, sem_free_security, struct kern_ipc_perm *perm) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sem_associate, + struct kern_ipc_perm *perm, int semflg) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sem_semctl, + struct kern_ipc_perm *perm, int cmd) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sem_semop, + struct kern_ipc_perm *perm, struct sembuf *sops, unsigned nsops, + int alter) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, netlink_send, struct sock *sk, + struct sk_buff *skb) +LSM_HOOK(void, LSM_RET_VOID, 0, d_instantiate, struct dentry *dentry, struct inode *inode) -LSM_HOOK(int, -EINVAL, getprocattr, struct task_struct *p, const char *name, - char **value) -LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size) -LSM_HOOK(int, 0, ismaclabel, const char *name) -LSM_HOOK(int, -EOPNOTSUPP, secid_to_secctx, u32 secid, char **secdata, - u32 *seclen) -LSM_HOOK(int, 0, secctx_to_secid, const char *secdata, u32 seclen, u32 *secid) -LSM_HOOK(void, LSM_RET_VOID, release_secctx, char *secdata, u32 seclen) -LSM_HOOK(void, LSM_RET_VOID, inode_invalidate_secctx, struct inode *inode) -LSM_HOOK(int, 0, inode_notifysecctx, struct inode *inode, void *ctx, u32 ctxlen) -LSM_HOOK(int, 0, inode_setsecctx, struct dentry *dentry, void *ctx, u32 ctxlen) -LSM_HOOK(int, 0, inode_getsecctx, struct inode *inode, void **ctx, - u32 *ctxlen) +LSM_HOOK(int, -EINVAL, + LSM_RET_NEG | LSM_RET_ZERO | LSM_RET_ONE | LSM_RET_GT_ONE, getprocattr, + struct task_struct *p, const char *name, char **value) +LSM_HOOK(int, -EINVAL, + LSM_RET_NEG | LSM_RET_ZERO | LSM_RET_ONE | LSM_RET_GT_ONE, setprocattr, + const char *name, void *value, size_t size) +LSM_HOOK(int, 0, LSM_RET_ZERO | LSM_RET_ONE, ismaclabel, const char *name) +LSM_HOOK(int, -EOPNOTSUPP, LSM_RET_NEG | LSM_RET_ZERO, secid_to_secctx, + u32 secid, char **secdata, u32 *seclen) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, secctx_to_secid, + const char *secdata, u32 seclen, u32 *secid) +LSM_HOOK(void, LSM_RET_VOID, 0, release_secctx, char *secdata, u32 seclen) +LSM_HOOK(void, LSM_RET_VOID, 0, inode_invalidate_secctx, struct inode *inode) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_notifysecctx, + struct inode *inode, void *ctx, u32 ctxlen) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_setsecctx, + struct dentry *dentry, void *ctx, u32 ctxlen) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inode_getsecctx, + struct inode *inode, void **ctx, u32 *ctxlen) #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE) -LSM_HOOK(int, 0, post_notification, const struct cred *w_cred, - const struct cred *cred, struct watch_notification *n) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, post_notification, + const struct cred *w_cred, const struct cred *cred, + struct watch_notification *n) #endif /* CONFIG_SECURITY && CONFIG_WATCH_QUEUE */ #if defined(CONFIG_SECURITY) && defined(CONFIG_KEY_NOTIFICATIONS) -LSM_HOOK(int, 0, watch_key, struct key *key) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, watch_key, struct key *key) #endif /* CONFIG_SECURITY && CONFIG_KEY_NOTIFICATIONS */ #ifdef CONFIG_SECURITY_NETWORK -LSM_HOOK(int, 0, unix_stream_connect, struct sock *sock, struct sock *other, - struct sock *newsk) -LSM_HOOK(int, 0, unix_may_send, struct socket *sock, struct socket *other) -LSM_HOOK(int, 0, socket_create, int family, int type, int protocol, int kern) -LSM_HOOK(int, 0, socket_post_create, struct socket *sock, int family, int type, - int protocol, int kern) -LSM_HOOK(int, 0, socket_socketpair, struct socket *socka, struct socket *sockb) -LSM_HOOK(int, 0, socket_bind, struct socket *sock, struct sockaddr *address, - int addrlen) -LSM_HOOK(int, 0, socket_connect, struct socket *sock, struct sockaddr *address, - int addrlen) -LSM_HOOK(int, 0, socket_listen, struct socket *sock, int backlog) -LSM_HOOK(int, 0, socket_accept, struct socket *sock, struct socket *newsock) -LSM_HOOK(int, 0, socket_sendmsg, struct socket *sock, struct msghdr *msg, - int size) -LSM_HOOK(int, 0, socket_recvmsg, struct socket *sock, struct msghdr *msg, - int size, int flags) -LSM_HOOK(int, 0, socket_getsockname, struct socket *sock) -LSM_HOOK(int, 0, socket_getpeername, struct socket *sock) -LSM_HOOK(int, 0, socket_getsockopt, struct socket *sock, int level, int optname) -LSM_HOOK(int, 0, socket_setsockopt, struct socket *sock, int level, int optname) -LSM_HOOK(int, 0, socket_shutdown, struct socket *sock, int how) -LSM_HOOK(int, 0, socket_sock_rcv_skb, struct sock *sk, struct sk_buff *skb) -LSM_HOOK(int, 0, socket_getpeersec_stream, struct socket *sock, - char __user *optval, int __user *optlen, unsigned len) -LSM_HOOK(int, 0, socket_getpeersec_dgram, struct socket *sock, - struct sk_buff *skb, u32 *secid) -LSM_HOOK(int, 0, sk_alloc_security, struct sock *sk, int family, gfp_t priority) -LSM_HOOK(void, LSM_RET_VOID, sk_free_security, struct sock *sk) -LSM_HOOK(void, LSM_RET_VOID, sk_clone_security, const struct sock *sk, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, unix_stream_connect, + struct sock *sock, struct sock *other, struct sock *newsk) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, unix_may_send, struct socket *sock, + struct socket *other) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_create, int family, + int type, int protocol, int kern) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_post_create, + struct socket *sock, int family, int type, int protocol, int kern) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_socketpair, + struct socket *socka, struct socket *sockb) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_bind, struct socket *sock, + struct sockaddr *address, int addrlen) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_connect, + struct socket *sock, struct sockaddr *address, int addrlen) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_listen, struct socket *sock, + int backlog) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_accept, struct socket *sock, + struct socket *newsock) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_sendmsg, + struct socket *sock, struct msghdr *msg, int size) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_recvmsg, + struct socket *sock, struct msghdr *msg, int size, int flags) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_getsockname, + struct socket *sock) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_getpeername, + struct socket *sock) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_getsockopt, + struct socket *sock, int level, int optname) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_setsockopt, + struct socket *sock, int level, int optname) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_shutdown, + struct socket *sock, int how) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_sock_rcv_skb, + struct sock *sk, struct sk_buff *skb) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_getpeersec_stream, + struct socket *sock, char __user *optval, int __user *optlen, + unsigned len) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, socket_getpeersec_dgram, + struct socket *sock, struct sk_buff *skb, u32 *secid) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sk_alloc_security, struct sock *sk, + int family, gfp_t priority) +LSM_HOOK(void, LSM_RET_VOID, 0, sk_free_security, struct sock *sk) +LSM_HOOK(void, LSM_RET_VOID, 0, sk_clone_security, const struct sock *sk, struct sock *newsk) -LSM_HOOK(void, LSM_RET_VOID, sk_getsecid, struct sock *sk, u32 *secid) -LSM_HOOK(void, LSM_RET_VOID, sock_graft, struct sock *sk, struct socket *parent) -LSM_HOOK(int, 0, inet_conn_request, const struct sock *sk, struct sk_buff *skb, - struct request_sock *req) -LSM_HOOK(void, LSM_RET_VOID, inet_csk_clone, struct sock *newsk, +LSM_HOOK(void, LSM_RET_VOID, 0, sk_getsecid, struct sock *sk, u32 *secid) +LSM_HOOK(void, LSM_RET_VOID, 0, sock_graft, struct sock *sk, struct socket *parent) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, inet_conn_request, + const struct sock *sk, struct sk_buff *skb, struct request_sock *req) +LSM_HOOK(void, LSM_RET_VOID, 0, inet_csk_clone, struct sock *newsk, const struct request_sock *req) -LSM_HOOK(void, LSM_RET_VOID, inet_conn_established, struct sock *sk, +LSM_HOOK(void, LSM_RET_VOID, 0, inet_conn_established, struct sock *sk, struct sk_buff *skb) -LSM_HOOK(int, 0, secmark_relabel_packet, u32 secid) -LSM_HOOK(void, LSM_RET_VOID, secmark_refcount_inc, void) -LSM_HOOK(void, LSM_RET_VOID, secmark_refcount_dec, void) -LSM_HOOK(void, LSM_RET_VOID, req_classify_flow, const struct request_sock *req, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, secmark_relabel_packet, u32 secid) +LSM_HOOK(void, LSM_RET_VOID, 0, secmark_refcount_inc, void) +LSM_HOOK(void, LSM_RET_VOID, 0, secmark_refcount_dec, void) +LSM_HOOK(void, LSM_RET_VOID, 0, req_classify_flow, const struct request_sock *req, struct flowi_common *flic) -LSM_HOOK(int, 0, tun_dev_alloc_security, void **security) -LSM_HOOK(void, LSM_RET_VOID, tun_dev_free_security, void *security) -LSM_HOOK(int, 0, tun_dev_create, void) -LSM_HOOK(int, 0, tun_dev_attach_queue, void *security) -LSM_HOOK(int, 0, tun_dev_attach, struct sock *sk, void *security) -LSM_HOOK(int, 0, tun_dev_open, void *security) -LSM_HOOK(int, 0, sctp_assoc_request, struct sctp_association *asoc, - struct sk_buff *skb) -LSM_HOOK(int, 0, sctp_bind_connect, struct sock *sk, int optname, - struct sockaddr *address, int addrlen) -LSM_HOOK(void, LSM_RET_VOID, sctp_sk_clone, struct sctp_association *asoc, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, tun_dev_alloc_security, + void **security) +LSM_HOOK(void, LSM_RET_VOID, 0, tun_dev_free_security, void *security) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, tun_dev_create, void) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, tun_dev_attach_queue, + void *security) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, tun_dev_attach, struct sock *sk, + void *security) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, tun_dev_open, void *security) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sctp_assoc_request, + struct sctp_association *asoc, struct sk_buff *skb) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sctp_bind_connect, struct sock *sk, + int optname, struct sockaddr *address, int addrlen) +LSM_HOOK(void, LSM_RET_VOID, 0, sctp_sk_clone, struct sctp_association *asoc, struct sock *sk, struct sock *newsk) -LSM_HOOK(int, 0, sctp_assoc_established, struct sctp_association *asoc, - struct sk_buff *skb) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, sctp_assoc_established, + struct sctp_association *asoc, struct sk_buff *skb) #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_INFINIBAND -LSM_HOOK(int, 0, ib_pkey_access, void *sec, u64 subnet_prefix, u16 pkey) -LSM_HOOK(int, 0, ib_endport_manage_subnet, void *sec, const char *dev_name, - u8 port_num) -LSM_HOOK(int, 0, ib_alloc_security, void **sec) -LSM_HOOK(void, LSM_RET_VOID, ib_free_security, void *sec) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, ib_pkey_access, void *sec, + u64 subnet_prefix, u16 pkey) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, ib_endport_manage_subnet, + void *sec, const char *dev_name, u8 port_num) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, ib_alloc_security, void **sec) +LSM_HOOK(void, LSM_RET_VOID, 0, ib_free_security, void *sec) #endif /* CONFIG_SECURITY_INFINIBAND */ #ifdef CONFIG_SECURITY_NETWORK_XFRM -LSM_HOOK(int, 0, xfrm_policy_alloc_security, struct xfrm_sec_ctx **ctxp, - struct xfrm_user_sec_ctx *sec_ctx, gfp_t gfp) -LSM_HOOK(int, 0, xfrm_policy_clone_security, struct xfrm_sec_ctx *old_ctx, - struct xfrm_sec_ctx **new_ctx) -LSM_HOOK(void, LSM_RET_VOID, xfrm_policy_free_security, +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, xfrm_policy_alloc_security, + struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx, + gfp_t gfp) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, xfrm_policy_clone_security, + struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctx) +LSM_HOOK(void, LSM_RET_VOID, 0, xfrm_policy_free_security, + struct xfrm_sec_ctx *ctx) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, xfrm_policy_delete_security, struct xfrm_sec_ctx *ctx) -LSM_HOOK(int, 0, xfrm_policy_delete_security, struct xfrm_sec_ctx *ctx) -LSM_HOOK(int, 0, xfrm_state_alloc, struct xfrm_state *x, - struct xfrm_user_sec_ctx *sec_ctx) -LSM_HOOK(int, 0, xfrm_state_alloc_acquire, struct xfrm_state *x, - struct xfrm_sec_ctx *polsec, u32 secid) -LSM_HOOK(void, LSM_RET_VOID, xfrm_state_free_security, struct xfrm_state *x) -LSM_HOOK(int, 0, xfrm_state_delete_security, struct xfrm_state *x) -LSM_HOOK(int, 0, xfrm_policy_lookup, struct xfrm_sec_ctx *ctx, u32 fl_secid) -LSM_HOOK(int, 1, xfrm_state_pol_flow_match, struct xfrm_state *x, - struct xfrm_policy *xp, const struct flowi_common *flic) -LSM_HOOK(int, 0, xfrm_decode_session, struct sk_buff *skb, u32 *secid, - int ckall) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, xfrm_state_alloc, + struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, xfrm_state_alloc_acquire, + struct xfrm_state *x, struct xfrm_sec_ctx *polsec, u32 secid) +LSM_HOOK(void, LSM_RET_VOID, 0, xfrm_state_free_security, struct xfrm_state *x) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, xfrm_state_delete_security, + struct xfrm_state *x) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, xfrm_policy_lookup, + struct xfrm_sec_ctx *ctx, u32 fl_secid) +LSM_HOOK(int, 1, LSM_RET_ZERO | LSM_RET_ONE, xfrm_state_pol_flow_match, + struct xfrm_state *x, struct xfrm_policy *xp, + const struct flowi_common *flic) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, xfrm_decode_session, + struct sk_buff *skb, u32 *secid, int ckall) #endif /* CONFIG_SECURITY_NETWORK_XFRM */ /* key management security hooks */ #ifdef CONFIG_KEYS -LSM_HOOK(int, 0, key_alloc, struct key *key, const struct cred *cred, - unsigned long flags) -LSM_HOOK(void, LSM_RET_VOID, key_free, struct key *key) -LSM_HOOK(int, 0, key_permission, key_ref_t key_ref, const struct cred *cred, - enum key_need_perm need_perm) -LSM_HOOK(int, 0, key_getsecurity, struct key *key, char **_buffer) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, key_alloc, struct key *key, + const struct cred *cred, unsigned long flags) +LSM_HOOK(void, LSM_RET_VOID, 0, key_free, struct key *key) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, key_permission, key_ref_t key_ref, + const struct cred *cred, enum key_need_perm need_perm) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO | LSM_RET_ONE | LSM_RET_GT_ONE, + key_getsecurity, struct key *key, char **_buffer) #endif /* CONFIG_KEYS */ #ifdef CONFIG_AUDIT -LSM_HOOK(int, 0, audit_rule_init, u32 field, u32 op, char *rulestr, - void **lsmrule) -LSM_HOOK(int, 0, audit_rule_known, struct audit_krule *krule) -LSM_HOOK(int, 0, audit_rule_match, u32 secid, u32 field, u32 op, void *lsmrule) -LSM_HOOK(void, LSM_RET_VOID, audit_rule_free, void *lsmrule) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, audit_rule_init, u32 field, u32 op, + char *rulestr, void **lsmrule) +LSM_HOOK(int, 0, LSM_RET_ZERO | LSM_RET_ONE, audit_rule_known, + struct audit_krule *krule) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO | LSM_RET_ONE, audit_rule_match, + u32 secid, u32 field, u32 op, void *lsmrule) +LSM_HOOK(void, LSM_RET_VOID, 0, audit_rule_free, void *lsmrule) #endif /* CONFIG_AUDIT */ #ifdef CONFIG_BPF_SYSCALL -LSM_HOOK(int, 0, bpf, int cmd, union bpf_attr *attr, unsigned int size) -LSM_HOOK(int, 0, bpf_map, struct bpf_map *map, fmode_t fmode) -LSM_HOOK(int, 0, bpf_prog, struct bpf_prog *prog) -LSM_HOOK(int, 0, bpf_map_alloc_security, struct bpf_map *map) -LSM_HOOK(void, LSM_RET_VOID, bpf_map_free_security, struct bpf_map *map) -LSM_HOOK(int, 0, bpf_prog_alloc_security, struct bpf_prog_aux *aux) -LSM_HOOK(void, LSM_RET_VOID, bpf_prog_free_security, struct bpf_prog_aux *aux) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, bpf, int cmd, union bpf_attr *attr, + unsigned int size) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, bpf_map, struct bpf_map *map, + fmode_t fmode) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, bpf_prog, struct bpf_prog *prog) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, bpf_map_alloc_security, + struct bpf_map *map) +LSM_HOOK(void, LSM_RET_VOID, 0, bpf_map_free_security, struct bpf_map *map) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, bpf_prog_alloc_security, + struct bpf_prog_aux *aux) +LSM_HOOK(void, LSM_RET_VOID, 0, bpf_prog_free_security, struct bpf_prog_aux *aux) #endif /* CONFIG_BPF_SYSCALL */ -LSM_HOOK(int, 0, locked_down, enum lockdown_reason what) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, locked_down, + enum lockdown_reason what) #ifdef CONFIG_PERF_EVENTS -LSM_HOOK(int, 0, perf_event_open, struct perf_event_attr *attr, int type) -LSM_HOOK(int, 0, perf_event_alloc, struct perf_event *event) -LSM_HOOK(void, LSM_RET_VOID, perf_event_free, struct perf_event *event) -LSM_HOOK(int, 0, perf_event_read, struct perf_event *event) -LSM_HOOK(int, 0, perf_event_write, struct perf_event *event) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, perf_event_open, + struct perf_event_attr *attr, int type) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, perf_event_alloc, + struct perf_event *event) +LSM_HOOK(void, LSM_RET_VOID, 0, perf_event_free, struct perf_event *event) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, perf_event_read, + struct perf_event *event) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, perf_event_write, + struct perf_event *event) #endif /* CONFIG_PERF_EVENTS */ #ifdef CONFIG_IO_URING -LSM_HOOK(int, 0, uring_override_creds, const struct cred *new) -LSM_HOOK(int, 0, uring_sqpoll, void) -LSM_HOOK(int, 0, uring_cmd, struct io_uring_cmd *ioucmd) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, uring_override_creds, + const struct cred *new) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, uring_sqpoll, void) +LSM_HOOK(int, 0, LSM_RET_NEG | LSM_RET_ZERO, uring_cmd, + struct io_uring_cmd *ioucmd) #endif /* CONFIG_IO_URING */ diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index c0c570b7eabd..1911675a0da0 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1642,13 +1642,13 @@ * */ union security_list_options { - #define LSM_HOOK(RET, DEFAULT, NAME, ...) RET (*NAME)(__VA_ARGS__); + #define LSM_HOOK(RET, DEFAULT, RET_FLAGS, NAME, ...) RET (*NAME)(__VA_ARGS__); #include "lsm_hook_defs.h" #undef LSM_HOOK }; struct security_hook_heads { - #define LSM_HOOK(RET, DEFAULT, NAME, ...) struct hlist_head NAME; + #define LSM_HOOK(RET, DEFAULT, RET_FLAGS, NAME, ...) struct hlist_head NAME; #include "lsm_hook_defs.h" #undef LSM_HOOK } __randomize_layout; @@ -1683,6 +1683,11 @@ struct lsm_blob_sizes { */ #define LSM_RET_VOID ((void) 0) +#define LSM_RET_NEG 0x00000001 +#define LSM_RET_ZERO 0x00000002 +#define LSM_RET_ONE 0x00000004 +#define LSM_RET_GT_ONE 0x00000008 + /* * Initializing a security_hook_list structure takes * up a lot of space in a source file. This macro takes diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c index d6c9b3705f24..37bcedf5a44e 100644 --- a/kernel/bpf/bpf_lsm.c +++ b/kernel/bpf/bpf_lsm.c @@ -21,7 +21,7 @@ /* For every LSM hook that allows attachment of BPF programs, declare a nop * function where a BPF program can be attached. */ -#define LSM_HOOK(RET, DEFAULT, NAME, ...) \ +#define LSM_HOOK(RET, DEFAULT, RET_FLAGS, NAME, ...) \ noinline RET bpf_lsm_##NAME(__VA_ARGS__) \ { \ return DEFAULT; \ @@ -30,7 +30,8 @@ noinline RET bpf_lsm_##NAME(__VA_ARGS__) \ #include #undef LSM_HOOK -#define LSM_HOOK(RET, DEFAULT, NAME, ...) BTF_ID(func, bpf_lsm_##NAME) +#define LSM_HOOK(RET, DEFAULT, RET_FLAGS, NAME, ...) \ + BTF_ID(func, bpf_lsm_##NAME) BTF_SET_START(bpf_lsm_hooks) #include #undef LSM_HOOK diff --git a/security/bpf/hooks.c b/security/bpf/hooks.c index e5971fa74fd7..a2a3b2be345f 100644 --- a/security/bpf/hooks.c +++ b/security/bpf/hooks.c @@ -7,7 +7,7 @@ #include static struct security_hook_list bpf_lsm_hooks[] __lsm_ro_after_init = { - #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ + #define LSM_HOOK(RET, DEFAULT, RET_FLAGS, NAME, ...) \ LSM_HOOK_INIT(NAME, bpf_lsm_##NAME), #include #undef LSM_HOOK diff --git a/security/security.c b/security/security.c index 79d82cb6e469..4041d24e3283 100644 --- a/security/security.c +++ b/security/security.c @@ -371,7 +371,7 @@ int __init early_security_init(void) { struct lsm_info *lsm; -#define LSM_HOOK(RET, DEFAULT, NAME, ...) \ +#define LSM_HOOK(RET, DEFAULT, RET_FLAGS, NAME, ...) \ INIT_HLIST_HEAD(&security_hook_heads.NAME); #include "linux/lsm_hook_defs.h" #undef LSM_HOOK @@ -710,7 +710,7 @@ static int lsm_superblock_alloc(struct super_block *sb) #define DECLARE_LSM_RET_DEFAULT_void(DEFAULT, NAME) #define DECLARE_LSM_RET_DEFAULT_int(DEFAULT, NAME) \ static const int __maybe_unused LSM_RET_DEFAULT(NAME) = (DEFAULT); -#define LSM_HOOK(RET, DEFAULT, NAME, ...) \ +#define LSM_HOOK(RET, DEFAULT, RET_FLAGS, NAME, ...) \ DECLARE_LSM_RET_DEFAULT_##RET(DEFAULT, NAME) #include From patchwork Tue Nov 15 17:56:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 13044039 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 7ED94C43217 for ; Tue, 15 Nov 2022 17:59:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231889AbiKOR7E (ORCPT ); Tue, 15 Nov 2022 12:59:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50512 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231596AbiKOR6L (ORCPT ); Tue, 15 Nov 2022 12:58:11 -0500 Received: from frasgout13.his.huawei.com (frasgout13.his.huawei.com [14.137.139.46]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6E2692F3BE; Tue, 15 Nov 2022 09:58:10 -0800 (PST) Received: from mail02.huawei.com (unknown [172.18.147.228]) by frasgout13.his.huawei.com (SkyGuard) with ESMTP id 4NBYdS3q2Dz9xs6c; Wed, 16 Nov 2022 01:51:24 +0800 (CST) Received: from huaweicloud.com (unknown [10.204.63.22]) by APP1 (Coremail) with SMTP id LxC2BwCHcW7o0nNj73dpAA--.16599S6; Tue, 15 Nov 2022 18:57:46 +0100 (CET) From: Roberto Sassu To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yhs@fb.com, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, revest@chromium.org, jackmanb@chromium.org, paul@paul-moore.com, jmorris@namei.org, serge@hallyn.com Cc: bpf@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, Roberto Sassu Subject: [RFC][PATCH 4/4] security: Enforce limitations on return values from LSMs Date: Tue, 15 Nov 2022 18:56:52 +0100 Message-Id: <20221115175652.3836811-5-roberto.sassu@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221115175652.3836811-1-roberto.sassu@huaweicloud.com> References: <20221115175652.3836811-1-roberto.sassu@huaweicloud.com> MIME-Version: 1.0 X-CM-TRANSID: LxC2BwCHcW7o0nNj73dpAA--.16599S6 X-Coremail-Antispam: 1UD129KBjvJXoWxZFykWF4kJF4UJF1xGw47XFb_yoW5Jw47pw 4akFy5KF4j9Fy7XFZ3tanxua1Sv3yrKr4DCrZxXw15Za98Jwn8J3W8tF15tF1rCry8t34Y gF4Ut3y5Cw4DG37anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUPlb4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUAV Cq3wA2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVWUCVW8JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr0_Cr1l84ACjcxK6I8E87Iv6xkF7I0E 14v26r4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_JrI_JrylYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE 7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACI402YVCY1x02628vn2kIc2xKxwCY1x0262 kKe7AKxVW8ZVWrXwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s02 6c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_GF v_WrylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI42IY6xIIjxv20xvE c7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aV AFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZF pf9x07j7GYLUUUUU= X-CM-SenderInfo: purev21wro2thvvxqx5xdzvxpfor3voofrz/1tbiAgARBF1jj4F5bgAAsw X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-State: RFC From: Roberto Sassu LSMs should not be able to return arbitrary return values, as the callers of the LSM infrastructure might not be ready to handle unexpected values (e.g. positive values that are first converted to a pointer with ERR_PTR, and then evaluated with IS_ERR()). Modify call_int_hook() to call is_ret_value_allowed(), so that the return value from each LSM for a given hook is checked. If for the interval the return value falls into the corresponding flag is not set, change the return value to the default value, just for the current LSM. A misbehaving LSM would not have impact on the decision of other LSMs, as the loop terminates whenever the return value is not zero. Signed-off-by: Roberto Sassu --- security/security.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/security/security.c b/security/security.c index 4041d24e3283..cd417a8a0e65 100644 --- a/security/security.c +++ b/security/security.c @@ -716,6 +716,35 @@ static int lsm_superblock_alloc(struct super_block *sb) #include #undef LSM_HOOK +/* + * The return value flags of the LSM hook are defined in linux/lsm_hook_defs.h + * and can be accessed with: + * + * LSM_RET_FLAGS() + * + * The macros below define static constants for the return value flags of each + * LSM hook. + */ +#define LSM_RET_FLAGS(NAME) (NAME##_ret_flags) +#define DECLARE_LSM_RET_FLAGS(RET_FLAGS, NAME) \ + static const u32 __maybe_unused LSM_RET_FLAGS(NAME) = (RET_FLAGS); +#define LSM_HOOK(RET, DEFAULT, RET_FLAGS, NAME, ...) \ + DECLARE_LSM_RET_FLAGS(RET_FLAGS, NAME) + +#include +#undef LSM_HOOK + +static bool is_ret_value_allowed(int ret, u32 ret_flags) +{ + if ((ret < 0 && !(ret_flags & LSM_RET_NEG)) || + (ret == 0 && !(ret_flags & LSM_RET_ZERO)) || + (ret == 1 && !(ret_flags & LSM_RET_ONE)) || + (ret > 1 && !(ret_flags & LSM_RET_GT_ONE))) + return false; + + return true; +} + /* * Hook list operation macros. * @@ -741,6 +770,11 @@ static int lsm_superblock_alloc(struct super_block *sb) \ hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \ RC = P->hook.FUNC(__VA_ARGS__); \ + if (!is_ret_value_allowed(RC, LSM_RET_FLAGS(FUNC))) { \ + WARN_ONCE(1, "Illegal ret %d for " #FUNC " from %s, forcing %d\n", \ + RC, P->lsm, LSM_RET_DEFAULT(FUNC)); \ + RC = LSM_RET_DEFAULT(FUNC); \ + } \ if (RC != 0) \ break; \ } \