All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Biggers <ebiggers@kernel.org>
To: Andreas Dilger <adilger@dilger.ca>
Cc: linux-ext4@vger.kernel.org, linux-fscrypt@vger.kernel.org,
	Theodore Ts'o <tytso@mit.edu>
Subject: Re: [PATCH v4] e2fsck: check for consistent encryption policies
Date: Tue, 17 Sep 2019 18:01:01 -0700	[thread overview]
Message-ID: <20190918010100.GA45382@gmail.com> (raw)
In-Reply-To: <2757ADAC-336F-4EC8-8DBF-2B9C61C196C4@dilger.ca>

On Tue, Sep 10, 2019 at 05:40:51PM -0600, Andreas Dilger wrote:
> > diff --git a/e2fsck/encrypted_files.c b/e2fsck/encrypted_files.c
> > new file mode 100644
> > index 00000000..3dc706a7
> > --- /dev/null
> > +++ b/e2fsck/encrypted_files.c
> > @@ -0,0 +1,368 @@
> > 
> > +/* A range of inodes which share the same encryption policy */
> > +struct encrypted_file_range {
> > +	ext2_ino_t		first_ino;
> > +	ext2_ino_t		last_ino;
> > +	__u32			policy_id;
> > +};
> 
> This seems like a clear win...  As long as we have at least two inodes
> in a row with the same policy ID it will take less space than the previous
> version of the patch.
> 
> > +static int handle_nomem(e2fsck_t ctx, struct problem_context *pctx)
> > +{
> > +	fix_problem(ctx, PR_1_ALLOCATE_ENCRYPTED_DIRLIST, pctx);
> > +	/* Should never get here */
> > +	ctx->flags |= E2F_FLAG_ABORT;
> > +	return 0;
> > +}
> 
> It would be useful if the error message for PR_1_ALLOCATE_ENCRYPTED_DIRLIST
> printed the actual allocation size that failed, so that the user has some
> idea of how much memory would be needed.  The underlying ext2fs_resize_mem()
> code doesn't print anything, just returns EXT2_ET_NO_MEMORY.
> 

Yes, I can make it print the number of bytes using %N.

> > +	if (info->file_ranges_count == info->file_ranges_capacity) {
> > +		/* Double the capacity by default. */
> > +		size_t new_capacity = info->file_ranges_capacity * 2;
> > +
> > +		/* ... but go from 0 to 128 right away. */
> > +		if (new_capacity < 128)
> > +			new_capacity = 128;
> > +
> > +		/* We won't need more than the filesystem's inode count. */
> > +		if (new_capacity > ctx->fs->super->s_inodes_count)
> > +			new_capacity = ctx->fs->super->s_inodes_count;
> > +
> > +		/* To be safe, ensure the capacity really increases. */
> > +		if (new_capacity < info->file_ranges_capacity + 1)
> > +			new_capacity = info->file_ranges_capacity + 1;
> 
> Not sure how this could happen (more inodes than s_inodes_count?), but
> better safe than sorry I guess?
> 

Either that, or an integer overflow.  It shouldn't really happen, but I think we
should have this check to be safe.

> > +		if (ext2fs_resize_mem(info->file_ranges_capacity *
> > +					sizeof(*range),
> > +				      new_capacity * sizeof(*range),
> > +				      &info->file_ranges) != 0)
> > +			return handle_nomem(ctx, pctx);
> 
> This is the only thing that gives me pause, potentially having a huge
> allocation, but I think the RLE encoding of entries and the fact we
> have overwhelmingly 64-bit CPUs means we could still run with swap
> (on an internal NVMe M.2 device) if really needed.  A problem to fix
> if it ever actually rears its head, so long as there is a decent error
> message printed.
> 
> > +/*
> > + * Find the ID of an inode's encryption policy, using the information saved
> > + * earlier.
> > + *
> > + * If the inode is encrypted, returns the policy ID or
> > + * UNRECOGNIZED_ENCRYPTION_POLICY.  Else, returns NO_ENCRYPTION_POLICY.
> > + */
> > +__u32 find_encryption_policy(e2fsck_t ctx, ext2_ino_t ino)
> > +{
> > +	const struct encrypted_file_info *info = ctx->encrypted_files;
> > +	size_t l, r;
> > +
> > +	if (info == NULL)
> > +		return NO_ENCRYPTION_POLICY;
> > +	l = 0;
> > +	r = info->file_ranges_count;
> > +	while (l < r) {
> > +		size_t m = l + (r - l) / 2;
> 
> Using the RLE encoding for the entries should also speed up searching
> here considerably.  In theory, for a single-user Android filesystem
> there might only be one or two entries here.  It would be interesting
> to run this on some of your filesystems to see what the average count
> of inodes per entry is.
> 

On a freshly reset Android device I'm seeing 58 ranges for 4705 encrypted
inodes, so it's not quite *that* good, but it still helps a lot.

Note that there are actually 4 encryption policies on a single-user Android
device: system device-encrypted, user device-encrypted, user
credential-encrypted, and (recently added) per-boot encrypted.

- Eric

      reply	other threads:[~2019-09-18  1:01 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-09 17:43 [PATCH v4] e2fsck: check for consistent encryption policies Eric Biggers
2019-09-10 23:40 ` Andreas Dilger
2019-09-18  1:01   ` Eric Biggers [this message]

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=20190918010100.GA45382@gmail.com \
    --to=ebiggers@kernel.org \
    --cc=adilger@dilger.ca \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-fscrypt@vger.kernel.org \
    --cc=tytso@mit.edu \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.