Received: by 2002:ac0:a591:0:0:0:0:0 with SMTP id m17-v6csp1393758imm; Thu, 5 Jul 2018 22:26:54 -0700 (PDT) X-Google-Smtp-Source: AAOMgpe13D8dTlj7LaVOG8I+Dqyx1QkYVE9UmVajPbjyXuqozcd9iDr8oZCyPIEeO0VZaghKL94M X-Received: by 2002:a63:2d45:: with SMTP id t66-v6mr7975059pgt.381.1530854814493; Thu, 05 Jul 2018 22:26:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530854814; cv=none; d=google.com; s=arc-20160816; b=0Cpo6P0CcmNwVGCZq/98XLS7Ov8CUUDBjldlEP++f3KxmjiD2fugJ8ax8hlve/bZi2 dDEfJx1NfFJlCFDhYIUus3X5PV0HlO0jN22JBNV/d9OlzNhv9tk/CJEp+A9Zfodo875U lxN6tHj5xZB9zelKAxDyUxUdAfyJ8YvWFrDw+RJQsJGjagmjXiIHwEKgyQ5lkFmy+maN bb/0C3G6MJTZDgRQf8BVelwy7ap0SO/25NHe3AZ4shJQ0qwP2q4SmMEh6kQdNsVqCe6g sRNVtTh5WFTiqQyM+dAmGXYXIvh49AA7ujwA4BlITKvEa4lqxWo6kxyqjEQM8INzvMpd hsdQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=Kxl7aJNOt/7ciRXBGmyhwLxRU36RwJC1MZcGSeL56BE=; b=uREnC8piG30NtqYu0ZQaOmafcVSRfr92owo3AtczRPyydB44GTFpNiKZptfcaUSBul xrItmyYxMc087SzHk2aWdAg32rZdm2q6uKPbYEdYR1WJaSA6hT2OAzy9A/qqSFrCtW5H 9Bv3h0hQ2rPgVMAQbXFUCV5161cUQ1cBfL66v12BCsPJPls1hEtZMzCn8dxoDHlY8pcG Um0jwpZjbhJ1A9wpuGfwtgeuM7+GnCnxqPvD2CCMVgTZTsa3UASYdU85526S9x13ThAJ GWqGewZmh8/p3wT4ZBkBZn92S5iei+rXa2SIgqAnntIozq/NOiteshYDWwuHit3vxz7X Ceeg== 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=canonical.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b39-v6si7415812plb.249.2018.07.05.22.26.40; Thu, 05 Jul 2018 22:26:54 -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=canonical.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932498AbeGFFZy (ORCPT + 99 others); Fri, 6 Jul 2018 01:25:54 -0400 Received: from youngberry.canonical.com ([91.189.89.112]:45689 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932197AbeGFFZv (ORCPT ); Fri, 6 Jul 2018 01:25:51 -0400 Received: from 162-237-133-238.lightspeed.rcsntx.sbcglobal.net ([162.237.133.238] helo=sec.l.tihix.com) by youngberry.canonical.com with esmtpsa (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1fbJFd-0001Jc-Vu; Fri, 06 Jul 2018 05:25:50 +0000 From: Tyler Hicks To: John Johansen Cc: James Morris , Serge Hallyn , Seth Arnold , linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] apparmor: Check buffer bounds when mapping permissions mask Date: Fri, 6 Jul 2018 05:25:00 +0000 Message-Id: <1530854701-7348-2-git-send-email-tyhicks@canonical.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1530854701-7348-1-git-send-email-tyhicks@canonical.com> References: <1530854701-7348-1-git-send-email-tyhicks@canonical.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Don't read past the end of the buffer containing permissions characters or write past the end of the destination string. Detected by CoverityScan CID#1415361, 1415376 ("Out-of-bounds access") Fixes: e53cfe6c7caa ("apparmor: rework perm mapping to a slightly broader set") Signed-off-by: Tyler Hicks --- security/apparmor/file.c | 3 ++- security/apparmor/include/perms.h | 3 ++- security/apparmor/lib.c | 17 +++++++++++++---- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/security/apparmor/file.c b/security/apparmor/file.c index 224b2fef93ca..4285943f7260 100644 --- a/security/apparmor/file.c +++ b/security/apparmor/file.c @@ -47,7 +47,8 @@ static void audit_file_mask(struct audit_buffer *ab, u32 mask) { char str[10]; - aa_perm_mask_to_str(str, aa_file_perm_chrs, map_mask_to_chr_mask(mask)); + aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs, + map_mask_to_chr_mask(mask)); audit_log_string(ab, str); } diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h index 38aa6247d00f..b94ec114d1a4 100644 --- a/security/apparmor/include/perms.h +++ b/security/apparmor/include/perms.h @@ -137,7 +137,8 @@ extern struct aa_perms allperms; xcheck(fn_for_each((L1), (P), (FN1)), fn_for_each((L2), (P), (FN2))) -void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask); +void aa_perm_mask_to_str(char *str, size_t str_size, const char *chrs, + u32 mask); void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names, u32 mask); void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c index a7b3f681b80e..7ab368c3789b 100644 --- a/security/apparmor/lib.c +++ b/security/apparmor/lib.c @@ -198,15 +198,24 @@ const char *aa_file_perm_names[] = { /** * aa_perm_mask_to_str - convert a perm mask to its short string * @str: character buffer to store string in (at least 10 characters) + * @str_size: size of the @str buffer + * @chrs: NUL-terminated character buffer of permission characters * @mask: permission mask to convert */ -void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask) +void aa_perm_mask_to_str(char *str, size_t str_size, const char *chrs, u32 mask) { unsigned int i, perm = 1; + size_t num_chrs = strlen(chrs); + + for (i = 0; i < num_chrs; perm <<= 1, i++) { + if (mask & perm) { + /* Ensure that one byte is left for NUL-termination */ + if (WARN_ON_ONCE(str_size <= 1)) + continue; - for (i = 0; i < 32; perm <<= 1, i++) { - if (mask & perm) *str++ = chrs[i]; + str_size--; + } } *str = '\0'; } @@ -236,7 +245,7 @@ void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, audit_log_format(ab, "\""); if ((mask & chrsmask) && chrs) { - aa_perm_mask_to_str(str, chrs, mask & chrsmask); + aa_perm_mask_to_str(str, sizeof(str), chrs, mask & chrsmask); mask &= ~chrsmask; audit_log_format(ab, "%s", str); if (mask & namesmask) -- 2.7.4