Re: [PATCH v7 12/17] luks2: Better error handling when setting up the cryptodisk

2020-12-07 Thread Patrick Steinhardt
On Mon, Dec 07, 2020 at 10:04:01PM -0600, Glenn Washburn wrote:
> On Sun, 6 Dec 2020 20:35:13 +0100
> Patrick Steinhardt  wrote:
> 
> > On Fri, Dec 04, 2020 at 10:43:41AM -0600, Glenn Washburn wrote:
> > > First, check to make sure that source disk has a known size. If
> > > not, print debug message and return error. There are 4 cases where
> > > GRUB_DISK_SIZE_UNKNOWN is set (biosdisk, obdisk, ofdisk, and
> > > uboot), and in all those cases processing continues. So this is
> > > probably a bit conservative. However, 3 of the cases seem
> > > pathological, and the other, biosdisk, happens when booting from a
> > > cd. Since I doubt booting from a LUKS2 volume on a cd is a big use
> > > case, we'll error until someone complains.
> > > 
> > > Do some sanity checking on data coming from the luks header. If
> > > segment.size is "dynamic",
> > 
> > Nit: there's something missing here.
> 
> Yep, thanks for catching that. I was going to complete this and forgot
> in my rush to get the series out before some travel.  I'll rework that.
> 
> > > Check for errors from grub_strtoull when converting segment size
> > > from string. If a GRUB_ERR_BAD_NUMBER error was returned, then the
> > > string was not a valid parsable number, so skip the key. If
> > > GRUB_ERR_OUT_OF_RANGE was returned, then there was an overflow in
> > > converting to a 64-bit unsigned integer. So this could be a very
> > > large disk (perhaps large raid array). In this case, we want to
> > > continue to try to use this key so long as the source disk's size
> > > is greater than this segment size. Otherwise, this is an invalid
> > > segment, and continue on to the next key.
> > > 
> > > Signed-off-by: Glenn Washburn 
> > > ---
> > >  grub-core/disk/luks2.c | 98
> > > +- include/grub/disk.h|
> > > 17  2 files changed, 105 insertions(+), 10 deletions(-)
> > > 
> > > diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
> > > index de2e70796..1bb3a333d 100644
> > > --- a/grub-core/disk/luks2.c
> > > +++ b/grub-core/disk/luks2.c
> > > @@ -290,7 +290,7 @@ luks2_get_keyslot (grub_luks2_keyslot_t *k,
> > > grub_luks2_digest_t *d, grub_luks2_s break;
> > >  }
> > >if (i == size)
> > > -  return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No digest for
> > > keyslot \"%"PRIuGRUB_UINT64_T"\"", k->slot_key);
> > > +  return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No digest for
> > > keyslot \"%"PRIuGRUB_UINT64_T"\"", k->json_slot_key); 
> > >/* Get segment that matches the digest. */
> > >if (grub_json_getvalue (, root, "segments") ||
> > > @@ -308,7 +308,7 @@ luks2_get_keyslot (grub_luks2_keyslot_t *k,
> > > grub_luks2_digest_t *d, grub_luks2_s break;
> > >  }
> > >if (i == size)
> > > -return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No segment for
> > > digest \"%"PRIuGRUB_UINT64_T"\"", d->slot_key);
> > > +return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No segment for
> > > digest \"%"PRIuGRUB_UINT64_T"\"", d->json_slot_key); 
> > >return GRUB_ERR_NONE;
> > >  }
> > > @@ -600,37 +600,115 @@ luks2_recover_key (grub_disk_t source,
> > >goto err;
> > >  }
> > >  
> > > +  if (source->total_sectors == GRUB_DISK_SIZE_UNKNOWN)
> > > +{
> > > +  /* FIXME: Allow use of source disk, and maybe cause errors
> > > in read. */
> > > +  grub_dprintf ("luks2", "Source disk %s has an unknown size, "
> > > +  "conservatively returning error\n",
> > > source->name);
> > > +  ret = grub_error (GRUB_ERR_BUG, "Unknown size of luks2
> > > source device");
> > > +  goto err;
> > > +}
> > > +
> > >/* Try all keyslot */
> > >for (i = 0; i < size; i++)
> > >  {
> > > +  typeof(source->total_sectors) max_crypt_sectors = 0;
> > 
> > Please bear with me if this has been discussed in a previous round,
> > but why exactly do we cast `max_crypt_sectors` to the type of
> > `source->total_sectors`?
> 
> Technically, this isn't a cast.  Its a variable declaration.  But I'm
> using the typeof(source->total_sectors) because max_crypt_sectors can
> be no more or less than the total sectors, ie its of the same type.

Oh, of course. I somehow didn't realize this at all, probably because
this is not something one sees that often.

> > And isn't the variable always set anyway in
> > case the keyslot has a non-zero priority?
> 
> Yep. Are you suggesting that it need not be initialized?  This is true,
> but I don't think that's a problem.  I think generally initializing
> things is a good practice.  It might be problematic if this was in an
> oft used function (or it might not, would need to see if the compiler
> was smart enough to ignore the initialization).  But that
> initialization is going to happen very rarely in the lifetime of a grub
> execution instance.  I also don't really care either way.
> 
> Glenn

I just didn't realize it's a declaration, so keeping the initialization
is fine.

Patrick


signature.asc
Description: PGP 

Re: [PATCH v7 05/17] luks2: Add json_slot_key member to struct grub_luks2_keyslot/segment/digest

2020-12-07 Thread Patrick Steinhardt
On Mon, Dec 07, 2020 at 10:06:44PM -0600, Glenn Washburn wrote:
> On Mon, 7 Dec 2020 21:02:39 +0100
> Daniel Kiper  wrote:
> 
> > On Sun, Dec 06, 2020 at 02:29:06PM +0100, Patrick Steinhardt wrote:
> > > On Fri, Dec 04, 2020 at 10:43:34AM -0600, Glenn Washburn wrote:
> > > > This allows code using these structs to know the named key
> > > > associated with these json data structures. In the future we can
> > > > use these to provide better error messages to the user.
> > > >
> > > > Get rid of idx variable in luks2_get_keyslot() which was
> > > > overloaded to be used for both keyslot and segment slot keys.
> > > >
> > > > Signed-off-by: Glenn Washburn 
> > >
> > > Personally, I'd have named them `json_slot_idx`. But you've already
> > > done so much work on improving the code that I don't want this to
> > > be the reason to not give an SOB, especially considering that it's
> > > a strict improvement anyway. So:
> > >
> > > Signed-off-by: Patrick Steinhardt 
> > 
> > I can change this to json_slot_idx before committing if Glenn does not
> > object. Otherwise Reviewed-by: Daniel Kiper 
> 
> Thanks Patrick for the sentiment.  Looking at the luks2 spec, it says:
> 
> "JSON  objects  must  have  their names  formatted  as  a  string  that
> represents  a  number  in  the  decimal  notation (unsigned integer) –
> for example ”0”, ”1” and must contain attribute _type_. According  to
> the _type_,  the  implementation  decides  how  to  handle  (or
> ignore) such an object.  This notation allows mapping to LUKS1 API
> functions that use an integer as a reference to keyslots objects."
> 
> So here, the spec is calling that value a "name", and saying that it
> must be a string of decimal digits.  Looking at the spec, the "name" of
> the keyslot object does not need to correspond to the index into the
> array of keyslot areas on disk.  However it does in the canonical
> implementation for use with LUKS1 API functions which require and
> integer, as suggested in the quote above.
> 
> I'd say that these numbers are actually an id for the object of its
> respective class.  In the cryptsetup implementation, the "id" happens
> to correspond to the index into the binary key area array, but that's
> needn't be the case. My preference would be to name it "id" and second
> choice would be just "idx" (since its usually an index into a physical
> array of key areas or virtual array of segments and digests).
> 
> I don't think the "json" part of the name is warranted, because it
> really has nothing to do with json.  The "slot" part is really only
> applicable to keyslots because digests and segments don't have an
> equivalent slot aspect.  So I suggest we name the struct member names
> to just "id" instead.  And where we just the index of the name-value
> pair in the json associative array we use "json_idx" as a suffix.  So
> this would mean changing the argument keyslot_idx in
> luks2_get_keyslot() to keyslot_json_idx. Optionally the local variable
> "i" in luks2_get_keyslot() and luks2_parse_segment() could be renamed
> to "json_idx" as well (I don't care either way about this though).
> 
> Glenn

Sounds sensible to me. Based on your reasoning, I'm happy with either
"id" or "key". So we may just as well just keep it as-is, as you prefer.

Patrick


signature.asc
Description: PGP signature
___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCHv2] grub-install: Add backup and restore

2020-12-07 Thread Dimitri John Ledkov
On Tue, 8 Dec 2020, 03:17 Michael Chang,  wrote:

> On Mon, Dec 07, 2020 at 12:37:28PM +, Dimitri John Ledkov wrote:
> > Refactor clean_grub_dir to create a backup of all the files, instead
> > of just irrevocably removing them as the first action. If available,
> > register on_exit handle to restore the backup if any errors occur, or
> > remove the backup if everything was successful. If on_exit is not
> > available, the backup remains on disk for manual recovery.
> >
> > This allows safer upgrades of MBR & modules, such that
> > modules/images/fonts/translations are consistent with MBR in case of
> > errors. For example accidental grub-install /dev/non-existent-disk
> > currently clobbers and upgrades modules in /boot/grub, despite not
> > actually updating any MBR. This increases peak disk-usage slightly, by
> > requiring temporarily twice the disk space to complete grub-install.
>
> I'd love to have the described problem fixed too, as it helps a lot in
> the update path to survive grub-install error which can be contributed
> by many different reasons, even though grub has to stay with old version
> but still much better than unbootable system.
>
> But here I have a concern, as to what will happen if the error comes
> after image installation ? For example, the efibootmgr may fail to
> register boot entry after copying the images to efi partition. It looks
> to me that the restoring backup would be triggerd incorrectly for the
> new image to load restored old backups.
>
> Would you please help to clarify that ?
>


On Ubuntu we install secureboot signed prebuilt EFI images only which
prohibit module loading. Hence usually it is irrelevant if the EFI grub
modules are old or new.

And we do not call efibootmgr at all, as it does excessive writes to
efivars. Instead we don't even try to update efivars if there is no need.
It was submitted to this mailing list but I am not sure on the acceptance
status https://lists.gnu.org/archive/html/grub-devel/2019-03/msg00123.html

Above two things make EFI updates less fatal, as it is harder for a
prebuilt signed grub, which does not use modules, to fail booting. Unlike
i386-pc case.

And to answer your immediate question - the new EFI image will be used for
boot without rolling back.

Also, I am not sure how everyone installs signed grubs. Thus adding support
for ESP backup and restore might be futile upstream. As far as I can tell
it is safe to call grub-install on Ubuntu, whereas it might not be on other
distros. As Ubuntu preserves / reinstalls signed grub EFI images, instead
of generating a new random one and putting it on ESP thus causing failure
to boot with secureboot due to effectively replacing signed grub with an
unsigned one. And for resilient boot we have support for maintaining and
synchronising multiple ESP for Linux raid.

I kind of wish we'd prebuilt more core images at package build time and
simply copy them around. Not just the ones that have signing. Instead of
invoking mkimage on every installed system.

Nonetheless, it should be possible to hook up more files and directories to
perform backup, cleanup and restore on. Is there is a desire. The function
calls simply need to be added in the appropriate places.


> >
> > Also add modinfo.sh to the cleanup/backup/restore codepath, to ensure
> > it is also cleaned / backed up / restored.
> >
> > Signed-off-by: Dimitri John Ledkov 
> > ---
> >
> >  Changes since v1: as reported on linux-ext4 mailing list and debugged
> >  by Colin Watson, the grub_util_path_concat_ext call was incorrect in
> >  the restore backup case as there was no extention needed. Instead the
> >  call is corrected to just grub_util_path_concat.
> >
> >  This patch is now shipped in Ubuntu & Debian in multiple series. It
> >  would be nice to have this merged upstream, as it greatly improves
> >  grub upgrades and prevents missmatches of MBR & modules.
> >
> >  configure.ac   |   2 +-
> >  util/grub-install-common.c | 105 +++--
> >  2 files changed, 91 insertions(+), 16 deletions(-)
> >
> > diff --git a/configure.ac b/configure.ac
> > index 7c10a4db7..71cd414c3 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -419,7 +419,7 @@ else
> >  fi
> >
> >  # Check for functions and headers.
> > -AC_CHECK_FUNCS(posix_memalign memalign getextmntent)
> > +AC_CHECK_FUNCS(posix_memalign memalign getextmntent on_exit)
> >  AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h limits.h)
> >
> >  # glibc 2.25 still includes sys/sysmacros.h in sys/types.h but emits
> deprecation
> > diff --git a/util/grub-install-common.c b/util/grub-install-common.c
> > index 277eaf4e2..74584b92b 100644
> > --- a/util/grub-install-common.c
> > +++ b/util/grub-install-common.c
> > @@ -185,38 +185,113 @@ grub_install_mkdir_p (const char *dst)
> >free (t);
> >  }
> >
> > +static int
> > +strcmp_ext (const char *a, const char *b, const char *ext)
> > +{
> > +  char *bsuffix = grub_util_path_concat_ext (1, 

Re: [PATCH v2] loopback: Do not automaticaly replace existing loopback dev, error instead

2020-12-07 Thread Glenn Washburn
On Fri, 4 Dec 2020 13:34:44 +0100
Daniel Kiper  wrote:

> On Thu, Dec 03, 2020 at 07:57:11PM -0600, Glenn Washburn wrote:
> > If there is a loopback device with the same name as the one to be
> > created, instead of closing the old one and replacing it with the
> > new one, return an error instead. If the loopback device was
> > created, its probably being used by something and just replacing it
> > may cause grub to crash unexpectedly. This fixes obvious problems
> > like `loopback d (d)/somefile'. Its not too onerous to force the
> > user to delete the loopback first with the `-d' switch.
> >
> > Signed-off-by: Glenn Washburn 
> 
> Reviewed-by: Daniel Kiper 
> 
> Daniel
> 
> PS May I ask you to create new thread for new version of the patches
>instead of attaching them to previous threads?

These two patches were not meant to be a thread together, ie separate
patches, which was why I was treating them separately.  I can see how
that might be confusing now.

Glenn


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: Mips-arc tests ever work?

2020-12-07 Thread Glenn Washburn
On Sat, 5 Dec 2020 21:28:05 +0100
John Paul Adrian Glaubitz  wrote:

> On 12/5/20 8:10 PM, Glenn Washburn wrote:
> >> I'm running manual tests for all architectures before each release.
> > 
> > What exactly are manual tests?  Is that running manually the tests
> > for that target? (ie "make check" for that target)
> 
> Yes. I'm test-compiling GRUB natively, run "make check" and also
> perform test installations in some cases.

Ok so I'm clear, since you're running "make check", your qemu tests for
mips-arc are failing due to indy not being a machine type, correct?

> > Also what version of qemu are you running to do the tests?
> 
> I'm performing all tests on real hardware. I have access to all
> architectures supported by GRUB either through my personal hardware
> zoo, the Debian project of which I am member of or the GCC compile
> farm for which I am also providing hardware.
> 
> You are free to register for the GCC compile farm and use it yourself
> [1].

Cool project, thanks for the tip.

> >> I could not find any reference to "indy" in the qemu git log. Are
> >> you sure it was ever officially supported? I assume the tests here
> >> were run on real hardware.
> > 
> > Take a look in "tests/util/grub-shell.in" and you'll find the
> > offending test code in grub.  I have no clue either way whether it
> > was ever supported, but someone obviously did because its in the
> > test code.  And that someone might be Vladimir (phcoder) who
> > committed the code.  This is why I'm wondering if it ever worked.
> 
> Maybe he used a fork of qemu for these tests.
> 
> >>> According to wikipedia the SGI Indy originally used R4k
> >>> processors. So would machine type mips be the one to use since
> >>> its description says "mips r4k platform"?
> >>
> >> No, that was a different, generic machine type, see [1].
> > 
> > I'm confused by this response.  My qemu doesn't list a "r4k" machine
> > type and its version 4.2.1.  The machine type "mips" says its the
> > r4k platform, but that doesn't look like what's being removed in
> > that commit.  Reviewing the hw/mips/Kconfig, it looks like the
> > machine types have changed a lot since 4.2.1, so maybe it was
> > renamed to "r4k" (haven't checked yet).  However if it was renamed
> > and is being removed, that's going to cause further problems
> > (when/if we use qemu 5.2 for testing) because grub-shell is using
> > the "mips" machine type for "mips-qemu_mips" and "mipsel-qemu_mips".
> 
> Well, either way, the r4k machine no longer exists in QEMU 5.2.
> 
> >>> So can anyone familiar with this tell me an appropriate machine
> >>> type of the above listed to use instead of indy?  Perhaps Vladimir
> >>> who committed that code can chime in?
> > 
> > Ultimately, I just want to know what machine should I use if not
> > indy for the "mips-arc" target?  I know very little about mips and
> > what an appropriate machine type would be for emulating this target.
> 
> I guess "malta" would work, too.

Ok, see if that works.

> Adrian
> 
> > [1] https://gcc.gnu.org/wiki/CompileFarm
> 

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v7 12/17] luks2: Better error handling when setting up the cryptodisk

2020-12-07 Thread Glenn Washburn
This patch got mangled accidentally with patch 5.  I'll update them
both.

Glenn

On Fri,  4 Dec 2020 10:43:41 -0600
Glenn Washburn  wrote:

> First, check to make sure that source disk has a known size. If not,
> print debug message and return error. There are 4 cases where
> GRUB_DISK_SIZE_UNKNOWN is set (biosdisk, obdisk, ofdisk, and uboot),
> and in all those cases processing continues. So this is probably a bit
> conservative. However, 3 of the cases seem pathological, and the
> other, biosdisk, happens when booting from a cd. Since I doubt
> booting from a LUKS2 volume on a cd is a big use case, we'll error
> until someone complains.
> 
> Do some sanity checking on data coming from the luks header. If
> segment.size is "dynamic",
> 
> Check for errors from grub_strtoull when converting segment size from
> string. If a GRUB_ERR_BAD_NUMBER error was returned, then the string
> was not a valid parsable number, so skip the key. If
> GRUB_ERR_OUT_OF_RANGE was returned, then there was an overflow in
> converting to a 64-bit unsigned integer. So this could be a very
> large disk (perhaps large raid array). In this case, we want to
> continue to try to use this key so long as the source disk's size is
> greater than this segment size. Otherwise, this is an invalid
> segment, and continue on to the next key.
> 
> Signed-off-by: Glenn Washburn 
> ---
>  grub-core/disk/luks2.c | 98
> +- include/grub/disk.h|
> 17  2 files changed, 105 insertions(+), 10 deletions(-)
> 
> diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
> index de2e70796..1bb3a333d 100644
> --- a/grub-core/disk/luks2.c
> +++ b/grub-core/disk/luks2.c
> @@ -290,7 +290,7 @@ luks2_get_keyslot (grub_luks2_keyslot_t *k,
> grub_luks2_digest_t *d, grub_luks2_s break;
>  }
>if (i == size)
> -  return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No digest for
> keyslot \"%"PRIuGRUB_UINT64_T"\"", k->slot_key);
> +  return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No digest for
> keyslot \"%"PRIuGRUB_UINT64_T"\"", k->json_slot_key); 
>/* Get segment that matches the digest. */
>if (grub_json_getvalue (, root, "segments") ||
> @@ -308,7 +308,7 @@ luks2_get_keyslot (grub_luks2_keyslot_t *k,
> grub_luks2_digest_t *d, grub_luks2_s break;
>  }
>if (i == size)
> -return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No segment for
> digest \"%"PRIuGRUB_UINT64_T"\"", d->slot_key);
> +return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No segment for
> digest \"%"PRIuGRUB_UINT64_T"\"", d->json_slot_key); 
>return GRUB_ERR_NONE;
>  }
> @@ -600,37 +600,115 @@ luks2_recover_key (grub_disk_t source,
>goto err;
>  }
>  
> +  if (source->total_sectors == GRUB_DISK_SIZE_UNKNOWN)
> +{
> +  /* FIXME: Allow use of source disk, and maybe cause errors in
> read. */
> +  grub_dprintf ("luks2", "Source disk %s has an unknown size, "
> +  "conservatively returning error\n",
> source->name);
> +  ret = grub_error (GRUB_ERR_BUG, "Unknown size of luks2 source
> device");
> +  goto err;
> +}
> +
>/* Try all keyslot */
>for (i = 0; i < size; i++)
>  {
> +  typeof(source->total_sectors) max_crypt_sectors = 0;
> +
> +  grub_errno = GRUB_ERR_NONE;
>ret = luks2_get_keyslot (, , , json, i);
>if (ret)
>   goto err;
> +  if (grub_errno != GRUB_ERR_NONE)
> +   grub_dprintf ("luks2", "Ignoring unhandled error %d from
> luks2_get_keyslot\n", grub_errno); 
>if (keyslot.priority == 0)
>   {
> -   grub_dprintf ("luks2", "Ignoring keyslot
> \"%"PRIuGRUB_UINT64_T"\" due to priority\n", keyslot.slot_key);
> +   grub_dprintf ("luks2", "Ignoring keyslot
> \"%"PRIuGRUB_UINT64_T"\" due to priority\n", keyslot.json_slot_key);
> continue; }
>  
> -  grub_dprintf ("luks2", "Trying keyslot
> \"%"PRIuGRUB_UINT64_T"\"\n", keyslot.slot_key);
> +  grub_dprintf ("luks2", "Trying keyslot
> \"%"PRIuGRUB_UINT64_T"\"\n", keyslot.json_slot_key); 
>/* Set up disk according to keyslot's segment. */
>crypt->offset_sectors = grub_divmod64 (segment.offset,
> segment.sector_size, NULL); crypt->log_sector_size = sizeof (unsigned
> int) * 8
>   - __builtin_clz ((unsigned int) segment.sector_size)
> - 1;
> +  /* Set to the source disk size, which is the maximum we allow.
> */
> +  max_crypt_sectors = grub_disk_convert_sector(source,
> +
> source->total_sectors,
> +
> crypt->log_sector_size); +
> +  if (max_crypt_sectors < crypt->offset_sectors)
> + {
> +   grub_dprintf ("luks2", "Segment \"%"PRIuGRUB_UINT64_T"\"
> has offset"
> +  " %"PRIuGRUB_UINT64_T" which is
> greater than"
> +  " source disk size
> %"PRIuGRUB_UINT64_T","
> +  " skipping\n",
> +  segment.json_slot_key,
> crypt->offset_sectors,
> +  max_crypt_sectors);
> +  

Re: [PATCH v7 05/17] luks2: Add json_slot_key member to struct grub_luks2_keyslot/segment/digest

2020-12-07 Thread Glenn Washburn
On Mon, 7 Dec 2020 21:02:39 +0100
Daniel Kiper  wrote:

> On Sun, Dec 06, 2020 at 02:29:06PM +0100, Patrick Steinhardt wrote:
> > On Fri, Dec 04, 2020 at 10:43:34AM -0600, Glenn Washburn wrote:
> > > This allows code using these structs to know the named key
> > > associated with these json data structures. In the future we can
> > > use these to provide better error messages to the user.
> > >
> > > Get rid of idx variable in luks2_get_keyslot() which was
> > > overloaded to be used for both keyslot and segment slot keys.
> > >
> > > Signed-off-by: Glenn Washburn 
> >
> > Personally, I'd have named them `json_slot_idx`. But you've already
> > done so much work on improving the code that I don't want this to
> > be the reason to not give an SOB, especially considering that it's
> > a strict improvement anyway. So:
> >
> > Signed-off-by: Patrick Steinhardt 
> 
> I can change this to json_slot_idx before committing if Glenn does not
> object. Otherwise Reviewed-by: Daniel Kiper 

Thanks Patrick for the sentiment.  Looking at the luks2 spec, it says:

"JSON  objects  must  have  their names  formatted  as  a  string  that
represents  a  number  in  the  decimal  notation (unsigned integer) –
for example ”0”, ”1” and must contain attribute _type_. According  to
the _type_,  the  implementation  decides  how  to  handle  (or
ignore) such an object.  This notation allows mapping to LUKS1 API
functions that use an integer as a reference to keyslots objects."

So here, the spec is calling that value a "name", and saying that it
must be a string of decimal digits.  Looking at the spec, the "name" of
the keyslot object does not need to correspond to the index into the
array of keyslot areas on disk.  However it does in the canonical
implementation for use with LUKS1 API functions which require and
integer, as suggested in the quote above.

I'd say that these numbers are actually an id for the object of its
respective class.  In the cryptsetup implementation, the "id" happens
to correspond to the index into the binary key area array, but that's
needn't be the case. My preference would be to name it "id" and second
choice would be just "idx" (since its usually an index into a physical
array of key areas or virtual array of segments and digests).

I don't think the "json" part of the name is warranted, because it
really has nothing to do with json.  The "slot" part is really only
applicable to keyslots because digests and segments don't have an
equivalent slot aspect.  So I suggest we name the struct member names
to just "id" instead.  And where we just the index of the name-value
pair in the json associative array we use "json_idx" as a suffix.  So
this would mean changing the argument keyslot_idx in
luks2_get_keyslot() to keyslot_json_idx. Optionally the local variable
"i" in luks2_get_keyslot() and luks2_parse_segment() could be renamed
to "json_idx" as well (I don't care either way about this though).

Glenn

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v7 09/17] cryptodisk: Add macros GRUB_TYPE_U_MAX/MIN(type) to replace literals

2020-12-07 Thread Glenn Washburn
On Mon, 7 Dec 2020 21:22:09 +0100
Daniel Kiper  wrote:

> On Fri, Dec 04, 2020 at 10:43:38AM -0600, Glenn Washburn wrote:
> > Add GRUB_TYPE_U_MAX/MIN(type) macros to get the max/min values for
> > an unsigned number with size of type.
> >
> > Signed-off-by: Glenn Washburn 
> 
> Reviewed-by: Daniel Kiper 
> 
> But one nit below...
> 
> > ---
> >  grub-core/disk/cryptodisk.c | 8 
> >  include/grub/types.h| 7 +++
> >  2 files changed, 11 insertions(+), 4 deletions(-)
> >
> > diff --git a/grub-core/disk/cryptodisk.c
> > b/grub-core/disk/cryptodisk.c index 0e955a020..5aa0c4720 100644
> > --- a/grub-core/disk/cryptodisk.c
> > +++ b/grub-core/disk/cryptodisk.c
> > @@ -284,23 +284,23 @@ grub_cryptodisk_endecrypt (struct
> > grub_cryptodisk *dev, iv[1] = grub_cpu_to_le32 (sector >>
> > GRUB_TYPE_BITS (iv[0])); /* FALLTHROUGH */
> > case GRUB_CRYPTODISK_MODE_IV_PLAIN:
> > - iv[0] = grub_cpu_to_le32 (sector & 0x);
> > + iv[0] = grub_cpu_to_le32 (sector & GRUB_TYPE_U_MAX
> > (iv[0])); break;
> > case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64:
> >   iv[1] = grub_cpu_to_le32 (sector >> (GRUB_TYPE_BITS
> > (iv[1])
> >-
> > dev->log_sector_size)); iv[0] = grub_cpu_to_le32 ((sector <<
> > dev->log_sector_size)
> > -   & 0x);
> > +   & GRUB_TYPE_U_MAX (iv[0]));
> >   break;
> > case GRUB_CRYPTODISK_MODE_IV_BENBI:
> >   {
> > grub_uint64_t num = (sector << dev->benbi_log) + 1;
> > iv[sz - 2] = grub_cpu_to_be32 (num >> GRUB_TYPE_BITS
> > (iv[0]));
> > -   iv[sz - 1] = grub_cpu_to_be32 (num & 0x);
> > +   iv[sz - 1] = grub_cpu_to_be32 (num & GRUB_TYPE_U_MAX
> > (iv[0])); }
> >   break;
> > case GRUB_CRYPTODISK_MODE_IV_ESSIV:
> > - iv[0] = grub_cpu_to_le32 (sector & 0x);
> > + iv[0] = grub_cpu_to_le32 (sector & GRUB_TYPE_U_MAX
> > (iv[0])); err = grub_crypto_ecb_encrypt (dev->essiv_cipher, iv, iv,
> >  dev->cipher->cipher->blocksize);
> >   if (err)
> > diff --git a/include/grub/types.h b/include/grub/types.h
> > index 9989e3a16..0542011cc 100644
> > --- a/include/grub/types.h
> > +++ b/include/grub/types.h
> > @@ -161,6 +161,13 @@ typedef grub_int32_t   grub_ssize_t;
> >  #endif
> >  # define GRUB_LONG_MIN (-GRUB_LONG_MAX - 1)
> >
> > +/*
> > +  Cast to unsigned long long so that the "return value" is always
> > a consistent
> > +  type and to ensure an unsigned value regardless of type
> > parameter.
> > + */
> 
> Incorrect comment formatting...

I'll fix it, and get it right one of these days.

> > +#define GRUB_TYPE_U_MAX(type) ((unsigned long long)((typeof
> > (type))(~0))) +#define GRUB_TYPE_U_MIN(type) 0ULL
> > +
> >  typedef grub_uint64_t grub_properly_aligned_t;
> >
> >  #define GRUB_PROPERLY_ALIGNED_ARRAY(name, size)
> > grub_properly_aligned_t name[((size) + sizeof
> > (grub_properly_aligned_t) - 1) / sizeof (grub_properly_aligned_t)]
> 
> Daniel

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v7 12/17] luks2: Better error handling when setting up the cryptodisk

2020-12-07 Thread Glenn Washburn
On Sun, 6 Dec 2020 20:35:13 +0100
Patrick Steinhardt  wrote:

> On Fri, Dec 04, 2020 at 10:43:41AM -0600, Glenn Washburn wrote:
> > First, check to make sure that source disk has a known size. If
> > not, print debug message and return error. There are 4 cases where
> > GRUB_DISK_SIZE_UNKNOWN is set (biosdisk, obdisk, ofdisk, and
> > uboot), and in all those cases processing continues. So this is
> > probably a bit conservative. However, 3 of the cases seem
> > pathological, and the other, biosdisk, happens when booting from a
> > cd. Since I doubt booting from a LUKS2 volume on a cd is a big use
> > case, we'll error until someone complains.
> > 
> > Do some sanity checking on data coming from the luks header. If
> > segment.size is "dynamic",
> 
> Nit: there's something missing here.

Yep, thanks for catching that. I was going to complete this and forgot
in my rush to get the series out before some travel.  I'll rework that.

> > Check for errors from grub_strtoull when converting segment size
> > from string. If a GRUB_ERR_BAD_NUMBER error was returned, then the
> > string was not a valid parsable number, so skip the key. If
> > GRUB_ERR_OUT_OF_RANGE was returned, then there was an overflow in
> > converting to a 64-bit unsigned integer. So this could be a very
> > large disk (perhaps large raid array). In this case, we want to
> > continue to try to use this key so long as the source disk's size
> > is greater than this segment size. Otherwise, this is an invalid
> > segment, and continue on to the next key.
> > 
> > Signed-off-by: Glenn Washburn 
> > ---
> >  grub-core/disk/luks2.c | 98
> > +- include/grub/disk.h|
> > 17  2 files changed, 105 insertions(+), 10 deletions(-)
> > 
> > diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
> > index de2e70796..1bb3a333d 100644
> > --- a/grub-core/disk/luks2.c
> > +++ b/grub-core/disk/luks2.c
> > @@ -290,7 +290,7 @@ luks2_get_keyslot (grub_luks2_keyslot_t *k,
> > grub_luks2_digest_t *d, grub_luks2_s break;
> >  }
> >if (i == size)
> > -  return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No digest for
> > keyslot \"%"PRIuGRUB_UINT64_T"\"", k->slot_key);
> > +  return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No digest for
> > keyslot \"%"PRIuGRUB_UINT64_T"\"", k->json_slot_key); 
> >/* Get segment that matches the digest. */
> >if (grub_json_getvalue (, root, "segments") ||
> > @@ -308,7 +308,7 @@ luks2_get_keyslot (grub_luks2_keyslot_t *k,
> > grub_luks2_digest_t *d, grub_luks2_s break;
> >  }
> >if (i == size)
> > -return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No segment for
> > digest \"%"PRIuGRUB_UINT64_T"\"", d->slot_key);
> > +return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No segment for
> > digest \"%"PRIuGRUB_UINT64_T"\"", d->json_slot_key); 
> >return GRUB_ERR_NONE;
> >  }
> > @@ -600,37 +600,115 @@ luks2_recover_key (grub_disk_t source,
> >goto err;
> >  }
> >  
> > +  if (source->total_sectors == GRUB_DISK_SIZE_UNKNOWN)
> > +{
> > +  /* FIXME: Allow use of source disk, and maybe cause errors
> > in read. */
> > +  grub_dprintf ("luks2", "Source disk %s has an unknown size, "
> > +"conservatively returning error\n",
> > source->name);
> > +  ret = grub_error (GRUB_ERR_BUG, "Unknown size of luks2
> > source device");
> > +  goto err;
> > +}
> > +
> >/* Try all keyslot */
> >for (i = 0; i < size; i++)
> >  {
> > +  typeof(source->total_sectors) max_crypt_sectors = 0;
> 
> Please bear with me if this has been discussed in a previous round,
> but why exactly do we cast `max_crypt_sectors` to the type of
> `source->total_sectors`?

Technically, this isn't a cast.  Its a variable declaration.  But I'm
using the typeof(source->total_sectors) because max_crypt_sectors can
be no more or less than the total sectors, ie its of the same type.

> And isn't the variable always set anyway in
> case the keyslot has a non-zero priority?

Yep. Are you suggesting that it need not be initialized?  This is true,
but I don't think that's a problem.  I think generally initializing
things is a good practice.  It might be problematic if this was in an
oft used function (or it might not, would need to see if the compiler
was smart enough to ignore the initialization).  But that
initialization is going to happen very rarely in the lifetime of a grub
execution instance.  I also don't really care either way.

Glenn

> Patrick
>
> > +
> > +  grub_errno = GRUB_ERR_NONE;
> >ret = luks2_get_keyslot (, , , json,
> > i); if (ret)
> > goto err;
> > +  if (grub_errno != GRUB_ERR_NONE)
> > + grub_dprintf ("luks2", "Ignoring unhandled error %d from
> > luks2_get_keyslot\n", grub_errno); 
> >if (keyslot.priority == 0)
> > {
> > - grub_dprintf ("luks2", "Ignoring keyslot
> > \"%"PRIuGRUB_UINT64_T"\" due to priority\n", keyslot.slot_key);
> > + grub_dprintf ("luks2", "Ignoring 

Re: [PATCHv2] grub-install: Add backup and restore

2020-12-07 Thread Michael Chang via Grub-devel
On Mon, Dec 07, 2020 at 12:37:28PM +, Dimitri John Ledkov wrote:
> Refactor clean_grub_dir to create a backup of all the files, instead
> of just irrevocably removing them as the first action. If available,
> register on_exit handle to restore the backup if any errors occur, or
> remove the backup if everything was successful. If on_exit is not
> available, the backup remains on disk for manual recovery.
> 
> This allows safer upgrades of MBR & modules, such that
> modules/images/fonts/translations are consistent with MBR in case of
> errors. For example accidental grub-install /dev/non-existent-disk
> currently clobbers and upgrades modules in /boot/grub, despite not
> actually updating any MBR. This increases peak disk-usage slightly, by
> requiring temporarily twice the disk space to complete grub-install.

I'd love to have the described problem fixed too, as it helps a lot in
the update path to survive grub-install error which can be contributed
by many different reasons, even though grub has to stay with old version
but still much better than unbootable system.

But here I have a concern, as to what will happen if the error comes
after image installation ? For example, the efibootmgr may fail to
register boot entry after copying the images to efi partition. It looks
to me that the restoring backup would be triggerd incorrectly for the
new image to load restored old backups.

Would you please help to clarify that ?

Thanks,
Michael


> 
> Also add modinfo.sh to the cleanup/backup/restore codepath, to ensure
> it is also cleaned / backed up / restored.
> 
> Signed-off-by: Dimitri John Ledkov 
> ---
> 
>  Changes since v1: as reported on linux-ext4 mailing list and debugged
>  by Colin Watson, the grub_util_path_concat_ext call was incorrect in
>  the restore backup case as there was no extention needed. Instead the
>  call is corrected to just grub_util_path_concat.
> 
>  This patch is now shipped in Ubuntu & Debian in multiple series. It
>  would be nice to have this merged upstream, as it greatly improves
>  grub upgrades and prevents missmatches of MBR & modules.
> 
>  configure.ac   |   2 +-
>  util/grub-install-common.c | 105 +++--
>  2 files changed, 91 insertions(+), 16 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 7c10a4db7..71cd414c3 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -419,7 +419,7 @@ else
>  fi
>  
>  # Check for functions and headers.
> -AC_CHECK_FUNCS(posix_memalign memalign getextmntent)
> +AC_CHECK_FUNCS(posix_memalign memalign getextmntent on_exit)
>  AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h limits.h)
>  
>  # glibc 2.25 still includes sys/sysmacros.h in sys/types.h but emits 
> deprecation
> diff --git a/util/grub-install-common.c b/util/grub-install-common.c
> index 277eaf4e2..74584b92b 100644
> --- a/util/grub-install-common.c
> +++ b/util/grub-install-common.c
> @@ -185,38 +185,113 @@ grub_install_mkdir_p (const char *dst)
>free (t);
>  }
>  
> +static int
> +strcmp_ext (const char *a, const char *b, const char *ext)
> +{
> +  char *bsuffix = grub_util_path_concat_ext (1, b, ext);
> +  int r = strcmp (a, bsuffix);
> +  free (bsuffix);
> +  return r;
> +}
> +
> +enum clean_grub_dir_mode
> +{
> +  CLEAN = 0,
> +  CLEAN_BACKUP = 1,
> +  CREATE_BACKUP = 2,
> +  RESTORE_BACKUP = 3,
> +};
> +
>  static void
> -clean_grub_dir (const char *di)
> +clean_grub_dir_real (const char *di, enum clean_grub_dir_mode mode)
>  {
>grub_util_fd_dir_t d;
>grub_util_fd_dirent_t de;
> +  char suffix[2] = "";
> +
> +  if ((mode == CLEAN_BACKUP) || (mode == RESTORE_BACKUP))
> +{
> +  strcpy (suffix, "-");
> +}
>  
>d = grub_util_fd_opendir (di);
>if (!d)
> -grub_util_error (_("cannot open directory `%s': %s"),
> -  di, grub_util_fd_strerror ());
> +{
> +  if (mode == CLEAN_BACKUP)
> + return;
> +  grub_util_error (_("cannot open directory `%s': %s"),
> +di, grub_util_fd_strerror ());
> +}
>  
>while ((de = grub_util_fd_readdir (d)))
>  {
>const char *ext = strrchr (de->d_name, '.');
> -  if ((ext && (strcmp (ext, ".mod") == 0
> -|| strcmp (ext, ".lst") == 0
> -|| strcmp (ext, ".img") == 0
> -|| strcmp (ext, ".mo") == 0)
> -&& strcmp (de->d_name, "menu.lst") != 0)
> -   || strcmp (de->d_name, "efiemu32.o") == 0
> -   || strcmp (de->d_name, "efiemu64.o") == 0)
> +  if ((ext && (strcmp_ext (ext, ".mod", suffix) == 0
> +|| strcmp_ext (ext, ".lst", suffix) == 0
> +|| strcmp_ext (ext, ".img", suffix) == 0
> +|| strcmp_ext (ext, ".mo", suffix) == 0)
> +&& strcmp_ext (de->d_name, "menu.lst", suffix) != 0)
> +   || strcmp_ext (de->d_name, "modinfo.sh", suffix) == 0
> +   || strcmp_ext (de->d_name, "efiemu32.o", suffix) == 0
> +   || strcmp_ext (de->d_name, "efiemu64.o", 

Re: [PATCH 8/9] efi: Only register shim_lock verifier if shim_lock protocol is found and SB enabled

2020-12-07 Thread Michael Chang via Grub-devel
On Thu, Dec 03, 2020 at 04:01:49PM +0100, Javier Martinez Canillas wrote:
> The shim_lock module registers a verifier to call shim's verify, but the
> handler is registered even when the shim_lock protocol was not installed.
> 
> This doesn't cause a NULL pointer dereference in shim_lock_write() because
> the shim_lock_init() function just returns GRUB_ERR_NONE if sl isn't set.
> 
> But in that case there's no point to even register the shim_lock verifier
> since won't do anything. Additionally, it is only useful when Secure Boot
> is enabled.
> 
> Finally, don't assume that the shim_lock protocol will always be present
> when the shim_lock_write() function is called, and check for it on every
> call to this function.
> 
> Reported-by: Michael Chang 

To complete the information here, this fixed the problem I tried to
solve before, but in a more elegant way. :)

https://www.mail-archive.com/grub-devel@gnu.org/msg30738.html

Thank you to work on the patch.

Regards,
Michael

> Reported-by: Peter Jones 
> Signed-off-by: Javier Martinez Canillas 
> ---
> 
>  grub-core/commands/efi/shim_lock.c | 16 +---
>  1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/grub-core/commands/efi/shim_lock.c 
> b/grub-core/commands/efi/shim_lock.c
> index d8f52d721c3..5259b27e8fc 100644
> --- a/grub-core/commands/efi/shim_lock.c
> +++ b/grub-core/commands/efi/shim_lock.c
> @@ -28,7 +28,6 @@
>  GRUB_MOD_LICENSE ("GPLv3+");
>  
>  static grub_efi_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
> -static grub_efi_shim_lock_protocol_t *sl;
>  
>  /* List of modules which cannot be loaded if UEFI secure boot mode is 
> enabled. */
>  static const char * const disabled_mods[] = {"iorw", "memrw", "wrmsr", NULL};
> @@ -43,9 +42,6 @@ shim_lock_init (grub_file_t io, enum grub_file_type type,
>  
>*flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
>  
> -  if (!sl)
> -return GRUB_ERR_NONE;
> -
>switch (type & GRUB_FILE_TYPE_MASK)
>  {
>  case GRUB_FILE_TYPE_GRUB_MODULE:
> @@ -100,6 +96,11 @@ shim_lock_init (grub_file_t io, enum grub_file_type type,
>  static grub_err_t
>  shim_lock_write (void *context __attribute__ ((unused)), void *buf, 
> grub_size_t size)
>  {
> +  grub_efi_shim_lock_protocol_t *sl = grub_efi_locate_protocol 
> (_lock_guid, 0);
> +
> +  if (sl == NULL)
> +return grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim_lock protocol not 
> found"));
> +
>if (sl->verify (buf, size) != GRUB_EFI_SUCCESS)
>  return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim signature"));
>  
> @@ -115,12 +116,13 @@ struct grub_file_verifier shim_lock =
>  
>  GRUB_MOD_INIT(shim_lock)
>  {
> -  sl = grub_efi_locate_protocol (_lock_guid, 0);
> -  grub_verifier_register (_lock);
> +  grub_efi_shim_lock_protocol_t *sl = grub_efi_locate_protocol 
> (_lock_guid, 0);
>  
> -  if (!sl)
> +  if (sl == NULL || grub_efi_get_secureboot () != 
> GRUB_EFI_SECUREBOOT_MODE_ENABLED)
>  return;
>  
> +  grub_verifier_register (_lock);
> +
>grub_dl_set_persistent (mod);
>  }
>  
> -- 
> 2.28.0
> 


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH] templates: allow loading a Device Tree file from user conf

2020-12-07 Thread Matteo Croce
From: Matteo Croce 

Some machines rely on Device Tree for hardware discovery, so a
.dtb file must be passed to the kernel.

GRUB can do this via the `devicetree` command, but it's not possible
to do this from the user configuration.

Add a GRUB_DEVICETREE_FILE variable which holds the path of the .dtb
file relative to the boot partition and, if present, adds the
devicetree command to the menuentry.

Signed-off-by: Matteo Croce 
---
 util/grub-mkconfig.in   | 1 +
 util/grub.d/10_linux.in | 5 +
 2 files changed, 6 insertions(+)

diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
index d3e879b8e..3e15e6f20 100644
--- a/util/grub-mkconfig.in
+++ b/util/grub-mkconfig.in
@@ -228,6 +228,7 @@ export GRUB_DEFAULT \
   GRUB_CMDLINE_NETBSD \
   GRUB_CMDLINE_NETBSD_DEFAULT \
   GRUB_CMDLINE_GNUMACH \
+  GRUB_DEVICETREE_FILE \
   GRUB_EARLY_INITRD_LINUX_CUSTOM \
   GRUB_EARLY_INITRD_LINUX_STOCK \
   GRUB_TERMINAL_INPUT \
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
index e8b01c0d0..fb1bd30f5 100644
--- a/util/grub.d/10_linux.in
+++ b/util/grub.d/10_linux.in
@@ -143,6 +143,11 @@ linux_entry ()
echo'$(echo "$message" | grub_quote)'
linux   ${rel_dirname}/${basename} 
root=${linux_root_device_thisversion} ro ${args}
 EOF
+  if [ -n "${GRUB_DEVICETREE_FILE}" ] && test -e 
"${dirname}/${GRUB_DEVICETREE_FILE}"; then
+sed "s/^/$submenu_indentation/" << EOF
+   devicetree ${rel_dirname}/${GRUB_DEVICETREE_FILE}
+EOF
+  fi
   if test -n "${initrd}" ; then
 # TRANSLATORS: ramdisk isn't identifier. Should be translated.
 message="$(gettext_printf "Loading initial ramdisk ...")"
-- 
2.28.0


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [SPECIFICATION RFC] The firmware and bootloader log specification

2020-12-07 Thread Tom Rini
On Fri, Dec 04, 2020 at 02:23:23PM +0100, Paul Menzel wrote:
> Dear Wim, dear Daniel,
> 
> 
> First, thank you for including all parties in the discussion.
> Am 04.12.20 um 13:52 schrieb Wim Vervoorn:
> 
> > I agree with you. Using an existing standard is better than inventing
> > a new one in this case. I think using the coreboot logging is a good
> > idea as there is indeed a lot of support already available and it is
> > lightweight and simple.
> In my opinion coreboot’s format is lacking, that it does not record the
> timestamp, and the log level is not stored as metadata, but (in coreboot)
> only used to decide if to print the message or not.
> 
> I agree with you, that an existing standard should be used, and in my
> opinion it’s Linux message format. That is most widely supported, and
> existing tools could then also work with pre-Linux messages.
> 
> Sean Hudson from Mentor Graphics presented that idea at Embedded Linux
> Conference Europe 2016 [1]. No idea, if anything came out of that effort.
> (Unfortunately, I couldn’t find an email. Does somebody have contacts at
> Mentor to find out, how to reach him?)

I believe the main thing that came out of this was the reminder that
there was an even older attempt by U-Boot to have such a mechanism, and
that at the time getting the work accepted in Linux faced some hurdles
or another.

That said, I too agree with taking what's already a de facto standard,
the coreboot logging, and expand on it as needed.

-- 
Tom


signature.asc
Description: PGP signature
___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v7 09/17] cryptodisk: Add macros GRUB_TYPE_U_MAX/MIN(type) to replace literals

2020-12-07 Thread Daniel Kiper
On Fri, Dec 04, 2020 at 10:43:38AM -0600, Glenn Washburn wrote:
> Add GRUB_TYPE_U_MAX/MIN(type) macros to get the max/min values for an
> unsigned number with size of type.
>
> Signed-off-by: Glenn Washburn 

Reviewed-by: Daniel Kiper 

But one nit below...

> ---
>  grub-core/disk/cryptodisk.c | 8 
>  include/grub/types.h| 7 +++
>  2 files changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
> index 0e955a020..5aa0c4720 100644
> --- a/grub-core/disk/cryptodisk.c
> +++ b/grub-core/disk/cryptodisk.c
> @@ -284,23 +284,23 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev,
> iv[1] = grub_cpu_to_le32 (sector >> GRUB_TYPE_BITS (iv[0]));
> /* FALLTHROUGH */
>   case GRUB_CRYPTODISK_MODE_IV_PLAIN:
> -   iv[0] = grub_cpu_to_le32 (sector & 0x);
> +   iv[0] = grub_cpu_to_le32 (sector & GRUB_TYPE_U_MAX (iv[0]));
> break;
>   case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64:
> iv[1] = grub_cpu_to_le32 (sector >> (GRUB_TYPE_BITS (iv[1])
>  - dev->log_sector_size));
> iv[0] = grub_cpu_to_le32 ((sector << dev->log_sector_size)
> - & 0x);
> + & GRUB_TYPE_U_MAX (iv[0]));
> break;
>   case GRUB_CRYPTODISK_MODE_IV_BENBI:
> {
>   grub_uint64_t num = (sector << dev->benbi_log) + 1;
>   iv[sz - 2] = grub_cpu_to_be32 (num >> GRUB_TYPE_BITS (iv[0]));
> - iv[sz - 1] = grub_cpu_to_be32 (num & 0x);
> + iv[sz - 1] = grub_cpu_to_be32 (num & GRUB_TYPE_U_MAX (iv[0]));
> }
> break;
>   case GRUB_CRYPTODISK_MODE_IV_ESSIV:
> -   iv[0] = grub_cpu_to_le32 (sector & 0x);
> +   iv[0] = grub_cpu_to_le32 (sector & GRUB_TYPE_U_MAX (iv[0]));
> err = grub_crypto_ecb_encrypt (dev->essiv_cipher, iv, iv,
>dev->cipher->cipher->blocksize);
> if (err)
> diff --git a/include/grub/types.h b/include/grub/types.h
> index 9989e3a16..0542011cc 100644
> --- a/include/grub/types.h
> +++ b/include/grub/types.h
> @@ -161,6 +161,13 @@ typedef grub_int32_t grub_ssize_t;
>  #endif
>  # define GRUB_LONG_MIN (-GRUB_LONG_MAX - 1)
>
> +/*
> +  Cast to unsigned long long so that the "return value" is always a 
> consistent
> +  type and to ensure an unsigned value regardless of type parameter.
> + */

Incorrect comment formatting...

> +#define GRUB_TYPE_U_MAX(type) ((unsigned long long)((typeof (type))(~0)))
> +#define GRUB_TYPE_U_MIN(type) 0ULL
> +
>  typedef grub_uint64_t grub_properly_aligned_t;
>
>  #define GRUB_PROPERLY_ALIGNED_ARRAY(name, size) grub_properly_aligned_t 
> name[((size) + sizeof (grub_properly_aligned_t) - 1) / sizeof 
> (grub_properly_aligned_t)]

Daniel

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v7 08/17] cryptodisk: Add macro GRUB_TYPE_BITS() to replace some literals

2020-12-07 Thread Daniel Kiper
On Fri, Dec 04, 2020 at 10:43:37AM -0600, Glenn Washburn wrote:
> The new macro GRUB_TYPE_BITS(type) returns the number of bits allocated for
> type.
>
> Signed-off-by: Glenn Washburn 

Reviewed-by: Daniel Kiper 

Daniel

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v7 07/17] luks2: Add string "index" to user strings using a json index.

2020-12-07 Thread Daniel Kiper
On Fri, Dec 04, 2020 at 10:43:36AM -0600, Glenn Washburn wrote:
> This allows error messages to be more easily distinguishable between indexes
> and slot keys. The former include the string "index" in the error/debug
> string, and the later are surrounded in quotes.
>
> Signed-off-by: Glenn Washburn 

Reviewed-by: Daniel Kiper 

Daniel

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v7 06/17] luks2: Use more intuitive slot key instead of index in user messages

2020-12-07 Thread Daniel Kiper
On Fri, Dec 04, 2020 at 10:43:35AM -0600, Glenn Washburn wrote:
> Use the slot key name in the json array rather than the 0 based index in the
> json array for keyslots, segments, and digests. This is less confusing for
> the end user. For example, say you have a LUKS2 device with a key in slot 1
> and slot 4. When using the password for slot 4 to unlock the device, the
> messages using the index of the keyslot will mention keyslot 1 (its a
> zero-based index). Furthermore, with this change the keyslot number will
> align with the number used to reference the keyslot when using the
> --key-slot argument to cryptsetup.
>
> Signed-off-by: Glenn Washburn 
> ---
>  grub-core/disk/luks2.c | 20 ++--
>  1 file changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
> index 437c1da07..ea1065bcf 100644
> --- a/grub-core/disk/luks2.c
> +++ b/grub-core/disk/luks2.c
> @@ -284,13 +284,13 @@ luks2_get_keyslot (grub_luks2_keyslot_t *k, 
> grub_luks2_digest_t *d, grub_luks2_s
> grub_json_getuint64 (>json_slot_key, , NULL) ||
>grub_json_getchild (, , 0) ||
>luks2_parse_digest (d, ))
> - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not parse digest 
> %"PRIuGRUB_SIZE, i);
> + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not parse digest index 
> %"PRIuGRUB_SIZE, i);

Does not this change belong to next patch?

>if ((d->keyslots & (1 << k->json_slot_key)))
>   break;
>  }
>if (i == size)
> -  return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No digest for keyslot 
> %"PRIuGRUB_SIZE, keyslot_idx);
> +  return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No digest for keyslot 
> \"%"PRIuGRUB_UINT64_T"\"", k->slot_key);

I am afraid this does not build. The slot_key seems a remnant from v6.

>/* Get segment that matches the digest. */
>if (grub_json_getvalue (, root, "segments") ||
> @@ -308,7 +308,7 @@ luks2_get_keyslot (grub_luks2_keyslot_t *k, 
> grub_luks2_digest_t *d, grub_luks2_s
>   break;
>  }
>if (i == size)
> -return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No segment for digest 
> %"PRIuGRUB_SIZE);
> +return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No segment for digest 
> \"%"PRIuGRUB_UINT64_T"\"", d->slot_key);

Ditto and below...

>return GRUB_ERR_NONE;
>  }
> @@ -604,11 +604,11 @@ luks2_recover_key (grub_disk_t source,
>
>if (keyslot.priority == 0)
>   {
> -   grub_dprintf ("luks2", "Ignoring keyslot %"PRIuGRUB_SIZE" due to 
> priority\n", i);
> +   grub_dprintf ("luks2", "Ignoring keyslot \"%"PRIuGRUB_UINT64_T"\" due 
> to priority\n", keyslot.slot_key);
> continue;
>  }
>
> -  grub_dprintf ("luks2", "Trying keyslot %"PRIuGRUB_SIZE"\n", i);
> +  grub_dprintf ("luks2", "Trying keyslot \"%"PRIuGRUB_UINT64_T"\"\n", 
> keyslot.slot_key);
>
>/* Set up disk according to keyslot's segment. */
>crypt->offset_sectors = grub_divmod64 (segment.offset, 
> segment.sector_size, NULL);
> @@ -623,16 +623,16 @@ luks2_recover_key (grub_disk_t source,
>  (const grub_uint8_t *) passphrase, grub_strlen 
> (passphrase));
>if (ret)
>   {
> -   grub_dprintf ("luks2", "Decryption with keyslot %"PRIuGRUB_SIZE" 
> failed: %s\n",
> - i, grub_errmsg);
> +   grub_dprintf ("luks2", "Decryption with keyslot 
> \"%"PRIuGRUB_UINT64_T"\" failed: %s\n",
> + keyslot.slot_key, grub_errmsg);
> continue;
>   }
>
>ret = luks2_verify_key (, candidate_key, keyslot.key_size);
>if (ret)
>   {
> -   grub_dprintf ("luks2", "Could not open keyslot %"PRIuGRUB_SIZE": 
> %s\n",
> - i, grub_errmsg);
> +   grub_dprintf ("luks2", "Could not open keyslot 
> \"%"PRIuGRUB_UINT64_T"\": %s\n",
> + keyslot.slot_key, grub_errmsg);
> continue;
>   }
>
> @@ -640,7 +640,7 @@ luks2_recover_key (grub_disk_t source,
> * TRANSLATORS: It's a cryptographic key slot: one element of an array
> * where each element is either empty or holds a key.
> */
> -  grub_printf_ (N_("Slot %"PRIuGRUB_SIZE" opened\n"), i);
> +  grub_printf_ (N_("Slot \"%"PRIuGRUB_UINT64_T"\" opened\n"), 
> keyslot.slot_key);
>
>candidate_key_len = keyslot.key_size;
>break;

Daniel

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v7 05/17] luks2: Add json_slot_key member to struct grub_luks2_keyslot/segment/digest

2020-12-07 Thread Daniel Kiper
On Sun, Dec 06, 2020 at 02:29:06PM +0100, Patrick Steinhardt wrote:
> On Fri, Dec 04, 2020 at 10:43:34AM -0600, Glenn Washburn wrote:
> > This allows code using these structs to know the named key associated with
> > these json data structures. In the future we can use these to provide better
> > error messages to the user.
> >
> > Get rid of idx variable in luks2_get_keyslot() which was overloaded to be
> > used for both keyslot and segment slot keys.
> >
> > Signed-off-by: Glenn Washburn 
>
> Personally, I'd have named them `json_slot_idx`. But you've already done
> so much work on improving the code that I don't want this to be the
> reason to not give an SOB, especially considering that it's a strict
> improvement anyway. So:
>
> Signed-off-by: Patrick Steinhardt 

I can change this to json_slot_idx before committing if Glenn does not
object. Otherwise Reviewed-by: Daniel Kiper 

Daniel

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v7 04/17] luks2: Make sure all fields of output argument in luks2_parse_digest() are written to

2020-12-07 Thread Daniel Kiper
On Fri, Dec 04, 2020 at 10:43:33AM -0600, Glenn Washburn wrote:
> We should assume that the output argument "out" is uninitialized and could
> have random data. So, make sure to initialize the segments and keyslots bit
> fields because potentially not all bits of those fields are written to.
> Otherwise, the digest could say it belongs to keyslots and segments that it
> does not.
>
> Signed-off-by: Glenn Washburn 

Reviewed-by: Daniel Kiper 

Daniel

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v7 03/17] luks2: Remove unused argument in grub_error

2020-12-07 Thread Daniel Kiper
On Fri, Dec 04, 2020 at 10:43:32AM -0600, Glenn Washburn wrote:
> Reviewed-by: Daniel Kiper 
> Signed-off-by: Glenn Washburn 

Nit, my RB should be after your SOB. I will fix it.

Daniel

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v7 02/17] misc: Add parentheses around ALIGN_UP and ALIGN_DOWN arguments

2020-12-07 Thread Daniel Kiper
On Fri, Dec 04, 2020 at 10:43:31AM -0600, Glenn Washburn wrote:
> This ensures that expected order of operations is preserved when arguments
> are expressions.
>
> Signed-off-by: Glenn Washburn 

Good catch! Reviewed-by: Daniel Kiper 

Daniel

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v7 01/17] disk: Rename grub_disk_get_size to grub_disk_native_sectors

2020-12-07 Thread Daniel Kiper
On Fri, Dec 04, 2020 at 10:43:30AM -0600, Glenn Washburn wrote:
> The function grub_disk_get_size is confusingly named because it actually
> returns a sector count where the sectors are sized in the grub native sector
> size. Rename to something more appropriate.
>
> Suggested-by: Daniel Kiper 
>

Nit, please do not leave empty lines between the tags.
I will fix it before committing.

> Signed-off-by: Glenn Washburn 

Otherwise Reviewed-by: Daniel Kiper 

Daniel

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCHv2] grub-install: Add backup and restore

2020-12-07 Thread Colin Watson
On Mon, Dec 07, 2020 at 12:37:28PM +, Dimitri John Ledkov wrote:
> Refactor clean_grub_dir to create a backup of all the files, instead
> of just irrevocably removing them as the first action. If available,
> register on_exit handle to restore the backup if any errors occur, or
> remove the backup if everything was successful. If on_exit is not
> available, the backup remains on disk for manual recovery.

Reviewed-by: Colin Watson 

-- 
Colin Watson (he/him)  [cjwat...@debian.org]

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCHv2] grub-install: Add backup and restore

2020-12-07 Thread Dimitri John Ledkov
Refactor clean_grub_dir to create a backup of all the files, instead
of just irrevocably removing them as the first action. If available,
register on_exit handle to restore the backup if any errors occur, or
remove the backup if everything was successful. If on_exit is not
available, the backup remains on disk for manual recovery.

This allows safer upgrades of MBR & modules, such that
modules/images/fonts/translations are consistent with MBR in case of
errors. For example accidental grub-install /dev/non-existent-disk
currently clobbers and upgrades modules in /boot/grub, despite not
actually updating any MBR. This increases peak disk-usage slightly, by
requiring temporarily twice the disk space to complete grub-install.

Also add modinfo.sh to the cleanup/backup/restore codepath, to ensure
it is also cleaned / backed up / restored.

Signed-off-by: Dimitri John Ledkov 
---

 Changes since v1: as reported on linux-ext4 mailing list and debugged
 by Colin Watson, the grub_util_path_concat_ext call was incorrect in
 the restore backup case as there was no extention needed. Instead the
 call is corrected to just grub_util_path_concat.

 This patch is now shipped in Ubuntu & Debian in multiple series. It
 would be nice to have this merged upstream, as it greatly improves
 grub upgrades and prevents missmatches of MBR & modules.

 configure.ac   |   2 +-
 util/grub-install-common.c | 105 +++--
 2 files changed, 91 insertions(+), 16 deletions(-)

diff --git a/configure.ac b/configure.ac
index 7c10a4db7..71cd414c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -419,7 +419,7 @@ else
 fi
 
 # Check for functions and headers.
-AC_CHECK_FUNCS(posix_memalign memalign getextmntent)
+AC_CHECK_FUNCS(posix_memalign memalign getextmntent on_exit)
 AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h limits.h)
 
 # glibc 2.25 still includes sys/sysmacros.h in sys/types.h but emits 
deprecation
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
index 277eaf4e2..74584b92b 100644
--- a/util/grub-install-common.c
+++ b/util/grub-install-common.c
@@ -185,38 +185,113 @@ grub_install_mkdir_p (const char *dst)
   free (t);
 }
 
+static int
+strcmp_ext (const char *a, const char *b, const char *ext)
+{
+  char *bsuffix = grub_util_path_concat_ext (1, b, ext);
+  int r = strcmp (a, bsuffix);
+  free (bsuffix);
+  return r;
+}
+
+enum clean_grub_dir_mode
+{
+  CLEAN = 0,
+  CLEAN_BACKUP = 1,
+  CREATE_BACKUP = 2,
+  RESTORE_BACKUP = 3,
+};
+
 static void
-clean_grub_dir (const char *di)
+clean_grub_dir_real (const char *di, enum clean_grub_dir_mode mode)
 {
   grub_util_fd_dir_t d;
   grub_util_fd_dirent_t de;
+  char suffix[2] = "";
+
+  if ((mode == CLEAN_BACKUP) || (mode == RESTORE_BACKUP))
+{
+  strcpy (suffix, "-");
+}
 
   d = grub_util_fd_opendir (di);
   if (!d)
-grub_util_error (_("cannot open directory `%s': %s"),
-di, grub_util_fd_strerror ());
+{
+  if (mode == CLEAN_BACKUP)
+   return;
+  grub_util_error (_("cannot open directory `%s': %s"),
+  di, grub_util_fd_strerror ());
+}
 
   while ((de = grub_util_fd_readdir (d)))
 {
   const char *ext = strrchr (de->d_name, '.');
-  if ((ext && (strcmp (ext, ".mod") == 0
-  || strcmp (ext, ".lst") == 0
-  || strcmp (ext, ".img") == 0
-  || strcmp (ext, ".mo") == 0)
-  && strcmp (de->d_name, "menu.lst") != 0)
- || strcmp (de->d_name, "efiemu32.o") == 0
- || strcmp (de->d_name, "efiemu64.o") == 0)
+  if ((ext && (strcmp_ext (ext, ".mod", suffix) == 0
+  || strcmp_ext (ext, ".lst", suffix) == 0
+  || strcmp_ext (ext, ".img", suffix) == 0
+  || strcmp_ext (ext, ".mo", suffix) == 0)
+  && strcmp_ext (de->d_name, "menu.lst", suffix) != 0)
+ || strcmp_ext (de->d_name, "modinfo.sh", suffix) == 0
+ || strcmp_ext (de->d_name, "efiemu32.o", suffix) == 0
+ || strcmp_ext (de->d_name, "efiemu64.o", suffix) == 0)
{
- char *x = grub_util_path_concat (2, di, de->d_name);
- if (grub_util_unlink (x) < 0)
-   grub_util_error (_("cannot delete `%s': %s"), x,
-grub_util_fd_strerror ());
- free (x);
+ char *srcf = grub_util_path_concat (2, di, de->d_name);
+
+ if (mode == CREATE_BACKUP)
+   {
+ char *dstf = grub_util_path_concat_ext (2, di, de->d_name, "-");
+ if (grub_util_rename (srcf, dstf) < 0)
+   grub_util_error (_("cannot backup `%s': %s"), srcf,
+grub_util_fd_strerror ());
+ free (dstf);
+   }
+ else if (mode == RESTORE_BACKUP)
+   {
+ char *dstf = grub_util_path_concat (2, di, de->d_name);
+ dstf[strlen (dstf) - 1] = 0;
+ if (grub_util_rename (srcf, dstf) < 0)
+