diff mbox series

[fsverity-utils,v2,2/2] Allow to build and run sign/digest on Windows

Message ID 20201217144749.647533-2-luca.boccassi@gmail.com (mailing list archive)
State Superseded
Headers show
Series [fsverity-utils,v2,1/2] Remove unneeded includes | expand

Commit Message

Luca Boccassi Dec. 17, 2020, 2:47 p.m. UTC
From: Luca Boccassi <luca.boccassi@microsoft.com>

Add some minimal compat type defs, and stub out the enable/measure
sources. Also add a way to handle the fact that mingw adds a
.exe extension automatically in the Makefile install rules, and
that there is not pkg-config and the libcrypto linker flag is
different.

Signed-off-by: Luca Boccassi <luca.boccassi@microsoft.com>
---
v2: rework the stubbing out to detect mingw in the Makefile and remove
    sources from compilation, instead of ifdefs.
    add a new common/win32_defs.h for the compat definitions.
    define strerror_r using strerror_s.

    To compile with mingw:
      make CC=x86_64-w64-mingw32-gcc-8.3-win32
    note that the openssl headers and a win32 libcrypto.dll need
    to be available in the default search paths, and otherwise have
    to be specified as expected via CPPFLAGS/LDFLAGS

 Makefile               | 36 ++++++++++++++++++-------
 common/common_defs.h   |  2 ++
 common/fsverity_uapi.h |  2 ++
 common/win32_defs.h    | 61 ++++++++++++++++++++++++++++++++++++++++++
 lib/utils.c            | 11 +++++++-
 programs/fsverity.c    |  2 ++
 programs/utils.c       |  2 +-
 7 files changed, 105 insertions(+), 11 deletions(-)
 create mode 100644 common/win32_defs.h

Comments

Eric Biggers Dec. 17, 2020, 6:32 p.m. UTC | #1
On Thu, Dec 17, 2020 at 02:47:49PM +0000, luca.boccassi@gmail.com wrote:
> From: Luca Boccassi <luca.boccassi@microsoft.com>
> 
> Add some minimal compat type defs, and stub out the enable/measure
> sources. Also add a way to handle the fact that mingw adds a
> .exe extension automatically in the Makefile install rules, and
> that there is not pkg-config and the libcrypto linker flag is
> different.
> 
> Signed-off-by: Luca Boccassi <luca.boccassi@microsoft.com>
> ---
> v2: rework the stubbing out to detect mingw in the Makefile and remove
>     sources from compilation, instead of ifdefs.
>     add a new common/win32_defs.h for the compat definitions.
>     define strerror_r using strerror_s.
> 
>     To compile with mingw:
>       make CC=x86_64-w64-mingw32-gcc-8.3-win32
>     note that the openssl headers and a win32 libcrypto.dll need
>     to be available in the default search paths, and otherwise have
>     to be specified as expected via CPPFLAGS/LDFLAGS
> 

I got some warnings and an error when compiling:

$ make CC=x86_64-w64-mingw32-gcc
  CC       lib/compute_digest.o
  CC       lib/hash_algs.o
  CC       lib/sign_digest.o
  CC       lib/utils.o
lib/utils.c: In function ‘xmalloc’:
lib/utils.c:25:25: warning: unknown conversion type character ‘l’ in format [-Wformat=]
   25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from lib/../common/win32_defs.h:24,
                 from lib/../common/common_defs.h:18,
                 from lib/lib_private.h:15,
                 from lib/utils.c:14:
/usr/x86_64-w64-mingw32/include/inttypes.h:36:18: note: format string is defined here
   36 | #define PRIu64 "llu"
      |                  ^
lib/utils.c:25:25: warning: too many arguments for format [-Wformat-extra-args]
   25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  AR       libfsverity.a
  CC       lib/compute_digest.shlib.o
  CC       lib/hash_algs.shlib.o
  CC       lib/sign_digest.shlib.o
  CC       lib/utils.shlib.o
lib/utils.c: In function ‘xmalloc’:
lib/utils.c:25:25: warning: unknown conversion type character ‘l’ in format [-Wformat=]
   25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from lib/../common/win32_defs.h:24,
                 from lib/../common/common_defs.h:18,
                 from lib/lib_private.h:15,
                 from lib/utils.c:14:
/usr/x86_64-w64-mingw32/include/inttypes.h:36:18: note: format string is defined here
   36 | #define PRIu64 "llu"
      |                  ^
lib/utils.c:25:25: warning: too many arguments for format [-Wformat-extra-args]
   25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  CCLD     libfsverity.so.0
/usr/lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -l:libcrypto.dll
collect2: error: ld returned 1 exit status
make: *** [Makefile:137: libfsverity.so.0] Error 1



This is on Arch Linux with mingw-w64-gcc and mingw-w64-openssl installed.

So there's something wrong with the SIZET_PF format string, and also
-l:libcrypto.dll isn't correct; it should be just -lcrypto like it is on Linux.
(MinGW knows to look for a .dll file.)

- Eric
Luca Boccassi Dec. 17, 2020, 6:44 p.m. UTC | #2
On Thu, 2020-12-17 at 10:32 -0800, Eric Biggers wrote:
> On Thu, Dec 17, 2020 at 02:47:49PM +0000, luca.boccassi@gmail.com wrote:
> > From: Luca Boccassi <luca.boccassi@microsoft.com>
> > 
> > Add some minimal compat type defs, and stub out the enable/measure
> > sources. Also add a way to handle the fact that mingw adds a
> > .exe extension automatically in the Makefile install rules, and
> > that there is not pkg-config and the libcrypto linker flag is
> > different.
> > 
> > Signed-off-by: Luca Boccassi <luca.boccassi@microsoft.com>
> > ---
> > v2: rework the stubbing out to detect mingw in the Makefile and remove
> >     sources from compilation, instead of ifdefs.
> >     add a new common/win32_defs.h for the compat definitions.
> >     define strerror_r using strerror_s.
> > 
> >     To compile with mingw:
> >       make CC=x86_64-w64-mingw32-gcc-8.3-win32
> >     note that the openssl headers and a win32 libcrypto.dll need
> >     to be available in the default search paths, and otherwise have
> >     to be specified as expected via CPPFLAGS/LDFLAGS
> > 
> 
> I got some warnings and an error when compiling:
> 
> $ make CC=x86_64-w64-mingw32-gcc
>   CC       lib/compute_digest.o
>   CC       lib/hash_algs.o
>   CC       lib/sign_digest.o
>   CC       lib/utils.o
> lib/utils.c: In function ‘xmalloc’:
> lib/utils.c:25:25: warning: unknown conversion type character ‘l’ in format [-Wformat=]
>    25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
>       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> In file included from lib/../common/win32_defs.h:24,
>                  from lib/../common/common_defs.h:18,
>                  from lib/lib_private.h:15,
>                  from lib/utils.c:14:
> /usr/x86_64-w64-mingw32/include/inttypes.h:36:18: note: format string is defined here
>    36 | #define PRIu64 "llu"
>       |                  ^
> lib/utils.c:25:25: warning: too many arguments for format [-Wformat-extra-args]
>    25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
>       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>   AR       libfsverity.a
>   CC       lib/compute_digest.shlib.o
>   CC       lib/hash_algs.shlib.o
>   CC       lib/sign_digest.shlib.o
>   CC       lib/utils.shlib.o
> lib/utils.c: In function ‘xmalloc’:
> lib/utils.c:25:25: warning: unknown conversion type character ‘l’ in format [-Wformat=]
>    25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
>       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> In file included from lib/../common/win32_defs.h:24,
>                  from lib/../common/common_defs.h:18,
>                  from lib/lib_private.h:15,
>                  from lib/utils.c:14:
> /usr/x86_64-w64-mingw32/include/inttypes.h:36:18: note: format string is defined here
>    36 | #define PRIu64 "llu"
>       |                  ^
> lib/utils.c:25:25: warning: too many arguments for format [-Wformat-extra-args]
>    25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
>       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>   CCLD     libfsverity.so.0
> /usr/lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -l:libcrypto.dll
> collect2: error: ld returned 1 exit status
> make: *** [Makefile:137: libfsverity.so.0] Error 1
> 
> 
> 
> This is on Arch Linux with mingw-w64-gcc and mingw-w64-openssl installed.
> 
> So there's something wrong with the SIZET_PF format string, and also
> -l:libcrypto.dll isn't correct; it should be just -lcrypto like it is on Linux.
> (MinGW knows to look for a .dll file.)
> 
> - Eric

Mmh I don't get any warnings on Debian - gcc-mingw-w64-x86-64 8.3.0-
6+21.3~deb10u1 - any idea how to fix it?

And on -lcrypto, it didn't use to work before the refactor - but now it
does. I have no clue what was happening. Will change it back in v3.
Eric Biggers Dec. 17, 2020, 7:05 p.m. UTC | #3
On Thu, Dec 17, 2020 at 06:44:38PM +0000, Luca Boccassi wrote:
> On Thu, 2020-12-17 at 10:32 -0800, Eric Biggers wrote:
> > On Thu, Dec 17, 2020 at 02:47:49PM +0000, luca.boccassi@gmail.com wrote:
> > > From: Luca Boccassi <luca.boccassi@microsoft.com>
> > > 
> > > Add some minimal compat type defs, and stub out the enable/measure
> > > sources. Also add a way to handle the fact that mingw adds a
> > > .exe extension automatically in the Makefile install rules, and
> > > that there is not pkg-config and the libcrypto linker flag is
> > > different.
> > > 
> > > Signed-off-by: Luca Boccassi <luca.boccassi@microsoft.com>
> > > ---
> > > v2: rework the stubbing out to detect mingw in the Makefile and remove
> > >     sources from compilation, instead of ifdefs.
> > >     add a new common/win32_defs.h for the compat definitions.
> > >     define strerror_r using strerror_s.
> > > 
> > >     To compile with mingw:
> > >       make CC=x86_64-w64-mingw32-gcc-8.3-win32
> > >     note that the openssl headers and a win32 libcrypto.dll need
> > >     to be available in the default search paths, and otherwise have
> > >     to be specified as expected via CPPFLAGS/LDFLAGS
> > > 
> > 
> > I got some warnings and an error when compiling:
> > 
> > $ make CC=x86_64-w64-mingw32-gcc
> >   CC       lib/compute_digest.o
> >   CC       lib/hash_algs.o
> >   CC       lib/sign_digest.o
> >   CC       lib/utils.o
> > lib/utils.c: In function ‘xmalloc’:
> > lib/utils.c:25:25: warning: unknown conversion type character ‘l’ in format [-Wformat=]
> >    25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
> >       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > In file included from lib/../common/win32_defs.h:24,
> >                  from lib/../common/common_defs.h:18,
> >                  from lib/lib_private.h:15,
> >                  from lib/utils.c:14:
> > /usr/x86_64-w64-mingw32/include/inttypes.h:36:18: note: format string is defined here
> >    36 | #define PRIu64 "llu"
> >       |                  ^
> > lib/utils.c:25:25: warning: too many arguments for format [-Wformat-extra-args]
> >    25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
> >       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >   AR       libfsverity.a
> >   CC       lib/compute_digest.shlib.o
> >   CC       lib/hash_algs.shlib.o
> >   CC       lib/sign_digest.shlib.o
> >   CC       lib/utils.shlib.o
> > lib/utils.c: In function ‘xmalloc’:
> > lib/utils.c:25:25: warning: unknown conversion type character ‘l’ in format [-Wformat=]
> >    25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
> >       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > In file included from lib/../common/win32_defs.h:24,
> >                  from lib/../common/common_defs.h:18,
> >                  from lib/lib_private.h:15,
> >                  from lib/utils.c:14:
> > /usr/x86_64-w64-mingw32/include/inttypes.h:36:18: note: format string is defined here
> >    36 | #define PRIu64 "llu"
> >       |                  ^
> > lib/utils.c:25:25: warning: too many arguments for format [-Wformat-extra-args]
> >    25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
> >       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >   CCLD     libfsverity.so.0
> > /usr/lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -l:libcrypto.dll
> > collect2: error: ld returned 1 exit status
> > make: *** [Makefile:137: libfsverity.so.0] Error 1
> > 
> > 
> > 
> > This is on Arch Linux with mingw-w64-gcc and mingw-w64-openssl installed.
> > 
> > So there's something wrong with the SIZET_PF format string, and also
> > -l:libcrypto.dll isn't correct; it should be just -lcrypto like it is on Linux.
> > (MinGW knows to look for a .dll file.)
> > 
> > - Eric
> 
> Mmh I don't get any warnings on Debian - gcc-mingw-w64-x86-64 8.3.0-
> 6+21.3~deb10u1 - any idea how to fix it?
> 
> And on -lcrypto, it didn't use to work before the refactor - but now it
> does. I have no clue what was happening. Will change it back in v3.
> 

Apparently the definition of _GNU_SOURCE in lib/utils.c changes the printf
implementation that is used from Microsoft's to MinGW's, but the use of
__attribute__((format(printf))) is generating warnings assuming that Microsoft's
printf implementation is used.  Always defining _GNU_SOURCE and then using
__attribute__((format(gnu_printf))) might be the way to go:

diff --git a/Makefile b/Makefile
index cc62818..44aee92 100644
--- a/Makefile
+++ b/Makefile
@@ -52,7 +52,7 @@ override CFLAGS := -Wall -Wundef				\
 	$(call cc-option,-Wvla)					\
 	$(CFLAGS)
 
-override CPPFLAGS := -Iinclude -D_FILE_OFFSET_BITS=64 $(CPPFLAGS)
+override CPPFLAGS := -Iinclude -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $(CPPFLAGS)
 
 ifneq ($(V),1)
 QUIET_CC        = @echo '  CC      ' $@;
diff --git a/common/win32_defs.h b/common/win32_defs.h
index e13938a..4edb17f 100644
--- a/common/win32_defs.h
+++ b/common/win32_defs.h
@@ -37,6 +37,11 @@
 #  define __cold
 #endif
 
+#ifndef __printf
+#  define __printf(fmt_idx, vargs_idx) \
+	__attribute__((format(gnu_printf, fmt_idx, vargs_idx)))
+#endif
+
 typedef __signed__ char __s8;
 typedef unsigned char __u8;
 typedef __signed__ short __s16;
diff --git a/lib/utils.c b/lib/utils.c
index 8bb4413..55a4045 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -9,8 +9,6 @@
  * https://opensource.org/licenses/MIT.
  */
 
-#define _GNU_SOURCE /* for asprintf() and strerror_r() */
-
 #include "lib_private.h"
 
 #include <stdio.h>
Luca Boccassi Dec. 17, 2020, 7:12 p.m. UTC | #4
On Thu, 2020-12-17 at 11:05 -0800, Eric Biggers wrote:
> On Thu, Dec 17, 2020 at 06:44:38PM +0000, Luca Boccassi wrote:
> > On Thu, 2020-12-17 at 10:32 -0800, Eric Biggers wrote:
> > > On Thu, Dec 17, 2020 at 02:47:49PM +0000, luca.boccassi@gmail.com wrote:
> > > > From: Luca Boccassi <luca.boccassi@microsoft.com>
> > > > 
> > > > Add some minimal compat type defs, and stub out the enable/measure
> > > > sources. Also add a way to handle the fact that mingw adds a
> > > > .exe extension automatically in the Makefile install rules, and
> > > > that there is not pkg-config and the libcrypto linker flag is
> > > > different.
> > > > 
> > > > Signed-off-by: Luca Boccassi <luca.boccassi@microsoft.com>
> > > > ---
> > > > v2: rework the stubbing out to detect mingw in the Makefile and remove
> > > >     sources from compilation, instead of ifdefs.
> > > >     add a new common/win32_defs.h for the compat definitions.
> > > >     define strerror_r using strerror_s.
> > > > 
> > > >     To compile with mingw:
> > > >       make CC=x86_64-w64-mingw32-gcc-8.3-win32
> > > >     note that the openssl headers and a win32 libcrypto.dll need
> > > >     to be available in the default search paths, and otherwise have
> > > >     to be specified as expected via CPPFLAGS/LDFLAGS
> > > > 
> > > 
> > > I got some warnings and an error when compiling:
> > > 
> > > $ make CC=x86_64-w64-mingw32-gcc
> > >   CC       lib/compute_digest.o
> > >   CC       lib/hash_algs.o
> > >   CC       lib/sign_digest.o
> > >   CC       lib/utils.o
> > > lib/utils.c: In function ‘xmalloc’:
> > > lib/utils.c:25:25: warning: unknown conversion type character ‘l’ in format [-Wformat=]
> > >    25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
> > >       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > > In file included from lib/../common/win32_defs.h:24,
> > >                  from lib/../common/common_defs.h:18,
> > >                  from lib/lib_private.h:15,
> > >                  from lib/utils.c:14:
> > > /usr/x86_64-w64-mingw32/include/inttypes.h:36:18: note: format string is defined here
> > >    36 | #define PRIu64 "llu"
> > >       |                  ^
> > > lib/utils.c:25:25: warning: too many arguments for format [-Wformat-extra-args]
> > >    25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
> > >       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > >   AR       libfsverity.a
> > >   CC       lib/compute_digest.shlib.o
> > >   CC       lib/hash_algs.shlib.o
> > >   CC       lib/sign_digest.shlib.o
> > >   CC       lib/utils.shlib.o
> > > lib/utils.c: In function ‘xmalloc’:
> > > lib/utils.c:25:25: warning: unknown conversion type character ‘l’ in format [-Wformat=]
> > >    25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
> > >       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > > In file included from lib/../common/win32_defs.h:24,
> > >                  from lib/../common/common_defs.h:18,
> > >                  from lib/lib_private.h:15,
> > >                  from lib/utils.c:14:
> > > /usr/x86_64-w64-mingw32/include/inttypes.h:36:18: note: format string is defined here
> > >    36 | #define PRIu64 "llu"
> > >       |                  ^
> > > lib/utils.c:25:25: warning: too many arguments for format [-Wformat-extra-args]
> > >    25 |   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
> > >       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > >   CCLD     libfsverity.so.0
> > > /usr/lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -l:libcrypto.dll
> > > collect2: error: ld returned 1 exit status
> > > make: *** [Makefile:137: libfsverity.so.0] Error 1
> > > 
> > > 
> > > 
> > > This is on Arch Linux with mingw-w64-gcc and mingw-w64-openssl installed.
> > > 
> > > So there's something wrong with the SIZET_PF format string, and also
> > > -l:libcrypto.dll isn't correct; it should be just -lcrypto like it is on Linux.
> > > (MinGW knows to look for a .dll file.)
> > > 
> > > - Eric
> > 
> > Mmh I don't get any warnings on Debian - gcc-mingw-w64-x86-64 8.3.0-
> > 6+21.3~deb10u1 - any idea how to fix it?
> > 
> > And on -lcrypto, it didn't use to work before the refactor - but now it
> > does. I have no clue what was happening. Will change it back in v3.
> > 
> 
> Apparently the definition of _GNU_SOURCE in lib/utils.c changes the printf
> implementation that is used from Microsoft's to MinGW's, but the use of
> __attribute__((format(printf))) is generating warnings assuming that Microsoft's
> printf implementation is used.  Always defining _GNU_SOURCE and then using
> __attribute__((format(gnu_printf))) might be the way to go:
> 
> diff --git a/Makefile b/Makefile
> index cc62818..44aee92 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -52,7 +52,7 @@ override CFLAGS := -Wall -Wundef				\
>  	$(call cc-option,-Wvla)					\
>  	$(CFLAGS)
>  
> -override CPPFLAGS := -Iinclude -D_FILE_OFFSET_BITS=64 $(CPPFLAGS)
> +override CPPFLAGS := -Iinclude -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $(CPPFLAGS)
>  
>  ifneq ($(V),1)
>  QUIET_CC        = @echo '  CC      ' $@;
> diff --git a/common/win32_defs.h b/common/win32_defs.h
> index e13938a..4edb17f 100644
> --- a/common/win32_defs.h
> +++ b/common/win32_defs.h
> @@ -37,6 +37,11 @@
>  #  define __cold
>  #endif
>  
> +#ifndef __printf
> +#  define __printf(fmt_idx, vargs_idx) \
> +	__attribute__((format(gnu_printf, fmt_idx, vargs_idx)))
> +#endif
> +
>  typedef __signed__ char __s8;
>  typedef unsigned char __u8;
>  typedef __signed__ short __s16;
> diff --git a/lib/utils.c b/lib/utils.c
> index 8bb4413..55a4045 100644
> --- a/lib/utils.c
> +++ b/lib/utils.c
> @@ -9,8 +9,6 @@
>   * https://opensource.org/licenses/MIT.
>   */
>  
> -#define _GNU_SOURCE /* for asprintf() and strerror_r() */
> -
>  #include "lib_private.h"
>  
>  #include <stdio.h>

I get the following warning with the mingw build now:

lib/utils.c: In function ‘xmalloc’:
lib/utils.c:23:25: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘size_t’ {aka ‘long long unsigned int’} [-Wformat=]
   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           size);
           ~~~~           
In file included from lib/../common/win32_defs.h:24,
                 from lib/../common/common_defs.h:18,
                 from lib/lib_private.h:15,
                 from lib/utils.c:12:
/usr/share/mingw-w64/include/inttypes.h:94:20: note: format string is defined here
 #define PRIu64 "I64u"
  AR       libfsverity.a
  CC       lib/sign_digest.shlib.o
  CC       lib/compute_digest.shlib.o
  CC       lib/hash_algs.shlib.o
  CC       lib/utils.shlib.o
lib/utils.c: In function ‘xmalloc’:
lib/utils.c:23:25: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘size_t’ {aka ‘long long unsigned int’} [-Wformat=]
   libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           size);
           ~~~~           
In file included from lib/../common/win32_defs.h:24,
                 from lib/../common/common_defs.h:18,
                 from lib/lib_private.h:15,
                 from lib/utils.c:12:
/usr/share/mingw-w64/include/inttypes.h:94:20: note: format string is defined here
 #define PRIu64 "I64u"


But, honestly, it seems harmless to me. If someone on Windows is trying
to get a digest and don't have memory to do it, they'll have bigger
problems to worry about than knowing how much it was requested. I'll
send a v3 with your suggested changes. As far as I can read online,
handling %zu in a cross compatible way is like the number one
annoyance.
Eric Biggers Dec. 17, 2020, 7:20 p.m. UTC | #5
On Thu, Dec 17, 2020 at 07:12:06PM +0000, Luca Boccassi wrote:
> 
> I get the following warning with the mingw build now:
> 
> lib/utils.c: In function ‘xmalloc’:
> lib/utils.c:23:25: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘size_t’ {aka ‘long long unsigned int’} [-Wformat=]
>    libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
>                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>            size);
>            ~~~~           
> In file included from lib/../common/win32_defs.h:24,
>                  from lib/../common/common_defs.h:18,
>                  from lib/lib_private.h:15,
>                  from lib/utils.c:12:
> /usr/share/mingw-w64/include/inttypes.h:94:20: note: format string is defined here
>  #define PRIu64 "I64u"
>   AR       libfsverity.a
>   CC       lib/sign_digest.shlib.o
>   CC       lib/compute_digest.shlib.o
>   CC       lib/hash_algs.shlib.o
>   CC       lib/utils.shlib.o
> lib/utils.c: In function ‘xmalloc’:
> lib/utils.c:23:25: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘size_t’ {aka ‘long long unsigned int’} [-Wformat=]
>    libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
>                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>            size);
>            ~~~~           
> In file included from lib/../common/win32_defs.h:24,
>                  from lib/../common/common_defs.h:18,
>                  from lib/lib_private.h:15,
>                  from lib/utils.c:12:
> /usr/share/mingw-w64/include/inttypes.h:94:20: note: format string is defined here
>  #define PRIu64 "I64u"
> 
> 
> But, honestly, it seems harmless to me. If someone on Windows is trying
> to get a digest and don't have memory to do it, they'll have bigger
> problems to worry about than knowing how much it was requested. I'll
> send a v3 with your suggested changes. As far as I can read online,
> handling %zu in a cross compatible way is like the number one
> annoyance.
> 

It needs to compile without warnings, otherwise new warnings won't be noticed.

I think that if the MinGW printf is used (by defining _GNU_SOURCE), then %zu
would just work as-is.  That's what I do in another project.  Try:

diff --git a/Makefile b/Makefile
index cc62818..44aee92 100644
--- a/Makefile
+++ b/Makefile
@@ -52,7 +52,7 @@ override CFLAGS := -Wall -Wundef				\
 	$(call cc-option,-Wvla)					\
 	$(CFLAGS)
 
-override CPPFLAGS := -Iinclude -D_FILE_OFFSET_BITS=64 $(CPPFLAGS)
+override CPPFLAGS := -Iinclude -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $(CPPFLAGS)
 
 ifneq ($(V),1)
 QUIET_CC        = @echo '  CC      ' $@;
diff --git a/common/win32_defs.h b/common/win32_defs.h
index e13938a..3b0d908 100644
--- a/common/win32_defs.h
+++ b/common/win32_defs.h
@@ -23,12 +23,6 @@
 #include <stdint.h>
 #include <inttypes.h>
 
-#ifdef _WIN64
-#  define SIZET_PF PRIu64
-#else
-#  define SIZET_PF PRIu32
-#endif
-
 #ifndef ENOPKG
 #   define ENOPKG 65
 #endif
@@ -37,6 +31,11 @@
 #  define __cold
 #endif
 
+#ifndef __printf
+#  define __printf(fmt_idx, vargs_idx) \
+	__attribute__((format(gnu_printf, fmt_idx, vargs_idx)))
+#endif
+
 typedef __signed__ char __s8;
 typedef unsigned char __u8;
 typedef __signed__ short __s16;
@@ -52,10 +51,6 @@ typedef __u32 __be32;
 typedef __u64 __le64;
 typedef __u64 __be64;
 
-#else
-
-#define SIZET_PF "zu"
-
 #endif /* _WIN32 */
 
 #endif /* COMMON_WIN32_DEFS_H */
diff --git a/lib/utils.c b/lib/utils.c
index 8bb4413..036dd60 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -9,8 +9,6 @@
  * https://opensource.org/licenses/MIT.
  */
 
-#define _GNU_SOURCE /* for asprintf() and strerror_r() */
-
 #include "lib_private.h"
 
 #include <stdio.h>
@@ -22,7 +20,7 @@ static void *xmalloc(size_t size)
 	void *p = malloc(size);
 
 	if (!p)
-		libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
+		libfsverity_error_msg("out of memory (tried to allocate %zu bytes)",
 				      size);
 	return p;
 }

- Eric
Luca Boccassi Dec. 17, 2020, 7:26 p.m. UTC | #6
On Thu, 2020-12-17 at 11:20 -0800, Eric Biggers wrote:
> On Thu, Dec 17, 2020 at 07:12:06PM +0000, Luca Boccassi wrote:
> > I get the following warning with the mingw build now:
> > 
> > lib/utils.c: In function ‘xmalloc’:
> > lib/utils.c:23:25: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘size_t’ {aka ‘long long unsigned int’} [-Wformat=]
> >    libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
> >                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >            size);
> >            ~~~~           
> > In file included from lib/../common/win32_defs.h:24,
> >                  from lib/../common/common_defs.h:18,
> >                  from lib/lib_private.h:15,
> >                  from lib/utils.c:12:
> > /usr/share/mingw-w64/include/inttypes.h:94:20: note: format string is defined here
> >  #define PRIu64 "I64u"
> >   AR       libfsverity.a
> >   CC       lib/sign_digest.shlib.o
> >   CC       lib/compute_digest.shlib.o
> >   CC       lib/hash_algs.shlib.o
> >   CC       lib/utils.shlib.o
> > lib/utils.c: In function ‘xmalloc’:
> > lib/utils.c:23:25: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘size_t’ {aka ‘long long unsigned int’} [-Wformat=]
> >    libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
> >                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >            size);
> >            ~~~~           
> > In file included from lib/../common/win32_defs.h:24,
> >                  from lib/../common/common_defs.h:18,
> >                  from lib/lib_private.h:15,
> >                  from lib/utils.c:12:
> > /usr/share/mingw-w64/include/inttypes.h:94:20: note: format string is defined here
> >  #define PRIu64 "I64u"
> > 
> > 
> > But, honestly, it seems harmless to me. If someone on Windows is trying
> > to get a digest and don't have memory to do it, they'll have bigger
> > problems to worry about than knowing how much it was requested. I'll
> > send a v3 with your suggested changes. As far as I can read online,
> > handling %zu in a cross compatible way is like the number one
> > annoyance.
> > 
> 
> It needs to compile without warnings, otherwise new warnings won't be noticed.
> 
> I think that if the MinGW printf is used (by defining _GNU_SOURCE), then %zu
> would just work as-is.  That's what I do in another project.  Try:
> 
> diff --git a/Makefile b/Makefile
> index cc62818..44aee92 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -52,7 +52,7 @@ override CFLAGS := -Wall -Wundef				\
>  	$(call cc-option,-Wvla)					\
>  	$(CFLAGS)
>  
> -override CPPFLAGS := -Iinclude -D_FILE_OFFSET_BITS=64 $(CPPFLAGS)
> +override CPPFLAGS := -Iinclude -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $(CPPFLAGS)
>  
>  ifneq ($(V),1)
>  QUIET_CC        = @echo '  CC      ' $@;
> diff --git a/common/win32_defs.h b/common/win32_defs.h
> index e13938a..3b0d908 100644
> --- a/common/win32_defs.h
> +++ b/common/win32_defs.h
> @@ -23,12 +23,6 @@
>  #include <stdint.h>
>  #include <inttypes.h>
>  
> -#ifdef _WIN64
> -#  define SIZET_PF PRIu64
> -#else
> -#  define SIZET_PF PRIu32
> -#endif
> -
>  #ifndef ENOPKG
>  #   define ENOPKG 65
>  #endif
> @@ -37,6 +31,11 @@
>  #  define __cold
>  #endif
>  
> +#ifndef __printf
> +#  define __printf(fmt_idx, vargs_idx) \
> +	__attribute__((format(gnu_printf, fmt_idx, vargs_idx)))
> +#endif
> +
>  typedef __signed__ char __s8;
>  typedef unsigned char __u8;
>  typedef __signed__ short __s16;
> @@ -52,10 +51,6 @@ typedef __u32 __be32;
>  typedef __u64 __le64;
>  typedef __u64 __be64;
>  
> -#else
> -
> -#define SIZET_PF "zu"
> -
>  #endif /* _WIN32 */
>  
>  #endif /* COMMON_WIN32_DEFS_H */
> diff --git a/lib/utils.c b/lib/utils.c
> index 8bb4413..036dd60 100644
> --- a/lib/utils.c
> +++ b/lib/utils.c
> @@ -9,8 +9,6 @@
>   * https://opensource.org/licenses/MIT.
>   */
>  
> -#define _GNU_SOURCE /* for asprintf() and strerror_r() */
> -
>  #include "lib_private.h"
>  
>  #include <stdio.h>
> @@ -22,7 +20,7 @@ static void *xmalloc(size_t size)
>  	void *p = malloc(size);
>  
>  	if (!p)
> -		libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
> +		libfsverity_error_msg("out of memory (tried to allocate %zu bytes)",
>  				      size);
>  	return p;
>  }

That works, no more warnings, nice! Thank you! Sent v4.
diff mbox series

Patch

diff --git a/Makefile b/Makefile
index bfe83c4..cc62818 100644
--- a/Makefile
+++ b/Makefile
@@ -35,6 +35,11 @@ 
 cc-option = $(shell if $(CC) $(1) -c -x c /dev/null -o /dev/null > /dev/null 2>&1; \
 	      then echo $(1); fi)
 
+# Support building with MinGW for minimal Windows fsverity.exe
+ifneq ($(findstring -mingw,$(shell $(CC) -dumpmachine 2>/dev/null)),)
+MINGW = 1
+endif
+
 CFLAGS ?= -O2
 
 override CFLAGS := -Wall -Wundef				\
@@ -62,7 +67,14 @@  BINDIR          ?= $(PREFIX)/bin
 INCDIR          ?= $(PREFIX)/include
 LIBDIR          ?= $(PREFIX)/lib
 DESTDIR         ?=
+ifneq ($(MINGW),1)
 PKGCONF         ?= pkg-config
+LIBCRYPTO       := -lcrypto
+else
+PKGCONF         := false
+LIBCRYPTO       := -l:libcrypto.dll
+EXEEXT          := .exe
+endif
 
 # Rebuild if a user-specified setting that affects the build changed.
 .build-config: FORCE
@@ -81,15 +93,15 @@  PKGCONF         ?= pkg-config
 
 DEFAULT_TARGETS :=
 COMMON_HEADERS  := $(wildcard common/*.h)
-LDLIBS          := $(shell "$(PKGCONF)" libcrypto --libs 2>/dev/null || echo -lcrypto)
+LDLIBS          := $(shell "$(PKGCONF)" libcrypto --libs 2>/dev/null || echo $(LIBCRYPTO))
 CFLAGS          += $(shell "$(PKGCONF)" libcrypto --cflags 2>/dev/null || echo)
 
 # If we are dynamically linking, when running tests we need to override
 # LD_LIBRARY_PATH as no RPATH is set
 ifdef USE_SHARED_LIB
-RUN_FSVERITY    = LD_LIBRARY_PATH=./ ./fsverity
+RUN_FSVERITY    = LD_LIBRARY_PATH=./ ./fsverity$(EXEEXT)
 else
-RUN_FSVERITY    = ./fsverity
+RUN_FSVERITY    = ./fsverity$(EXEEXT)
 endif
 
 ##############################################################################
@@ -99,6 +111,9 @@  endif
 SOVERSION       := 0
 LIB_CFLAGS      := $(CFLAGS) -fvisibility=hidden
 LIB_SRC         := $(wildcard lib/*.c)
+ifeq ($(MINGW),1)
+LIB_SRC         := $(filter-out lib/enable.c,${LIB_SRC})
+endif
 LIB_HEADERS     := $(wildcard lib/*.h) $(COMMON_HEADERS)
 STATIC_LIB_OBJ  := $(LIB_SRC:.c=.o)
 SHARED_LIB_OBJ  := $(LIB_SRC:.c=.shlib.o)
@@ -141,10 +156,13 @@  PROG_COMMON_SRC   := programs/utils.c
 PROG_COMMON_OBJ   := $(PROG_COMMON_SRC:.c=.o)
 FSVERITY_PROG_OBJ := $(PROG_COMMON_OBJ)		\
 		     programs/cmd_digest.o	\
-		     programs/cmd_enable.o	\
-		     programs/cmd_measure.o	\
 		     programs/cmd_sign.o	\
 		     programs/fsverity.o
+ifneq ($(MINGW),1)
+FSVERITY_PROG_OBJ += \
+		     programs/cmd_enable.o	\
+		     programs/cmd_measure.o
+endif
 TEST_PROG_SRC     := $(wildcard programs/test_*.c)
 TEST_PROGRAMS     := $(TEST_PROG_SRC:programs/%.c=%)
 
@@ -186,7 +204,7 @@  test_programs:$(TEST_PROGRAMS)
 # want to run the full tests.
 check:fsverity test_programs
 	for prog in $(TEST_PROGRAMS); do \
-		$(TEST_WRAPPER_PROG) ./$$prog || exit 1; \
+		$(TEST_WRAPPER_PROG) ./$$prog$(EXEEXT) || exit 1; \
 	done
 	$(RUN_FSVERITY) --help > /dev/null
 	$(RUN_FSVERITY) --version > /dev/null
@@ -202,7 +220,7 @@  check:fsverity test_programs
 
 install:all
 	install -d $(DESTDIR)$(LIBDIR)/pkgconfig $(DESTDIR)$(INCDIR) $(DESTDIR)$(BINDIR)
-	install -m755 fsverity $(DESTDIR)$(BINDIR)
+	install -m755 fsverity$(EXEEXT) $(DESTDIR)$(BINDIR)
 	install -m644 libfsverity.a $(DESTDIR)$(LIBDIR)
 	install -m755 libfsverity.so.$(SOVERSION) $(DESTDIR)$(LIBDIR)
 	ln -sf libfsverity.so.$(SOVERSION) $(DESTDIR)$(LIBDIR)/libfsverity.so
@@ -215,7 +233,7 @@  install:all
 	chmod 644 $(DESTDIR)$(LIBDIR)/pkgconfig/libfsverity.pc
 
 uninstall:
-	rm -f $(DESTDIR)$(BINDIR)/fsverity
+	rm -f $(DESTDIR)$(BINDIR)/fsverity$(EXEEXT)
 	rm -f $(DESTDIR)$(LIBDIR)/libfsverity.a
 	rm -f $(DESTDIR)$(LIBDIR)/libfsverity.so.$(SOVERSION)
 	rm -f $(DESTDIR)$(LIBDIR)/libfsverity.so
@@ -232,4 +250,4 @@  help:
 
 clean:
 	rm -f $(DEFAULT_TARGETS) $(TEST_PROGRAMS) \
-		lib/*.o programs/*.o .build-config fsverity.sig
+		fsverity$(EXEEXT) lib/*.o programs/*.o .build-config fsverity.sig
diff --git a/common/common_defs.h b/common/common_defs.h
index 279385a..3ae5561 100644
--- a/common/common_defs.h
+++ b/common/common_defs.h
@@ -15,6 +15,8 @@ 
 #include <stddef.h>
 #include <stdint.h>
 
+#include "win32_defs.h"
+
 typedef uint8_t u8;
 typedef uint16_t u16;
 typedef uint32_t u32;
diff --git a/common/fsverity_uapi.h b/common/fsverity_uapi.h
index 33f4415..be1d3f6 100644
--- a/common/fsverity_uapi.h
+++ b/common/fsverity_uapi.h
@@ -10,8 +10,10 @@ 
 #ifndef _UAPI_LINUX_FSVERITY_H
 #define _UAPI_LINUX_FSVERITY_H
 
+#ifndef _WIN32
 #include <linux/ioctl.h>
 #include <linux/types.h>
+#endif /* _WIN32 */
 
 #define FS_VERITY_HASH_ALG_SHA256	1
 #define FS_VERITY_HASH_ALG_SHA512	2
diff --git a/common/win32_defs.h b/common/win32_defs.h
new file mode 100644
index 0000000..e13938a
--- /dev/null
+++ b/common/win32_defs.h
@@ -0,0 +1,61 @@ 
+/* SPDX-License-Identifier: MIT */
+/*
+ * WIN32 compat definitions for libfsverity and the 'fsverity' program
+ *
+ * Copyright 2020 Microsoft
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/MIT.
+ */
+#ifndef COMMON_WIN32_DEFS_H
+#define COMMON_WIN32_DEFS_H
+
+/* Some minimal definitions to allow the digest/sign commands to run under Windows */
+
+/* All file reads we do need this flag on _WIN32 */
+#ifndef O_BINARY
+#  define O_BINARY 0
+#endif
+
+#ifdef _WIN32
+
+#include <stdint.h>
+#include <inttypes.h>
+
+#ifdef _WIN64
+#  define SIZET_PF PRIu64
+#else
+#  define SIZET_PF PRIu32
+#endif
+
+#ifndef ENOPKG
+#   define ENOPKG 65
+#endif
+
+#ifndef __cold
+#  define __cold
+#endif
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+typedef __signed__ long long  __s64;
+typedef unsigned long long  __u64;
+typedef __u16 __le16;
+typedef __u16 __be16;
+typedef __u32 __le32;
+typedef __u32 __be32;
+typedef __u64 __le64;
+typedef __u64 __be64;
+
+#else
+
+#define SIZET_PF "zu"
+
+#endif /* _WIN32 */
+
+#endif /* COMMON_WIN32_DEFS_H */
diff --git a/lib/utils.c b/lib/utils.c
index 8b5d6cb..8bb4413 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -22,7 +22,7 @@  static void *xmalloc(size_t size)
 	void *p = malloc(size);
 
 	if (!p)
-		libfsverity_error_msg("out of memory (tried to allocate %zu bytes)",
+		libfsverity_error_msg("out of memory (tried to allocate %" SIZET_PF " bytes)",
 				      size);
 	return p;
 }
@@ -53,6 +53,15 @@  libfsverity_set_error_callback(void (*cb)(const char *msg))
 	libfsverity_error_cb = cb;
 }
 
+#ifdef _WIN32
+static char *strerror_r(int errnum, char *buf, size_t buflen)
+{
+	strerror_s(buf, buflen, errnum);
+
+	return buf;
+}
+#endif
+
 void libfsverity_do_error_msg(const char *format, va_list va, int err)
 {
 	int saved_errno = errno;
diff --git a/programs/fsverity.c b/programs/fsverity.c
index 5d5fbe2..f68e034 100644
--- a/programs/fsverity.c
+++ b/programs/fsverity.c
@@ -28,6 +28,7 @@  static const struct fsverity_command {
 "    fsverity digest FILE...\n"
 "               [--hash-alg=HASH_ALG] [--block-size=BLOCK_SIZE] [--salt=SALT]\n"
 "               [--compact] [--for-builtin-sig]\n"
+#ifndef _WIN32
 	}, {
 		.name = "enable",
 		.func = fsverity_cmd_enable,
@@ -43,6 +44,7 @@  static const struct fsverity_command {
 "Display the fs-verity digest of the given verity file(s)",
 		.usage_str =
 "    fsverity measure FILE...\n"
+#endif /* _WIN32 */
 	}, {
 		.name = "sign",
 		.func = fsverity_cmd_sign,
diff --git a/programs/utils.c b/programs/utils.c
index facccda..ce19b57 100644
--- a/programs/utils.c
+++ b/programs/utils.c
@@ -102,7 +102,7 @@  void install_libfsverity_error_handler(void)
 
 bool open_file(struct filedes *file, const char *filename, int flags, int mode)
 {
-	file->fd = open(filename, flags, mode);
+	file->fd = open(filename, flags | O_BINARY, mode);
 	if (file->fd < 0) {
 		error_msg_errno("can't open '%s' for %s", filename,
 				(flags & O_ACCMODE) == O_RDONLY ? "reading" :