From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.0 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94AB1C48BEA for ; Mon, 24 Jun 2019 10:10:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 69D5A20645 for ; Mon, 24 Jun 2019 10:10:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1561371031; bh=Me5ZH5WNgfvvOavz611o8SnLtBSXHw0NStY2yeoBmU8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=eHMVL1/+EMIyfw12CP4KlqCygkfp1hjRws4eTkxk0ZBXV/jjpn/RPIxrdoB0f2yj9 U3W7Ye1xmQxSyo1EQnnp3KuUlAkXuaiqjEXkmfCi3MA7FWauOGGL3TlXTSiMR62WHF 5kvaFAU/KWZtLpZGM0CUG+0Vaj+40oS/m/bmJrko= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730375AbfFXKHy (ORCPT ); Mon, 24 Jun 2019 06:07:54 -0400 Received: from mail.kernel.org ([198.145.29.99]:40274 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730340AbfFXKHk (ORCPT ); Mon, 24 Jun 2019 06:07:40 -0400 Received: from localhost (f4.8f.5177.ip4.static.sl-reverse.com [119.81.143.244]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 43DD72089F; Mon, 24 Jun 2019 10:07:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1561370859; bh=Me5ZH5WNgfvvOavz611o8SnLtBSXHw0NStY2yeoBmU8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZzN93yS64FG0ePJ0QdYrQKbYzJdegKFQudzfcXvc36mqiaAVSz2f26+cN13Y1Efva qBFCvoZj0OmuTVXskpG7ABcGq9f/P0q0vVVQgEuldVGOJGP2sK7gxnzgZqoHsoi9i2 wVlkG8pxvncbpeMQOGPhFrU/O+eDsjCG/OC+jIF0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Mike Salvatore , John Johansen Subject: [PATCH 5.1 027/121] apparmor: reset pos on failure to unpack for various functions Date: Mon, 24 Jun 2019 17:55:59 +0800 Message-Id: <20190624092322.128018773@linuxfoundation.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190624092320.652599624@linuxfoundation.org> References: <20190624092320.652599624@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Mike Salvatore commit 156e42996bd84eccb6acf319f19ce0cb140d00e3 upstream. Each function that manipulates the aa_ext struct should reset it's "pos" member on failure. This ensures that, on failure, no changes are made to the state of the aa_ext struct. There are paths were elements are optional and the error path is used to indicate the optional element is not present. This means instead of just aborting on error the unpack stream can become unsynchronized on optional elements, if using one of the affected functions. Cc: stable@vger.kernel.org Fixes: 736ec752d95e ("AppArmor: policy routines for loading and unpacking policy") Signed-off-by: Mike Salvatore Signed-off-by: John Johansen Signed-off-by: Greg Kroah-Hartman --- security/apparmor/policy_unpack.c | 47 +++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 8 deletions(-) --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -223,16 +223,21 @@ static void *kvmemdup(const void *src, s static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk) { size_t size = 0; + void *pos = e->pos; if (!inbounds(e, sizeof(u16))) - return 0; + goto fail; size = le16_to_cpu(get_unaligned((__le16 *) e->pos)); e->pos += sizeof(__le16); if (!inbounds(e, size)) - return 0; + goto fail; *chunk = e->pos; e->pos += size; return size; + +fail: + e->pos = pos; + return 0; } /* unpack control byte */ @@ -294,62 +299,84 @@ fail: static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name) { + void *pos = e->pos; + if (unpack_nameX(e, AA_U8, name)) { if (!inbounds(e, sizeof(u8))) - return 0; + goto fail; if (data) *data = get_unaligned((u8 *)e->pos); e->pos += sizeof(u8); return 1; } + +fail: + e->pos = pos; return 0; } static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) { + void *pos = e->pos; + if (unpack_nameX(e, AA_U32, name)) { if (!inbounds(e, sizeof(u32))) - return 0; + goto fail; if (data) *data = le32_to_cpu(get_unaligned((__le32 *) e->pos)); e->pos += sizeof(u32); return 1; } + +fail: + e->pos = pos; return 0; } static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name) { + void *pos = e->pos; + if (unpack_nameX(e, AA_U64, name)) { if (!inbounds(e, sizeof(u64))) - return 0; + goto fail; if (data) *data = le64_to_cpu(get_unaligned((__le64 *) e->pos)); e->pos += sizeof(u64); return 1; } + +fail: + e->pos = pos; return 0; } static size_t unpack_array(struct aa_ext *e, const char *name) { + void *pos = e->pos; + if (unpack_nameX(e, AA_ARRAY, name)) { int size; if (!inbounds(e, sizeof(u16))) - return 0; + goto fail; size = (int)le16_to_cpu(get_unaligned((__le16 *) e->pos)); e->pos += sizeof(u16); return size; } + +fail: + e->pos = pos; return 0; } static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name) { + void *pos = e->pos; + if (unpack_nameX(e, AA_BLOB, name)) { u32 size; if (!inbounds(e, sizeof(u32))) - return 0; + goto fail; size = le32_to_cpu(get_unaligned((__le32 *) e->pos)); e->pos += sizeof(u32); if (inbounds(e, (size_t) size)) { @@ -358,6 +385,9 @@ static size_t unpack_blob(struct aa_ext return size; } } + +fail: + e->pos = pos; return 0; } @@ -374,9 +404,10 @@ static int unpack_str(struct aa_ext *e, if (src_str[size - 1] != 0) goto fail; *string = src_str; + + return size; } } - return size; fail: e->pos = pos;