From patchwork Tue Apr 4 14:53:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Albershteyn X-Patchwork-Id: 13200417 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 107E2C77B60 for ; Tue, 4 Apr 2023 14:56:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233678AbjDDO4P (ORCPT ); Tue, 4 Apr 2023 10:56:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58326 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232681AbjDDO4G (ORCPT ); Tue, 4 Apr 2023 10:56:06 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1D6321710 for ; Tue, 4 Apr 2023 07:54:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1680620098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=do7mgrJpiSwWS1mlFAfBuj//WIsG4B8mI0gR4ORK1OQ=; b=PV9Bb2sK39g3rx0wkpLAFyntElrQPwETDSVRy3/nVdmbq1i954EJ88AihMkofOWdrKPu3b 7QC2b0ArKmiHnvYe7KutvcRfLGWnbosuofIugQG8N2Qv/N7ORBu5NNL4pmN5vnA3NfmVrb 2pyv1i8kyYyA59HsCOFFBGxxlijp3ks= Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-85-wkic_rJKO5-UryqoYLncew-1; Tue, 04 Apr 2023 10:54:57 -0400 X-MC-Unique: wkic_rJKO5-UryqoYLncew-1 Received: by mail-qt1-f199.google.com with SMTP id r22-20020ac85c96000000b003e638022bc9so10333918qta.5 for ; Tue, 04 Apr 2023 07:54:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680620096; 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=do7mgrJpiSwWS1mlFAfBuj//WIsG4B8mI0gR4ORK1OQ=; b=QPJnXGMqsaGqmAxXD4Hc8U17mGI6CZExDn1PnFxLWIcZtBat8tY/VYIzeLV8BtaY5t uPwwSSbr64PUih0szURt0QTFi4V6ihva+5TU/sVAGPqT4ze7e7nQ6Zsj24vmO64tMaRh w2Ai40nOD4rhAuu8c/hWBBePrtakW6YJHrWq8epZQG5YXJjZPAFZ9bcG4ZieCCGxUmzi ax0H84bcm6WahIY201MpA6+Ve8kZ0q8GQKUX1eVzRLwGQKjoLcK8o0cGBmprC3iQeNFO bT1EYUzN3KE+7hSXQpcXM9CH18n8kJ1uStYGlbVXSHaQN7cLV7FB+QlZD6zzH/LZZwVW cGyQ== X-Gm-Message-State: AAQBX9d+tQJba/S9Ace2ahNjkUJrFzjIpO4tKwuZyFugE/423TXiNT3s DBgintjttFs6zZ4oadJNOpCZAtOFTHEoEDfYi6zIvrTvIxcqGu3p1rSeZdanNKmA4vCXLqO5ZdZ du/dcq0okVHVB/nFYEuxYDA== X-Received: by 2002:ac8:5dca:0:b0:3e6:4843:ce39 with SMTP id e10-20020ac85dca000000b003e64843ce39mr3446043qtx.21.1680620095705; Tue, 04 Apr 2023 07:54:55 -0700 (PDT) X-Google-Smtp-Source: AKy350YrWqDzCGkW5Me9zkv+YJzY1mx+oPLzV295riL8PYBIw4GPxqdHHd+/6CyZuOvEvtkOcPBiVQ== X-Received: by 2002:ac8:5dca:0:b0:3e6:4843:ce39 with SMTP id e10-20020ac85dca000000b003e64843ce39mr3445998qtx.21.1680620095304; Tue, 04 Apr 2023 07:54:55 -0700 (PDT) Received: from aalbersh.remote.csb ([109.183.6.197]) by smtp.gmail.com with ESMTPSA id j4-20020ac86644000000b003e6387431dcsm3296539qtp.7.2023.04.04.07.54.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Apr 2023 07:54:55 -0700 (PDT) From: Andrey Albershteyn To: djwong@kernel.org, dchinner@redhat.com, ebiggers@kernel.org, hch@infradead.org, linux-xfs@vger.kernel.org, fsverity@lists.linux.dev Cc: rpeterso@redhat.com, agruenba@redhat.com, xiang@kernel.org, chao@kernel.org, damien.lemoal@opensource.wdc.com, jth@kernel.org, linux-erofs@lists.ozlabs.org, linux-btrfs@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, cluster-devel@redhat.com, Allison Henderson Subject: [PATCH v2 04/23] xfs: Add xfs_verify_pptr Date: Tue, 4 Apr 2023 16:53:00 +0200 Message-Id: <20230404145319.2057051-5-aalbersh@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20230404145319.2057051-1-aalbersh@redhat.com> References: <20230404145319.2057051-1-aalbersh@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Allison Henderson Attribute names of parent pointers are not strings. So we need to modify attr_namecheck to verify parent pointer records when the XFS_ATTR_PARENT flag is set. Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 47 ++++++++++++++++++++++++++++++++--- fs/xfs/libxfs/xfs_attr.h | 3 ++- fs/xfs/libxfs/xfs_da_format.h | 8 ++++++ fs/xfs/scrub/attr.c | 2 +- fs/xfs/xfs_attr_item.c | 11 +++++--- fs/xfs/xfs_attr_list.c | 17 +++++++++---- 6 files changed, 74 insertions(+), 14 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 101823772bf9..711022742e34 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -1577,9 +1577,33 @@ xfs_attr_node_get( return error; } -/* Returns true if the attribute entry name is valid. */ -bool -xfs_attr_namecheck( +/* + * Verify parent pointer attribute is valid. + * Return true on success or false on failure + */ +STATIC bool +xfs_verify_pptr( + struct xfs_mount *mp, + const struct xfs_parent_name_rec *rec) +{ + xfs_ino_t p_ino; + xfs_dir2_dataptr_t p_diroffset; + + p_ino = be64_to_cpu(rec->p_ino); + p_diroffset = be32_to_cpu(rec->p_diroffset); + + if (!xfs_verify_ino(mp, p_ino)) + return false; + + if (p_diroffset > XFS_DIR2_MAX_DATAPTR) + return false; + + return true; +} + +/* Returns true if the string attribute entry name is valid. */ +static bool +xfs_str_attr_namecheck( const void *name, size_t length) { @@ -1594,6 +1618,23 @@ xfs_attr_namecheck( return !memchr(name, 0, length); } +/* Returns true if the attribute entry name is valid. */ +bool +xfs_attr_namecheck( + struct xfs_mount *mp, + const void *name, + size_t length, + int flags) +{ + if (flags & XFS_ATTR_PARENT) { + if (length != sizeof(struct xfs_parent_name_rec)) + return false; + return xfs_verify_pptr(mp, (struct xfs_parent_name_rec *)name); + } + + return xfs_str_attr_namecheck(name, length); +} + int __init xfs_attr_intent_init_cache(void) { diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h index 3e81f3f48560..b79dae788cfb 100644 --- a/fs/xfs/libxfs/xfs_attr.h +++ b/fs/xfs/libxfs/xfs_attr.h @@ -547,7 +547,8 @@ int xfs_attr_get(struct xfs_da_args *args); int xfs_attr_set(struct xfs_da_args *args); int xfs_attr_set_iter(struct xfs_attr_intent *attr); int xfs_attr_remove_iter(struct xfs_attr_intent *attr); -bool xfs_attr_namecheck(const void *name, size_t length); +bool xfs_attr_namecheck(struct xfs_mount *mp, const void *name, size_t length, + int flags); int xfs_attr_calc_size(struct xfs_da_args *args, int *local); void xfs_init_attr_trans(struct xfs_da_args *args, struct xfs_trans_res *tres, unsigned int *total); diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h index b02b67f1999e..75b13807145d 100644 --- a/fs/xfs/libxfs/xfs_da_format.h +++ b/fs/xfs/libxfs/xfs_da_format.h @@ -731,6 +731,14 @@ xfs_attr3_leaf_name(xfs_attr_leafblock_t *leafp, int idx) return &((char *)leafp)[be16_to_cpu(entries[idx].nameidx)]; } +static inline int +xfs_attr3_leaf_flags(xfs_attr_leafblock_t *leafp, int idx) +{ + struct xfs_attr_leaf_entry *entries = xfs_attr3_leaf_entryp(leafp); + + return entries[idx].flags; +} + static inline xfs_attr_leaf_name_remote_t * xfs_attr3_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx) { diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c index 9d2e33743ecd..2a79a13cb600 100644 --- a/fs/xfs/scrub/attr.c +++ b/fs/xfs/scrub/attr.c @@ -129,7 +129,7 @@ xchk_xattr_listent( } /* Does this name make sense? */ - if (!xfs_attr_namecheck(name, namelen)) { + if (!xfs_attr_namecheck(sx->sc->mp, name, namelen, flags)) { xchk_fblock_set_corrupt(sx->sc, XFS_ATTR_FORK, args.blkno); return; } diff --git a/fs/xfs/xfs_attr_item.c b/fs/xfs/xfs_attr_item.c index 95e9ecbb4a67..da807f286a09 100644 --- a/fs/xfs/xfs_attr_item.c +++ b/fs/xfs/xfs_attr_item.c @@ -593,7 +593,8 @@ xfs_attri_item_recover( */ attrp = &attrip->attri_format; if (!xfs_attri_validate(mp, attrp) || - !xfs_attr_namecheck(nv->name.i_addr, nv->name.i_len)) + !xfs_attr_namecheck(mp, nv->name.i_addr, nv->name.i_len, + attrp->alfi_attr_filter)) return -EFSCORRUPTED; error = xlog_recover_iget(mp, attrp->alfi_ino, &ip); @@ -804,7 +805,8 @@ xlog_recover_attri_commit_pass2( } attr_name = item->ri_buf[i].i_addr; - if (!xfs_attr_namecheck(attr_name, attri_formatp->alfi_name_len)) { + if (!xfs_attr_namecheck(mp, attr_name, attri_formatp->alfi_name_len, + attri_formatp->alfi_attr_filter)) { XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, item->ri_buf[i].i_addr, item->ri_buf[i].i_len); return -EFSCORRUPTED; @@ -822,8 +824,9 @@ xlog_recover_attri_commit_pass2( } attr_nname = item->ri_buf[i].i_addr; - if (!xfs_attr_namecheck(attr_nname, - attri_formatp->alfi_nname_len)) { + if (!xfs_attr_namecheck(mp, attr_nname, + attri_formatp->alfi_nname_len, + attri_formatp->alfi_attr_filter)) { XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, item->ri_buf[i].i_addr, item->ri_buf[i].i_len); diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index 99bbbe1a0e44..a51f7f13a352 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c @@ -58,9 +58,13 @@ xfs_attr_shortform_list( struct xfs_attr_sf_sort *sbuf, *sbp; struct xfs_attr_shortform *sf; struct xfs_attr_sf_entry *sfe; + struct xfs_mount *mp; int sbsize, nsbuf, count, i; int error = 0; + ASSERT(context != NULL); + ASSERT(dp != NULL); + mp = dp->i_mount; sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data; ASSERT(sf != NULL); if (!sf->hdr.count) @@ -82,8 +86,9 @@ xfs_attr_shortform_list( (dp->i_af.if_bytes + sf->hdr.count * 16) < context->bufsize)) { for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { if (XFS_IS_CORRUPT(context->dp->i_mount, - !xfs_attr_namecheck(sfe->nameval, - sfe->namelen))) + !xfs_attr_namecheck(mp, sfe->nameval, + sfe->namelen, + sfe->flags))) return -EFSCORRUPTED; context->put_listent(context, sfe->flags, @@ -174,8 +179,9 @@ xfs_attr_shortform_list( cursor->offset = 0; } if (XFS_IS_CORRUPT(context->dp->i_mount, - !xfs_attr_namecheck(sbp->name, - sbp->namelen))) { + !xfs_attr_namecheck(mp, sbp->name, + sbp->namelen, + sbp->flags))) { error = -EFSCORRUPTED; goto out; } @@ -465,7 +471,8 @@ xfs_attr3_leaf_list_int( } if (XFS_IS_CORRUPT(context->dp->i_mount, - !xfs_attr_namecheck(name, namelen))) + !xfs_attr_namecheck(mp, name, namelen, + entry->flags))) return -EFSCORRUPTED; context->put_listent(context, entry->flags, name, namelen, valuelen);