From patchwork Thu Oct 13 22:36:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 2427 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp510545wrs; Thu, 13 Oct 2022 15:38:47 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6204paq4rVh8YJjd4lpJKNGNrsPV/SR9ikqjutKu3IjC895RMFFMcjN6nzTqrBNG+xhrks X-Received: by 2002:a05:6402:4505:b0:451:1551:7b14 with SMTP id ez5-20020a056402450500b0045115517b14mr1706496edb.300.1665700727452; Thu, 13 Oct 2022 15:38:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665700727; cv=none; d=google.com; s=arc-20160816; b=pknYgA8skjaCwt7qGGPkGFhbsr2y08JucAixLT8+Ul0h2+Lh71HedwMKXh8IHE794n heP0KN+HqmuOnIYoEuF5iA2lIX4+9M0x2pGfBQgAUlJ9XqcU79IwiZx7G8WVaCNOd6X7 5jeE6WEvNKOHbAduOL3C0/d0uAPce+mabSEnKQ5pFRagSMOGicffAZIdQOxVwMDdYZ39 uzjuiZwfgeMlLw4Cc4nc7dYCLtaWHk8wspLllhJA5TkMZ1rnaPjxIWk8LoGkHERbPZ2h PZUMroZf6c/H8r9Vm9EVWQQS9Whivf4kaVws8nUD207iiq/D8GXOerDwzThyd3envaNu dm7Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=4QtMvi+okgythLC0BZ5AgbF6b/T036dwH9EuwQzqT3w=; b=t2xviPoTAkM3sHVqKTkbN+O42WlD6Dsx636cKXBs2BuntK74YCbdRoFxtRZ29KfKO1 xhs2r3s5klZ9OsIJdTVRE7i5/caFgo+1MoMAnJbNKFvt9JJ80+BDHcH9nMYvV3RkArsX rAOBFenES8oqT92dMNoWoi/0D8kNig1TRyOYmlsAlVan/pcN6RVNbHYiuByIrhb6aVay YutmFN5clfNScU9+R1WOS7qL5DenCv04WOe0Q8agVBM2HNIMp6uhZXgDFQFLp5VxhEWn U9KdDRiKj7RKUXVZHOOHz9uhKtmj3Lkm8WbNyzg8M4GjaA2pKak/ACkGQCW16uIVb0s5 xsCg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=oPHpU2FN; 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=chromium.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id cs13-20020a170906dc8d00b0077b4248b138si766427ejc.127.2022.10.13.15.38.19; Thu, 13 Oct 2022 15:38:47 -0700 (PDT) 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=@chromium.org header.s=google header.b=oPHpU2FN; 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=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229780AbiJMWhR (ORCPT + 99 others); Thu, 13 Oct 2022 18:37:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43528 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229683AbiJMWhD (ORCPT ); Thu, 13 Oct 2022 18:37:03 -0400 Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 283ED11A975 for ; Thu, 13 Oct 2022 15:37:00 -0700 (PDT) Received: by mail-pl1-x631.google.com with SMTP id k9so2673376pll.11 for ; Thu, 13 Oct 2022 15:36:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4QtMvi+okgythLC0BZ5AgbF6b/T036dwH9EuwQzqT3w=; b=oPHpU2FNCIKE86DHkbE5v7YdCVfFxuOh2IeHYY2DreHarIwYexNLRoxwOscPXlk54Z 2XsBONOx9Ca9mdC2873canzK4z+yM15aoISs7hNWPzcT1YPJUreGCcYGFpRBB6gle9kl 5vsX6q8Bvc8b4zxMGfPt3LYcWr74dN592yUGU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4QtMvi+okgythLC0BZ5AgbF6b/T036dwH9EuwQzqT3w=; b=kALKxd81UlPRA1ISd8hEb04amHN7DcsjoEXc9rQgc2W0YriJOWWKM7VOPxrUn+/vw0 iA6GchE/H1zJPYanOpobNwI5Wu9FDZ194DQ62nJ/7Z0kiq9i1HZmeOqKc/k9unaq5JZh rZlF2uZ0LUA4MjZK/zjG4lbgobFb8DoHxPqm7sp+A3A+aulqQUdr0uEgUGg5Rvssl/u3 3RhXnvEqvLkAbb+Bu64z/JxsRMv6gVNrjkd8ADiRGvFKzAahizm9ZDRqToQHz5bitPi1 UZnosJDXymA6yq8NgAUOhAYgI381AqBkethyhAWB9vpFIMn4n6YO1JphgtRTZHYBxIdA atFA== X-Gm-Message-State: ACrzQf11flTeXSSeE0HYVi+bisaq04OBTAp9TGXE9dqcU3QXUaONWfLR Kf7ObdS74DHhu/v8Y3O3TQl64w== X-Received: by 2002:a17:90b:1e0b:b0:20d:7ddf:9b08 with SMTP id pg11-20020a17090b1e0b00b0020d7ddf9b08mr2169714pjb.187.1665700618898; Thu, 13 Oct 2022 15:36:58 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id q135-20020a632a8d000000b004277f43b736sm188041pgq.92.2022.10.13.15.36.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Oct 2022 15:36:56 -0700 (PDT) From: Kees Cook To: Mimi Zohar Cc: Kees Cook , Paul Moore , James Morris , "Serge E. Hallyn" , Dmitry Kasatkin , =?utf-8?q?Micka=C3=ABl_Sala?= =?utf-8?q?=C3=BCn?= , Petr Vorel , Borislav Petkov , Takashi Iwai , Jonathan McDowell , linux-security-module@vger.kernel.org, linux-integrity@vger.kernel.org, KP Singh , Casey Schaufler , John Johansen , linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH 2/9] security: Move trivial IMA hooks into LSM Date: Thu, 13 Oct 2022 15:36:47 -0700 Message-Id: <20221013223654.659758-2-keescook@chromium.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221013222702.never.990-kees@kernel.org> References: <20221013222702.never.990-kees@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=11716; h=from:subject; bh=JPYrXEme63zNrHu8RasMAYqzn5dsYfwQ9sKlRFYwCmg=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBjSJMEBD/MwZ0ABEhYQJlMhma7ILk1MIOCXpU03Rs0 Pj96qRKJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCY0iTBAAKCRCJcvTf3G3AJgJlEA Cl24Ozc1VocmsUXHG32wY4+VYx+AcAuzOiJniFxKvvLj9WZt1tVP6AZjctFfMVwWIYt2Nlp0w5NaLq KR6DqQStima1UGNyAr4KydA8JnaQnpwN77IwaHZ1ICYrUrKzOrdOXu5F+QhyxgHODuswpWPtwVK+ew x8JxGGC1WNatLweiisDHYYWDztKqyLRM5zAdyVG29XHOoXyKvEcLVuYuRaJFLZhCgoL6rWTqQHibTE L3ZJ15erp8I3sBCswkF/cutq1D/h4FkF0ipjXmE4sq5Q4sDFAMLzsVeLoS+77uNySIufqHNEzEJvsv MtkRe9YfjdQ1ebLBOmRTwJ4DK9ygu5UYyEFE3DVjl6s9WCF7xoeeyw1xGeAmWZCGEISesOX3EK1qc6 QG2Qvh0zysfKi4bQh+X/w7YHus44k+O8wibXQXMCOeMA7MayrCMPXDiSLOU13TyewKQKYAR1MaNfMo T2CssSFp7cVYpPa2V1ko6UScmuAnLVwuzGlDI97OoskTZeNpZUCU0SDObm1+NrjbO/OVm4Oz6q3Rry hToO3DDPLYNqpYUahPlARDjFN5Yd85npwGh+K3T3xS75m7UM1ZXJnG1yltz+N2SBik1ARXebC7yHhh PymeAcPzWH1I8+VKQ4In6NgU0I2xesFr6C2GXdeu8txN30aQHn3wLGlT3Y0A== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable 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 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746613806180123338?= X-GMAIL-MSGID: =?utf-8?q?1746613806180123338?= This moves the trivial hard-coded stacking of IMA LSM hooks into the existing LSM infrastructure. Cc: Paul Moore Cc: James Morris Cc: "Serge E. Hallyn" Cc: Mimi Zohar Cc: Dmitry Kasatkin Cc: "Mickaël Salaün" Cc: Petr Vorel Cc: Borislav Petkov Cc: Takashi Iwai Cc: Jonathan McDowell Cc: linux-security-module@vger.kernel.org Cc: linux-integrity@vger.kernel.org Signed-off-by: Kees Cook --- include/linux/ima.h | 50 ----------------------------- security/integrity/ima/ima_main.c | 40 +++++++++++++++++------- security/security.c | 52 ++++++------------------------- 3 files changed, 37 insertions(+), 105 deletions(-) diff --git a/include/linux/ima.h b/include/linux/ima.h index 81708ca0ebc7..3c641cc65270 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -16,20 +16,10 @@ struct linux_binprm; #ifdef CONFIG_IMA extern enum hash_algo ima_get_current_hash_algo(void); -extern int ima_bprm_check(struct linux_binprm *bprm); extern int ima_file_check(struct file *file, int mask); extern void ima_post_create_tmpfile(struct user_namespace *mnt_userns, struct inode *inode); extern void ima_file_free(struct file *file); -extern int ima_file_mmap(struct file *file, unsigned long prot); -extern int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot); -extern int ima_load_data(enum kernel_load_data_id id, bool contents); -extern int ima_post_load_data(char *buf, loff_t size, - enum kernel_load_data_id id, char *description); -extern int ima_read_file(struct file *file, enum kernel_read_file_id id, - bool contents); -extern int ima_post_read_file(struct file *file, void *buf, loff_t size, - enum kernel_read_file_id id); extern void ima_post_path_mknod(struct user_namespace *mnt_userns, struct dentry *dentry); extern int ima_file_hash(struct file *file, char *buf, size_t buf_size); @@ -56,11 +46,6 @@ static inline enum hash_algo ima_get_current_hash_algo(void) return HASH_ALGO__LAST; } -static inline int ima_bprm_check(struct linux_binprm *bprm) -{ - return 0; -} - static inline int ima_file_check(struct file *file, int mask) { return 0; @@ -76,41 +61,6 @@ static inline void ima_file_free(struct file *file) return; } -static inline int ima_file_mmap(struct file *file, unsigned long prot) -{ - return 0; -} - -static inline int ima_file_mprotect(struct vm_area_struct *vma, - unsigned long prot) -{ - return 0; -} - -static inline int ima_load_data(enum kernel_load_data_id id, bool contents) -{ - return 0; -} - -static inline int ima_post_load_data(char *buf, loff_t size, - enum kernel_load_data_id id, - char *description) -{ - return 0; -} - -static inline int ima_read_file(struct file *file, enum kernel_read_file_id id, - bool contents) -{ - return 0; -} - -static inline int ima_post_read_file(struct file *file, void *buf, loff_t size, - enum kernel_read_file_id id) -{ - return 0; -} - static inline void ima_post_path_mknod(struct user_namespace *mnt_userns, struct dentry *dentry) { diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index e617863af5ff..2cff001b02e4 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -395,6 +395,7 @@ static int process_measurement(struct file *file, const struct cred *cred, /** * ima_file_mmap - based on policy, collect/store measurement. * @file: pointer to the file to be measured (May be NULL) + * @reqprot: contains the protection that will be applied by the kernel. * @prot: contains the protection that will be applied by the kernel. * * Measure files being mmapped executable based on the ima_must_measure() @@ -403,11 +404,12 @@ static int process_measurement(struct file *file, const struct cred *cred, * On success return 0. On integrity appraisal error, assuming the file * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. */ -int ima_file_mmap(struct file *file, unsigned long prot) +static int ima_file_mmap(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags) { u32 secid; - if (file && (prot & PROT_EXEC)) { + if (file && (reqprot & PROT_EXEC)) { security_current_getsecid_subj(&secid); return process_measurement(file, current_cred(), secid, NULL, 0, MAY_EXEC, MMAP_CHECK); @@ -419,6 +421,7 @@ int ima_file_mmap(struct file *file, unsigned long prot) /** * ima_file_mprotect - based on policy, limit mprotect change * @vma: vm_area_struct protection is set to + * @reqprot: contains the protection that were requested. * @prot: contains the protection that will be applied by the kernel. * * Files can be mmap'ed read/write and later changed to execute to circumvent @@ -429,7 +432,8 @@ int ima_file_mmap(struct file *file, unsigned long prot) * * On mprotect change success, return 0. On failure, return -EACESS. */ -int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot) +static int ima_file_mprotect(struct vm_area_struct *vma, + unsigned long reqprot, unsigned long prot) { struct ima_template_desc *template = NULL; struct file *file; @@ -483,7 +487,7 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot) * On success return 0. On integrity appraisal error, assuming the file * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. */ -int ima_bprm_check(struct linux_binprm *bprm) +static int ima_bprm_check(struct linux_binprm *bprm) { int ret; u32 secid; @@ -706,8 +710,8 @@ void ima_post_path_mknod(struct user_namespace *mnt_userns, * * For permission return 0, otherwise return -EACCES. */ -int ima_read_file(struct file *file, enum kernel_read_file_id read_id, - bool contents) +static int ima_read_file(struct file *file, enum kernel_read_file_id read_id, + bool contents) { enum ima_hooks func; u32 secid; @@ -756,8 +760,8 @@ const int read_idmap[READING_MAX_ID] = { * On success return 0. On integrity appraisal error, assuming the file * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. */ -int ima_post_read_file(struct file *file, void *buf, loff_t size, - enum kernel_read_file_id read_id) +static int ima_post_read_file(struct file *file, char *buf, loff_t size, + enum kernel_read_file_id read_id) { enum ima_hooks func; u32 secid; @@ -790,7 +794,7 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, * * For permission return 0, otherwise return -EACCES. */ -int ima_load_data(enum kernel_load_data_id id, bool contents) +static int ima_load_data(enum kernel_load_data_id id, bool contents) { bool ima_enforce, sig_enforce; @@ -844,9 +848,9 @@ int ima_load_data(enum kernel_load_data_id id, bool contents) * On success return 0. On integrity appraisal error, assuming the file * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. */ -int ima_post_load_data(char *buf, loff_t size, - enum kernel_load_data_id load_id, - char *description) +static int ima_post_load_data(char *buf, loff_t size, + enum kernel_load_data_id load_id, + char *description) { if (load_id == LOADING_FIRMWARE) { if ((ima_appraise & IMA_APPRAISE_FIRMWARE) && @@ -1077,6 +1081,18 @@ static int __init init_ima(void) late_initcall(init_ima); /* Start IMA after the TPM is available */ +static struct security_hook_list ima_hooks[] __lsm_ro_after_init = { + LSM_HOOK_INIT(bprm_check_security, ima_bprm_check), + LSM_HOOK_INIT(mmap_file, ima_file_mmap), + LSM_HOOK_INIT(file_mprotect, ima_file_mprotect), + LSM_HOOK_INIT(kernel_read_file, ima_read_file), + LSM_HOOK_INIT(kernel_post_read_file, ima_post_read_file), + LSM_HOOK_INIT(kernel_load_data, ima_load_data), + LSM_HOOK_INIT(kernel_post_load_data, ima_post_load_data), +}; + void __init integrity_lsm_ima_init(void) { + pr_info("Integrity LSM enabling IMA\n"); + integrity_add_lsm_hooks(ima_hooks, ARRAY_SIZE(ima_hooks)); } diff --git a/security/security.c b/security/security.c index 14d30fec8a00..8f7c1b5fa5fa 100644 --- a/security/security.c +++ b/security/security.c @@ -862,12 +862,7 @@ int security_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file) int security_bprm_check(struct linux_binprm *bprm) { - int ret; - - ret = call_int_hook(bprm_check_security, 0, bprm); - if (ret) - return ret; - return ima_bprm_check(bprm); + return call_int_hook(bprm_check_security, 0, bprm); } void security_bprm_committing_creds(struct linux_binprm *bprm) @@ -1589,12 +1584,8 @@ static inline unsigned long mmap_prot(struct file *file, unsigned long prot) int security_mmap_file(struct file *file, unsigned long prot, unsigned long flags) { - int ret; - ret = call_int_hook(mmap_file, 0, file, prot, - mmap_prot(file, prot), flags); - if (ret) - return ret; - return ima_file_mmap(file, prot); + return call_int_hook(mmap_file, 0, file, prot, + mmap_prot(file, prot), flags); } int security_mmap_addr(unsigned long addr) @@ -1605,12 +1596,7 @@ int security_mmap_addr(unsigned long addr) int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, unsigned long prot) { - int ret; - - ret = call_int_hook(file_mprotect, 0, vma, reqprot, prot); - if (ret) - return ret; - return ima_file_mprotect(vma, prot); + return call_int_hook(file_mprotect, 0, vma, reqprot, prot); } int security_file_lock(struct file *file, unsigned int cmd) @@ -1746,35 +1732,20 @@ int security_kernel_module_request(char *kmod_name) int security_kernel_read_file(struct file *file, enum kernel_read_file_id id, bool contents) { - int ret; - - ret = call_int_hook(kernel_read_file, 0, file, id, contents); - if (ret) - return ret; - return ima_read_file(file, id, contents); + return call_int_hook(kernel_read_file, 0, file, id, contents); } EXPORT_SYMBOL_GPL(security_kernel_read_file); int security_kernel_post_read_file(struct file *file, char *buf, loff_t size, enum kernel_read_file_id id) { - int ret; - - ret = call_int_hook(kernel_post_read_file, 0, file, buf, size, id); - if (ret) - return ret; - return ima_post_read_file(file, buf, size, id); + return call_int_hook(kernel_post_read_file, 0, file, buf, size, id); } EXPORT_SYMBOL_GPL(security_kernel_post_read_file); int security_kernel_load_data(enum kernel_load_data_id id, bool contents) { - int ret; - - ret = call_int_hook(kernel_load_data, 0, id, contents); - if (ret) - return ret; - return ima_load_data(id, contents); + return call_int_hook(kernel_load_data, 0, id, contents); } EXPORT_SYMBOL_GPL(security_kernel_load_data); @@ -1782,13 +1753,8 @@ int security_kernel_post_load_data(char *buf, loff_t size, enum kernel_load_data_id id, char *description) { - int ret; - - ret = call_int_hook(kernel_post_load_data, 0, buf, size, id, - description); - if (ret) - return ret; - return ima_post_load_data(buf, size, id, description); + return call_int_hook(kernel_post_load_data, 0, buf, size, id, + description); } EXPORT_SYMBOL_GPL(security_kernel_post_load_data);