Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp113672yba; Wed, 17 Apr 2019 20:55:48 -0700 (PDT) X-Google-Smtp-Source: APXvYqwvifiedhBM1Qwt09pytdS5fe5vBZU93rAduT5QY9w5TTEJkwdG4Sxf4py6KErmnBaaRZ8v X-Received: by 2002:a63:1e22:: with SMTP id e34mr8644120pge.69.1555559748593; Wed, 17 Apr 2019 20:55:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1555559748; cv=none; d=google.com; s=arc-20160816; b=H6YQOBYKdzLLctGj6wCVED2JsoJraanjpWf1Nau0IpE5Qp8UF8Uh19iocQzMnp1dEl 7jN/FMK7IEmMkajlotp1WkIh2LWDwOrOPCw+x1S1dHZZJq/pN9FJK0jgWoV2gDj5g+Ln wvFa4nIXPFa3oxufw69JA6YvLbmW75VYUUtVmHxuyFoYxfeExpdJvSfQC2TD1T33v4or ZgZ3vrNBEZxzDOEUBqvnOrsI/f1M6/CyAcwnB8t4pb2lH7A+D5vdR+MuFo6n21XiTACq DPr6kTZGhH/W1vlper1MBeDgsBJzb6UiCPeJG7w9jBP/Sdhi24ZSbYTjl82z5bObee9/ M5ag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:references:in-reply-to:date :subject:cc:to:from; bh=t/2o481Ff70qjbnpvAUGHTKkjMsrcrd1X/oGmwv40gA=; b=naiZ6AjtTTdDj7POuhBazdCWmWEMUdattCvUx55mPrLroUs6i7gf6I93iAsuekOKjR GpJA3bU5EjwP1pNslyR7hbzCaVE+Hpn7xtDHqQSZvnsrnTiCgede685DlyoQmJovCRwk OqPC1bAsigIO4fYD60vPwo4lmV2cT9kX4H8bdwcHMG+5t5hwhGwRWvkV14GrCjAc7dSS FC7TwBWc7Hlht8HoLa8SdD2EqLMheNzWL3BGPQmgFhP9sEZ6MWYPSqh7XT/4Uz3DArHK QL3fc2DFERRUxHTNeJ7RQD+HQMvPOiNVuqwAF9CnSOQgiYhnrKzHDy6mtQS+4QEq8NQl KaZw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q1si1178523pfb.68.2019.04.17.20.55.32; Wed, 17 Apr 2019 20:55:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388119AbfDRDwh (ORCPT + 99 others); Wed, 17 Apr 2019 23:52:37 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:52174 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2388110AbfDRDwf (ORCPT ); Wed, 17 Apr 2019 23:52:35 -0400 Received: from pps.filterd (m0098420.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x3I3o8KS191168 for ; Wed, 17 Apr 2019 23:52:34 -0400 Received: from e36.co.us.ibm.com (e36.co.us.ibm.com [32.97.110.154]) by mx0b-001b2d01.pphosted.com with ESMTP id 2rxf86mtwk-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 17 Apr 2019 23:52:34 -0400 Received: from localhost by e36.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 18 Apr 2019 04:52:33 +0100 Received: from b03cxnp07029.gho.boulder.ibm.com (9.17.130.16) by e36.co.us.ibm.com (192.168.1.136) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Thu, 18 Apr 2019 04:52:26 +0100 Received: from b03ledav004.gho.boulder.ibm.com (b03ledav004.gho.boulder.ibm.com [9.17.130.235]) by b03cxnp07029.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x3I3qPF128377250 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 18 Apr 2019 03:52:25 GMT Received: from b03ledav004.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 21EA27805F; Thu, 18 Apr 2019 03:52:25 +0000 (GMT) Received: from b03ledav004.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 95D297805C; Thu, 18 Apr 2019 03:52:20 +0000 (GMT) Received: from morokweng.localdomain.com (unknown [9.85.230.182]) by b03ledav004.gho.boulder.ibm.com (Postfix) with ESMTP; Thu, 18 Apr 2019 03:52:20 +0000 (GMT) From: Thiago Jung Bauermann To: linux-integrity@vger.kernel.org Cc: linux-security-module@vger.kernel.org, keyrings@vger.kernel.org, linux-crypto@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Mimi Zohar , Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , David Howells , David Woodhouse , Jessica Yu , Herbert Xu , "David S. Miller" , Jonathan Corbet , "AKASHI, Takahiro" , Thiago Jung Bauermann Subject: [PATCH v10 08/12] ima: Factor xattr_verify() out of ima_appraise_measurement() Date: Thu, 18 Apr 2019 00:51:16 -0300 X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190418035120.2354-1-bauerman@linux.ibm.com> References: <20190418035120.2354-1-bauerman@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 19041803-0020-0000-0000-00000ED91E0F X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00010947; HX=3.00000242; KW=3.00000007; PH=3.00000004; SC=3.00000284; SDB=6.01190666; UDB=6.00623948; IPR=6.00971462; MB=3.00026493; MTD=3.00000008; XFM=3.00000015; UTC=2019-04-18 03:52:31 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19041803-0021-0000-0000-000065794A41 Message-Id: <20190418035120.2354-9-bauerman@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-04-18_03:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904180023 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Verify xattr signature in a separate function so that the logic in ima_appraise_measurement() remains clear when it gains the ability to also verify an appended module signature. The code in the switch statement is unchanged except for having to dereference the status and cause variables (since they're now pointers), and fixing the style of a block comment to appease checkpatch. Suggested-by: Mimi Zohar Signed-off-by: Thiago Jung Bauermann --- security/integrity/ima/ima_appraise.c | 141 +++++++++++++++----------- 1 file changed, 81 insertions(+), 60 deletions(-) diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index ea8fa29f07d3..b3837e26bb27 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -202,6 +202,83 @@ int ima_read_xattr(struct dentry *dentry, return ret; } +/* + * xattr_verify - verify xattr digest or signature + * + * Verify whether the hash or signature matches the file contents. + * + * Return 0 on success, error code otherwise. + */ +static int xattr_verify(enum ima_hooks func, struct integrity_iint_cache *iint, + struct evm_ima_xattr_data *xattr_value, int xattr_len, + enum integrity_status *status, const char **cause) +{ + int rc = -EINVAL, hash_start = 0; + + switch (xattr_value->type) { + case IMA_XATTR_DIGEST_NG: + /* first byte contains algorithm id */ + hash_start = 1; + /* fall through */ + case IMA_XATTR_DIGEST: + if (iint->flags & IMA_DIGSIG_REQUIRED) { + *cause = "IMA-signature-required"; + *status = INTEGRITY_FAIL; + break; + } + clear_bit(IMA_DIGSIG, &iint->atomic_flags); + if (xattr_len - sizeof(xattr_value->type) - hash_start >= + iint->ima_hash->length) + /* + * xattr length may be longer. md5 hash in previous + * version occupied 20 bytes in xattr, instead of 16 + */ + rc = memcmp(&xattr_value->data[hash_start], + iint->ima_hash->digest, + iint->ima_hash->length); + else + rc = -EINVAL; + if (rc) { + *cause = "invalid-hash"; + *status = INTEGRITY_FAIL; + break; + } + *status = INTEGRITY_PASS; + break; + case EVM_IMA_XATTR_DIGSIG: + set_bit(IMA_DIGSIG, &iint->atomic_flags); + rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA, + (const char *)xattr_value, + xattr_len, + iint->ima_hash->digest, + iint->ima_hash->length); + if (rc == -EOPNOTSUPP) { + *status = INTEGRITY_UNKNOWN; + break; + } + if (IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING) && rc && + func == KEXEC_KERNEL_CHECK) + rc = integrity_digsig_verify(INTEGRITY_KEYRING_PLATFORM, + (const char *)xattr_value, + xattr_len, + iint->ima_hash->digest, + iint->ima_hash->length); + if (rc) { + *cause = "invalid-signature"; + *status = INTEGRITY_FAIL; + } else { + *status = INTEGRITY_PASS; + } + break; + default: + *status = INTEGRITY_UNKNOWN; + *cause = "unknown-ima-data"; + break; + } + + return rc; +} + /* * ima_appraise_measurement - appraise file measurement * @@ -221,7 +298,7 @@ int ima_appraise_measurement(enum ima_hooks func, struct dentry *dentry = file_dentry(file); struct inode *inode = d_backing_inode(dentry); enum integrity_status status = INTEGRITY_UNKNOWN; - int rc = xattr_len, hash_start = 0; + int rc = xattr_len; if (!(inode->i_opflags & IOP_XATTR)) return INTEGRITY_UNKNOWN; @@ -259,65 +336,9 @@ int ima_appraise_measurement(enum ima_hooks func, WARN_ONCE(true, "Unexpected integrity status %d\n", status); } - switch (xattr_value->type) { - case IMA_XATTR_DIGEST_NG: - /* first byte contains algorithm id */ - hash_start = 1; - /* fall through */ - case IMA_XATTR_DIGEST: - if (iint->flags & IMA_DIGSIG_REQUIRED) { - cause = "IMA-signature-required"; - status = INTEGRITY_FAIL; - break; - } - clear_bit(IMA_DIGSIG, &iint->atomic_flags); - if (xattr_len - sizeof(xattr_value->type) - hash_start >= - iint->ima_hash->length) - /* xattr length may be longer. md5 hash in previous - version occupied 20 bytes in xattr, instead of 16 - */ - rc = memcmp(&xattr_value->data[hash_start], - iint->ima_hash->digest, - iint->ima_hash->length); - else - rc = -EINVAL; - if (rc) { - cause = "invalid-hash"; - status = INTEGRITY_FAIL; - break; - } - status = INTEGRITY_PASS; - break; - case EVM_IMA_XATTR_DIGSIG: - set_bit(IMA_DIGSIG, &iint->atomic_flags); - rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA, - (const char *)xattr_value, - xattr_len, - iint->ima_hash->digest, - iint->ima_hash->length); - if (rc == -EOPNOTSUPP) { - status = INTEGRITY_UNKNOWN; - break; - } - if (IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING) && rc && - func == KEXEC_KERNEL_CHECK) - rc = integrity_digsig_verify(INTEGRITY_KEYRING_PLATFORM, - (const char *)xattr_value, - xattr_len, - iint->ima_hash->digest, - iint->ima_hash->length); - if (rc) { - cause = "invalid-signature"; - status = INTEGRITY_FAIL; - } else { - status = INTEGRITY_PASS; - } - break; - default: - status = INTEGRITY_UNKNOWN; - cause = "unknown-ima-data"; - break; - } + if (xattr_value) + rc = xattr_verify(func, iint, xattr_value, xattr_len, &status, + &cause); out: /*