diff mbox series

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

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

Commit Message

Luca Boccassi Dec. 17, 2020, 7:25 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
v3: apply suggestion to remove -D_GNU_SOURCE from the header and define
    it as a CPPFLAGS, and to add  a definition of __printf for _WIN32
    to fix compiler warnings
    removed override of -lcrypto, not needed
v4: apply suggestion to remove overrides of %zu, as it now "just works".
    no more compilation warnings.

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

Comments

Eric Biggers Dec. 21, 2020, 9:40 p.m. UTC | #1
On Thu, Dec 17, 2020 at 07:25:16PM +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>

This commit message is outdated; can you update it?

> diff --git a/Makefile b/Makefile
> index bfe83c4..a5aa900 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				\
> @@ -47,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      ' $@;
> @@ -62,7 +67,12 @@ BINDIR          ?= $(PREFIX)/bin
>  INCDIR          ?= $(PREFIX)/include
>  LIBDIR          ?= $(PREFIX)/lib
>  DESTDIR         ?=
> +ifneq ($(MINGW),1)
>  PKGCONF         ?= pkg-config
> +else
> +PKGCONF         := false
> +EXEEXT          := .exe
> +endif
>  
>  # Rebuild if a user-specified setting that affects the build changed.
>  .build-config: FORCE
> @@ -87,9 +97,9 @@ 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 +109,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 +154,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=%)
>  

The Makefile target to build the binary is still "fsverity", but for Windows it
actually builds "fsverity.exe".  I think that when the .exe extension is added,
the name of the Makefile target should change too.  Makefile targets should be
either a filename target *or* a special target, not conditionally either one.

> @@ -186,7 +202,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

The .exe extension isn't being added to the test programs when they are built.
Did you intend for building the test programs for Windows (and running them on
Windows) to be supported?

- Eric
Luca Boccassi Dec. 21, 2020, 10:23 p.m. UTC | #2
On Mon, 21 Dec 2020 at 21:40, Eric Biggers <ebiggers@kernel.org> wrote:
>
> On Thu, Dec 17, 2020 at 07:25:16PM +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>
>
> This commit message is outdated; can you update it?

Fixed in v5.

> > diff --git a/Makefile b/Makefile
> > index bfe83c4..a5aa900 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                             \
> > @@ -47,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      ' $@;
> > @@ -62,7 +67,12 @@ BINDIR          ?= $(PREFIX)/bin
> >  INCDIR          ?= $(PREFIX)/include
> >  LIBDIR          ?= $(PREFIX)/lib
> >  DESTDIR         ?=
> > +ifneq ($(MINGW),1)
> >  PKGCONF         ?= pkg-config
> > +else
> > +PKGCONF         := false
> > +EXEEXT          := .exe
> > +endif
> >
> >  # Rebuild if a user-specified setting that affects the build changed.
> >  .build-config: FORCE
> > @@ -87,9 +97,9 @@ 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 +109,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 +154,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=%)
> >
>
> The Makefile target to build the binary is still "fsverity", but for Windows it
> actually builds "fsverity.exe".  I think that when the .exe extension is added,
> the name of the Makefile target should change too.  Makefile targets should be
> either a filename target *or* a special target, not conditionally either one.

Ok, updated in v5.

> > @@ -186,7 +202,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
>
> The .exe extension isn't being added to the test programs when they are built.
> Did you intend for building the test programs for Windows (and running them on
> Windows) to be supported?

Yes it probably should. Made further updates, and at least with
mingw/wine make check works.

Kind regards,
Luca Boccassi
diff mbox series

Patch

diff --git a/Makefile b/Makefile
index bfe83c4..a5aa900 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				\
@@ -47,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      ' $@;
@@ -62,7 +67,12 @@  BINDIR          ?= $(PREFIX)/bin
 INCDIR          ?= $(PREFIX)/include
 LIBDIR          ?= $(PREFIX)/lib
 DESTDIR         ?=
+ifneq ($(MINGW),1)
 PKGCONF         ?= pkg-config
+else
+PKGCONF         := false
+EXEEXT          := .exe
+endif
 
 # Rebuild if a user-specified setting that affects the build changed.
 .build-config: FORCE
@@ -87,9 +97,9 @@  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 +109,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 +154,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 +202,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 +218,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 +231,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 +248,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..29ef9b2
--- /dev/null
+++ b/common/win32_defs.h
@@ -0,0 +1,57 @@ 
+/* 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>
+
+#ifndef ENOPKG
+#   define ENOPKG 65
+#endif
+
+#ifndef __cold
+#  define __cold
+#endif
+
+/* For %zu in printf() */
+#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;
+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;
+
+#endif /* _WIN32 */
+
+#endif /* COMMON_WIN32_DEFS_H */
diff --git a/lib/utils.c b/lib/utils.c
index 8b5d6cb..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>
@@ -53,6 +51,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" :