linux-xfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com>
To: "Darrick J. Wong" <djwong@kernel.org>
Cc: Allison Henderson <allison.henderson@oracle.com>,
	"linux-xfs@vger.kernel.org" <linux-xfs@vger.kernel.org>
Subject: Re: [PATCHSET v10r1d2 00/17] xfs: encode parent pointer name in xattr key
Date: Tue, 28 Mar 2023 10:21:10 +0300	[thread overview]
Message-ID: <CAOQ4uxg=Gy-s58KkpGmj9sZR1n2qVWxy73_iLcsWLV6+_i8uqw@mail.gmail.com> (raw)
In-Reply-To: <20230328012932.GE16180@frogsfrogsfrogs>

On Tue, Mar 28, 2023 at 4:29 AM Darrick J. Wong <djwong@kernel.org> wrote:
>
> On Sun, Mar 26, 2023 at 06:21:17AM +0300, Amir Goldstein wrote:
> > On Sat, Mar 25, 2023 at 8:01 PM Darrick J. Wong <djwong@kernel.org> wrote:
> > >
> > > On Sat, Mar 25, 2023 at 10:59:16AM +0300, Amir Goldstein wrote:
> > > > On Fri, Mar 24, 2023 at 8:19 PM Allison Henderson
> > > > <allison.henderson@oracle.com> wrote:
> > > > >
> > > > > On Thu, 2023-03-16 at 12:17 -0700, Darrick J. Wong wrote:
> > > > > > Hi all,
> > > > > >
> > > > > > As I've mentioned in past comments on the parent pointers patchset,
> > > > > > the
> > > > > > proposed ondisk parent pointer format presents a major difficulty for
> > > > > > online directory repair.  This difficulty derives from encoding the
> > > > > > directory offset of the dirent that the parent pointer is mirroring.
> > > > > > Recall that parent pointers are stored in extended attributes:
> > > > > >
> > > > > >     (parent_ino, parent_gen, diroffset) -> (dirent_name)
> > > > > >
> > > > > > If the directory is rebuilt, the offsets of the new directory entries
> > > > > > must match the diroffset encoded in the parent pointer, or the
> > > > > > filesystem becomes inconsistent.  There are a few ways to solve this
> > > > > > problem.
> > > > > >
> > > > > > One approach would be to augment the directory addname function to
> > > > > > take
> > > > > > a diroffset and try to create the new entry at that offset.  This
> > > > > > will
> > > > > > not work if the original directory became corrupt and the parent
> > > > > > pointers were written out with impossible diroffsets (e.g.
> > > > > > overlapping).
> > > > > > Requiring matching diroffsets also prevents reorganization and
> > > > > > compaction of directories.
> > > > > >
> > > > > > This could be remedied by recording the parent pointer diroffset
> > > > > > updates
> > > > > > necessary to retain consistency, and using the logged parent pointer
> > > > > > replace function to rewrite parent pointers as necessary.  This is a
> > > > > > poor choice from a performance perspective because the logged xattr
> > > > > > updates must be committed in the same transaction that commits the
> > > > > > new
> > > > > > directory structure.  If there are a large number of diroffset
> > > > > > updates,
> > > > > > then the directory commit could take an even longer time.
> > > > > >
> > > > > > Worse yet, if the logged xattr updates fill up the transaction,
> > > > > > repair
> > > > > > will have no choice but to roll to a fresh transaction to continue
> > > > > > logging.  This breaks repair's policy that repairs should commit
> > > > > > atomically.  It may break the filesystem as well, since all files
> > > > > > involved are pinned until the delayed pptr xattr processing
> > > > > > completes.
> > > > > > This is a completely bad engineering choice.
> > > > > >
> > > > > > Note that the diroffset information is not used anywhere in the
> > > > > > directory lookup code.  Observe that the only information that we
> > > > > > require for a parent pointer is the inverse of an pre-ftype dirent,
> > > > > > since this is all we need to reconstruct a directory entry:
> > > > > >
> > > > > >     (parent_ino, dirent_name) -> NULL
> > > > > >
> > > > > > The xattr code supports xattrs with zero-length values, surprisingly.
> > > > > > The parent_gen field makes it easy to export parent handle
> > > > > > information,
> > > > > > so it can be retained:
> > > > > >
> > > > > >     (parent_ino, parent_gen, dirent_name) -> NULL
> > > > > >
> > > > > > Moving the ondisk format to this format is very advantageous for
> > > > > > repair
> > > > > > code.  Unfortunately, there is one hitch: xattr names cannot exceed
> > > > > > 255
> > > > > > bytes due to ondisk format limitations.  We don't want to constrain
> > > > > > the
> > > > > > length of dirent names, so instead we create a special VLOOKUP mode
> > > > > > for
> > > > > > extended attributes that allows parent pointers to require matching
> > > > > > on
> > > > > > both the name and the value.
> > > > > >
> > > > > > The ondisk format of a parent pointer can then become:
> > > > > >
> > > > > >     (parent_ino, parent_gen, dirent_name[0:242]) ->
> > > > > > (dirent_name[243:255])
> > > >
> > > > With VLOOKUP in place, why is this better than
> > > > (parent_ino, parent_gen) -> (dirent_name)
> > > >
> > > > Is it because the dabtree hash is calculated only on the key
> > > > and changing that would be way more intrusive?
> > >
> > > Yes.  The dabtree hash is calculated on the full attr name, so this is
> > > an attempt to reduce hash collisions during parent pointer lookups by
> > > stuffing as many bytes in the attr name as possible.
> > >
> > > It would be very easy to change the xfs_da_hashname calls inside
> > > xfs_parent.c to use either the full dirent name (i.e. pptr hash matches
> > > dirent hash) or use the full parent pointer and not just the attr key,
> > > but that would be a major break from the tradition that the da hash is
> > > computed against the attr name only.
> > >
> > > (I'm not opposed to doing that too, but one breaking change at a time.
> > > ;))
> > >
> > > > Does that mean that user can create up to 2^12
> > > > parent pointers with the same hash and we are fine with it?
> > >
> > > Yes.  The dabtree can handle an xattr structure where every name hashes
> > > to the same value, though performance will be slow as it scans every
> > > attr to find the one it wants.
> > >
> > > The number of parent pointers with the same hash can be much higher
> > > than 2^12 -- I wrote a dumb C program that creates an arbitrary number
> > > of attr names with identical hashes.  It's not fast when you get past
> > > 100,000. :P
> > >
> >
> > Right.
> > So how about
> > (parent_ino, parent_gen, dirent_hash) -> (dirent_name)
> >
> > This is not a breaking change and you won't need to do another
> > breaking change later.
> >
> > This could also be internal to VLOOKUP: appended vhash to
> > attr name and limit VLOOKUP name size to  255 - vhashsize.
>
> The original "put the hash in the xattr name" patches did that, but I
> discarded that approach because it increases the size of each parent
> pointer by 4 bytes, and was really easy to make a verrrry slow
> filesystem:
>
> I wrote an xfs_io command to compute lists of names with the same
> dirhash value.  If I created a giant directory with the same file
> hardlinked millions of times where all those dirent names all hash to
> the same value, lookups in the directory gets really slow because the
> dabtree code has to walk (on average) half a million dirents to find the
> matching one.
>
> There were also millions of parent pointer xattrs, all with the same
> attr name and hence the same hash value here too.  Doing that made the
> performance totally awful.  Changing the hash to crc32c and then sha512
> made it much harder to induce collision slowdowns on both ends like
> that, though sha512 added a noticeable performance hit for what it was
> preventing.
>

OK, but this attack is applicable to the dabtree hash itself only with
the proposed dirent_name[0:242] key, is it not?

> Hopefully the fact that the attr name starts with 12 bytes (4 of which
> aren't known to unprivileged userspace) and omits the last 12 bytes of
> the dirent name will make it harder to generate double-collisions.
> Granted there's probably someone who's more math-smart than me who can
> figure this out.

My concern is that generating 7^12 collisions using all the possible
printable suffix dirent_name[243:255] is so simple that even a non-malicious
but rather unlucky script would end up hitting those collisions:
Report_$ORGANIZATION_$DEPARTEMT_$PRODUCT_$PROJECT_...
$GROUP_$OWNER_$DATE_$TIME_$ID.pdf
You get what I mean...

So my thinking was that the unlucky should not suffer the same penalty
as the malicious.

Thanks,
Amir.

  reply	other threads:[~2023-03-28  7:21 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-16 18:54 [RFC DELUGE v10r1d2] xfs: Parent Pointers Darrick J. Wong
2023-03-16 19:17 ` [PATCHSET v10r1d2 0/7] xfs: bug fixes for parent pointers Darrick J. Wong
2023-03-16 19:19   ` [PATCH 1/7] xfs: validate parent pointer xattrs in getparent Darrick J. Wong
2023-03-16 19:20   ` [PATCH 2/7] xfs: rename xfs_pptr_info to xfs_getparents Darrick J. Wong
2023-03-16 19:20   ` [PATCH 3/7] xfs: rename xfs_parent_ptr Darrick J. Wong
2023-03-16 19:20   ` [PATCH 4/7] xfs: fix GETPARENTS ioctl Darrick J. Wong
2023-03-16 19:20   ` [PATCH 5/7] xfs: add tracing to the " Darrick J. Wong
2023-03-16 19:21   ` [PATCH 6/7] xfs: shorten parent pointer function names Darrick J. Wong
2023-03-16 19:21   ` [PATCH 7/7] xfs: rearrange bits of the parent pointer apis for fsck Darrick J. Wong
2023-03-16 19:17 ` [PATCHSET v10r1d2 00/17] xfs: encode parent pointer name in xattr key Darrick J. Wong
2023-03-16 19:21   ` [PATCH 01/17] xfs: document the ri_total validation in xlog_recover_attri_commit_pass2 Darrick J. Wong
2023-03-16 19:22   ` [PATCH 02/17] xfs: make xfs_attr_set require XFS_DA_OP_REMOVE Darrick J. Wong
2023-03-16 19:22   ` [PATCH 03/17] xfs: allow xattr matching on value for local/sf attrs Darrick J. Wong
2023-03-16 19:22   ` [PATCH 04/17] xfs: preserve VLOOKUP in xfs_attr_set Darrick J. Wong
2023-03-16 19:22   ` [PATCH 05/17] xfs: restructure xfs_attr_complete_op a bit Darrick J. Wong
2023-03-16 19:23   ` [PATCH 06/17] xfs: use helpers to extract xattr op from opflags Darrick J. Wong
2023-03-16 19:23   ` [PATCH 07/17] xfs: validate recovered name buffers when recovering xattr items Darrick J. Wong
2023-03-16 19:23   ` [PATCH 08/17] xfs: always set args->value in xfs_attri_item_recover Darrick J. Wong
2023-03-16 19:23   ` [PATCH 09/17] xfs: flip nvreplace detection in xfs_attr_complete_op Darrick J. Wong
2023-03-16 19:24   ` [PATCH 10/17] xfs: log VLOOKUP xattr removal operations Darrick J. Wong
2023-03-16 19:24   ` [PATCH 11/17] xfs: log VLOOKUP xattr setting operations Darrick J. Wong
2023-03-16 19:24   ` [PATCH 12/17] xfs: overlay alfi_nname_len atop alfi_name_len for NVREPLACE Darrick J. Wong
2023-03-16 19:24   ` [PATCH 13/17] xfs: refactor value length in xlog_recover_attri_commit_pass2 Darrick J. Wong
2023-03-16 19:25   ` [PATCH 14/17] xfs: rename nname to newname Darrick J. Wong
2023-03-16 19:25   ` [PATCH 15/17] xfs: log VLOOKUP xattr nvreplace operations Darrick J. Wong
2023-03-16 19:25   ` [PATCH 16/17] xfs: log new xattr values for NVREPLACEXXX operations Darrick J. Wong
2023-03-16 19:25   ` [PATCH 17/17] xfs: replace parent pointer diroffset with full dirent name Darrick J. Wong
2023-03-24 17:10   ` [PATCHSET v10r1d2 00/17] xfs: encode parent pointer name in xattr key Allison Henderson
2023-03-25  7:59     ` Amir Goldstein
2023-03-25 17:01       ` Darrick J. Wong
2023-03-26  3:21         ` Amir Goldstein
2023-03-28  1:29           ` Darrick J. Wong
2023-03-28  7:21             ` Amir Goldstein [this message]
2023-03-28 22:29             ` Dave Chinner
2023-03-28 23:54               ` Darrick J. Wong
2023-03-29  0:19                 ` Dave Chinner
2023-03-29  0:46                   ` Darrick J. Wong
2023-03-30  1:56                     ` Darrick J. Wong
2023-03-25 17:03     ` Darrick J. Wong
2023-03-16 19:17 ` [PATCHSET v10r1d2 0/9] xfsprogs: tool fixes for parent pointers Darrick J. Wong
2023-03-16 19:26   ` [PATCH 1/9] libxfs: initialize the slab cache for parent defer items Darrick J. Wong
2023-03-16 19:26   ` [PATCH 2/9] mkfs: fix libxfs api misuse Darrick J. Wong
2023-03-16 19:26   ` [PATCH 3/9] libxfs: create new files with attr forks if necessary Darrick J. Wong
2023-03-16 19:26   ` [PATCH 4/9] mkfs: fix subdir parent pointer creation Darrick J. Wong
2023-03-16 19:27   ` [PATCH 5/9] xfs_db: report parent pointer keys Darrick J. Wong
2023-03-16 19:27   ` [PATCH 6/9] xfs_db: obfuscate dirent and pptr names consistently Darrick J. Wong
2023-03-16 19:27   ` [PATCH 7/9] xfs_io: print path in path_print Darrick J. Wong
2023-03-16 19:27   ` [PATCH 8/9] xfs_io: parent command is not experts-only Darrick J. Wong
2023-03-16 19:28   ` [PATCH 9/9] xfs_repair: fix incorrect dabtree hashval comparison Darrick J. Wong
2023-03-16 19:18 ` [PATCHSET v10r1d2 0/2] xfsprogs: actually use getparent ioctl Darrick J. Wong
2023-03-16 19:28   ` [PATCH 1/2] xfs_scrub: revert unnecessary code from "implement the upper half of parent pointers" Darrick J. Wong
2023-03-16 19:28   ` [PATCH 2/2] xfs_scrub: use parent pointers when possible to report file operations Darrick J. Wong
2023-03-16 19:18 ` [PATCHSET v10r1d2 0/7] libfrog: fix parent pointer library code Darrick J. Wong
2023-03-16 19:29   ` [PATCH 1/7] xfs_io: move parent pointer filtering and formatting flags out of libhandle Darrick J. Wong
2023-03-16 19:29   ` [PATCH 2/7] libfrog: remove all the parent pointer code from libhandle Darrick J. Wong
2023-03-16 19:29   ` [PATCH 3/7] libfrog: fix indenting errors in xfss_pptr_alloc Darrick J. Wong
2023-03-16 19:29   ` [PATCH 4/7] libfrog: return positive errno in pptrs.c Darrick J. Wong
2023-03-16 19:30   ` [PATCH 5/7] libfrog: only walk one parent pointer at a time in handle_walk_parent_path_ptr Darrick J. Wong
2023-03-16 19:30   ` [PATCH 6/7] libfrog: trim trailing slashes when printing pptr paths Darrick J. Wong
2023-03-16 19:30   ` [PATCH 7/7] libfrog: fix a buffer overrun in path_list_to_string Darrick J. Wong
2023-03-16 19:18 ` [PATCHSET v10r1d2 0/5] xfsprogs: bug fixes for parent pointers Darrick J. Wong
2023-03-16 19:30   ` [PATCH 1/5] xfs: rename xfs_pptr_info to xfs_getparents Darrick J. Wong
2023-03-16 19:31   ` [PATCH 2/5] xfs: rename xfs_parent_ptr Darrick J. Wong
2023-03-16 19:31   ` [PATCH 3/5] xfs: fix GETPARENTS ioctl Darrick J. Wong
2023-03-16 19:31   ` [PATCH 4/5] xfs: shorten parent pointer function names Darrick J. Wong
2023-03-16 19:31   ` [PATCH 5/5] xfs: rearrange bits of the parent pointer apis for fsck Darrick J. Wong
2023-03-16 19:18 ` [PATCHSET v10r1d2 0/4] xfs_logprint: clean up attri/pptr dumping Darrick J. Wong
2023-03-16 19:32   ` [PATCH 1/4] xfs: revert "xfsprogs: Print pptrs in ATTRI items" Darrick J. Wong
2023-03-16 19:32   ` [PATCH 2/4] xfs_logprint: print missing attri header fields Darrick J. Wong
2023-03-16 19:32   ` [PATCH 3/4] xfs: make logprint note attr names and newnames consistently Darrick J. Wong
2023-03-16 19:32   ` [PATCH 4/4] xfs_logprint: decode parent pointers fully Darrick J. Wong
2023-03-16 19:19 ` [PATCHSET v10r1d2 00/14] fstests: adjust tests for xfs parent pointers Darrick J. Wong
2023-03-16 19:33   ` [PATCH 01/14] xfs/122: update for " Darrick J. Wong
2023-03-16 19:33   ` [PATCH 02/14] populate: create hardlinks " Darrick J. Wong
2023-03-16 19:33   ` [PATCH 03/14] xfs/021: adapt golden output files " Darrick J. Wong
2023-03-16 19:33   ` [PATCH 04/14] generic/050: adapt " Darrick J. Wong
2023-03-16 19:34   ` [PATCH 05/14] xfs/018: disable parent pointers for this test Darrick J. Wong
2023-03-16 19:34   ` [PATCH 06/14] xfs/306: fix formatting failures with parent pointers Darrick J. Wong
2023-03-16 19:34   ` [PATCH 07/14] common: add helpers for parent pointer tests Darrick J. Wong
2023-03-16 19:35   ` [PATCH 08/14] xfs: add parent pointer test Darrick J. Wong
2023-03-16 19:35   ` [PATCH 09/14] xfs: add multi link " Darrick J. Wong
2023-03-16 19:35   ` [PATCH 10/14] xfs: add parent pointer inject test Darrick J. Wong
2023-03-16 19:35   ` [PATCH 11/14] common/parent: add license and copyright Darrick J. Wong
2023-03-16 19:36   ` [PATCH 12/14] common/parent: don't _fail on missing parent pointer components Darrick J. Wong
2023-03-16 19:36   ` [PATCH 13/14] common/parent: check xfs_io parent command paths Darrick J. Wong
2023-03-16 19:36   ` [PATCH 14/14] xfs/851: test xfs_io parent -p too Darrick J. Wong
2023-03-16 19:19 ` [PATCHSET v10r1d2 0/1] xfs: bug fixes for parent pointers Darrick J. Wong
2023-03-16 19:36   ` [PATCH 1/1] xfs/122: fix parent pointer ioctl structure sizes Darrick J. Wong
2023-03-16 19:19 ` [PATCHSET v10r1d2 0/1] fstests: encode parent pointer name in xattr key Darrick J. Wong
2023-03-16 19:37   ` [PATCH 1/1] xfs/{021,122}: adjust parent pointer encoding format Darrick J. Wong
2023-03-17 19:06 ` [RFC DELUGE v10r1d2] xfs: Parent Pointers Allison Henderson
2023-03-17 23:45   ` Darrick J. Wong
2023-03-21 21:14     ` Allison Henderson
2023-03-25 17:02       ` Darrick J. Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAOQ4uxg=Gy-s58KkpGmj9sZR1n2qVWxy73_iLcsWLV6+_i8uqw@mail.gmail.com' \
    --to=amir73il@gmail.com \
    --cc=allison.henderson@oracle.com \
    --cc=djwong@kernel.org \
    --cc=linux-xfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).