On 5/21/20 12:08 PM, Eric Biggers wrote: > On Thu, May 21, 2020 at 11:24:34AM -0400, Jes Sorensen wrote: >> Eric, >> >> Here is a more detailed review. The code as we have it seems to work for >> me, but there are some issues that I think would be right to address: > > Thanks for the feedback! > >> >> I appreciate that you improved the error return values from the original >> true/false/assert handling. >> >> As much as I hate typedefs, I also like the introduction of >> libfsverity_read_fn_t as function pointers are somewhat annoying to deal >> with. >> >> My biggest objection is the export of kernel datatypes to userland and I >> really don't think using u32/u16/u8 internally in the library adds any >> value. I had explicitly converted it to uint32_t/uint16_t/uint8_t in my >> version. > > I prefer u64/u32/u16/u8 since they're shorter and easier to read, and it's the > same convention that is used in the kernel code (which is where the other half > of fs-verity is). I like them too, but I tend to live in kernel space. > Note that these types aren't "exported" to or from anywhere but rather are just > typedefs in common/common_defs.h. It's just a particular convention. > > Also, fsverity-utils is already using this convention prior to this patchset. > If we did decide to change it, then we should change it in all the code, not > just in certain places. I thought I did it everywhere in my patch set? >> I also wonder if we should introduce an >> libfsverity_get_digest_size(alg_nr) function? It would be useful for a >> caller trying to allocate buffers to store them in, to be able to do >> this prior to calculating the first digest. > > That already exists; it's called libfsverity_digest_size(). > > Would it be clearer if we renamed: > > libfsverity_digest_size() => libfsverity_get_digest_size() > libfsverity_hash_name() => libfsverity_get_hash_name() Oh I missed you added that. Probably a good idea to rename them for consistency. >>> diff --git a/lib/compute_digest.c b/lib/compute_digest.c >>> index b279d63..13998bb 100644 >>> --- a/lib/compute_digest.c >>> +++ b/lib/compute_digest.c >>> @@ -1,13 +1,13 @@ >> ... snip ... >>> -const struct fsverity_hash_alg *find_hash_alg_by_name(const char *name) >>> +LIBEXPORT u32 >>> +libfsverity_find_hash_alg_by_name(const char *name) >> >> This export of u32 here is problematic. > > It's not "exported"; this is a .c file. As long as we use the stdint.h name in > libfsverity.h (to avoid polluting the library user's namespace), it is okay. > u32 and uint32_t are compatible; they're just different names for the same type. I would still keep it consistent avoid relying on assumptions that types are identical. >>> +struct fsverity_signed_digest { >>> + char magic[8]; /* must be "FSVerity" */ >>> + __le16 digest_algorithm; >>> + __le16 digest_size; >>> + __u8 digest[]; >>> +}; >> >> I don't really understand why you prefer to manage two versions of the >> digest, ie. libfsverity_digest and libfsverity_signed_digest, but it's >> not a big deal. > > Because fsverity_signed_digest has a specific endianness, people will access the > fields directly and forget to do the needed endianness conventions -- thus > producing code that doesn't work on big endian systems. Using a > native-endianness type for the intermediate struct avoids that pitfall. > > I think keeping the byte order handling internal to the library is preferable. Fair enough >>> +static void *xmalloc(size_t size) >>> +{ >>> + void *p = malloc(size); >>> + >>> + if (!p) >>> + libfsverity_error_msg("out of memory"); >>> + return p; >>> +} >>> + >>> +void *libfsverity_zalloc(size_t size) >>> +{ >>> + void *p = xmalloc(size); >>> + >>> + if (!p) >>> + return NULL; >>> + return memset(p, 0, size); >>> +} >> >> I suggest we get rid of xmalloc() and libfsverity_zalloc(). libc >> provides perfectly good malloc() and calloc() functions, and printing an >> out of memory error in a generic location doesn't tell us where the >> error happened. If anything those error messages should be printed by >> the calling function IMO. >> > > Maybe. I'm not sure knowing the specific allocation sites would be useful > enough to make all the callers handle printing the error message (which is > easily forgotten about). We could also add the allocation size that failed to > the message here. My point is mostly at this point, this just adds code obfuscation rather than adding real value. I can see how it was useful during initial development. Cheers, Jes