Re: [PATCH ima-evm-utils v5 02/17] log and reset 'errno' after failure to open non-critical files

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 2022-11-04 at 01:35 +0300, Vitaly Chikunov wrote:
> On Fri, Nov 04, 2022 at 01:24:21AM +0300, Vitaly Chikunov wrote:
> > On Fri, Nov 04, 2022 at 01:05:31AM +0300, Vitaly Chikunov wrote:
> > > Mimi,
> > > 
> > > On Thu, Nov 03, 2022 at 02:38:49PM -0400, Mimi Zohar wrote:
> > > > Define a log_errno_reset macro to emit the errno string at or near the
> > > > time of error, similar to the existing log_errno macro, but also reset
> > > > errno to avoid dangling or duplicate errno messages on exit.
> > > > 
> > > > The initial usage is for non-critical file open failures.
> > > > 
> > > > Suggested-by: Vitaly Chikunov <vt@xxxxxxxxxxxx>
> > > > Signed-off-by: Mimi Zohar <zohar@xxxxxxxxxxxxx>
> > > > ---
> > > >  src/evmctl.c | 12 ++++++++++--
> > > >  1 file changed, 10 insertions(+), 2 deletions(-)
> > > 
> > > Reviewed-by: Vitaly Chikunov <vt@xxxxxxxxxxxx>

Thanks!

> > > 
> > > > 
> > > > diff --git a/src/evmctl.c b/src/evmctl.c
> > > > index 0412bc0ac2b0..54123bf20f03 100644
> > > > --- a/src/evmctl.c
> > > > +++ b/src/evmctl.c
> > > > @@ -2055,7 +2060,6 @@ static int ima_measurement(const char *file)
> > > >  	int err_padded = -1;
> > > >  	int err = -1;
> > > >  
> > > > -	errno = 0;
> > > >  	memset(zero, 0, MAX_DIGEST_SIZE);
> > > >  
> > > >  	pseudo_padded_banks = init_tpm_banks(&num_banks);
> > > > @@ -2072,6 +2076,8 @@ static int ima_measurement(const char *file)
> > > >  		init_public_keys(imaevm_params.keyfile);
> > > >  	else				/* assume read pubkey from x509 cert */
> > > >  		init_public_keys("/etc/keys/x509_evm.der");
> > > > +	if (errno)
> > > > +		log_errno_reset(LOG_DEBUG, "Failed to initialize public keys");
> > > 
> > > Library prints appropriate error messages, so this is perhaps just to
> > > clear errno. But it's not necessarily completely failed, but maybe
> > > failure in one key. So I would say "Failure in initializing public
> > > keys" to be precise.
> > > 
> > > ps.
> > > 
> > > BTW, init_public_keys API call cannot return error except by errno,
> > > but it does not set it consistently so some errors may be missed.
> > > 
> > > init_public_keys loops calling read_pub_pkey
> > > 
> > >                 entry->key = read_pub_pkey(keyfile, 1);
> > >                 if (!entry->key) {
> > >                         free(entry);
> > >                         continue;
> > >                 }
> > > 
> > > and read_pub_pkey have such code:
> > > 
> > >         if (!keyfile)
> > >                 return NULL;
> > > 
> > > In that case some key is not read but we don't get any error notification.
> > > 
> > > I think it's legal, by the right of being library, so set `errno =
> > > EINVAL` there somewhere. But, I'm not sure where - as we should not
> > > clobber existing errno values. Perhaps, errno setting should be added to
> > > libimaevm consistently to all functions, but this is huge task, so I
> > > would not suggest to do it now. Just suggestion for the future
> > > developments, maybe.
> > 
> > Just to compare with other library - libtracefs sets errno _sometimes_,
> 
> It "is not consistent" in the sense that error in the API call does not
> have always errno set. And this is unlike we have for common libc API
> calls where errno is defined. (As a consequence we cannot just add
> strerror() to the printing errors from these APIs).
> 
> But, it's not necessarily there is standard or common practice about
> this matter.

The perror() man page seems to say that it is optional, but doesn't say
anything about libraries being self-consistent:  "When system call
fails, it usually returns -1 and sets the variable errno to a value
describing what went wrong.  (These values can be found in
<errno.h>.)  Many library functions do likewise."

> 
> 
> > for example, their API call tracefs_dynevent_get have:
> > 
> >   struct tracefs_dynevent *
> >   tracefs_dynevent_get(enum tracefs_dynevent_type type, const char *system,
> > 		       const char *event)
> >   {
> >   ...
> > 	  if (!event) {
> > 		  errno = -EINVAL;
> > 		  return NULL;
> > 	  }
> > 
> > 	  count = get_all_dynevents(type, system, &events);
> > 	  if (count <= 0)
> > 		  return NULL;
> >   ...
> > 
> > So it sets errno sometimes, but not always, which I am not sure is correct
> > approach. This needs to be discussed more with library experts.

Perhaps this isn't a question of self-consistency, but of who is
setting errno.  In the tracefs_dynevent_get() case, nothing else is
being called, so nothing could have set errno.  In the
get_all_dynevents() case, without looking at the code, something could
have already set errno.

As for the ima-evm-utils example, I agree read_pub_pkey() should return
-EINVAL when keyfile is NULL.  init_public_keys() verifies keyfile is
not NULL before calling read_pub_pkey(), so read_pub_pkey() returning
-EINVAL, shouldn't affect it.

-- 
Thanks,

Mimi




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux Kernel]     [Linux Kernel Hardening]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux