aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2022-02-08 01:13:48 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-02-08 01:13:48 +0000
commitfca5118c6f6f4f55ab8ab6a39679c5a5a871f5e3 (patch)
treea5e816c7e99ab84a0c3abfe52e8ddb094303bdf9
parent67c03956aff6fd90e29b2aa85db7f4d2371d0274 (diff)
parente483d62e0ccd06d6fe6ff1ce39db8b37322e558c (diff)
downloadfsverity-utils-fca5118c6f6f4f55ab8ab6a39679c5a5a871f5e3.tar.gz
Merge remote-tracking branch 'aosp/upstream-master' am: 58926f716c am: 7c6fce9125 am: 0685632d03 am: e483d62e0c
Original change: https://android-review.googlesource.com/c/platform/external/fsverity-utils/+/1975207 Change-Id: I8f68e66e5e46d109f8645125235286972eec6348
-rw-r--r--.github/workflows/ci.yml169
-rw-r--r--.gitignore2
-rw-r--r--METADATA8
-rw-r--r--Makefile17
-rw-r--r--NEWS.md11
-rw-r--r--README.md52
-rw-r--r--include/libfsverity.h16
-rw-r--r--lib/libfsverity.pc.in2
-rw-r--r--man/fsverity.1.md8
-rw-r--r--programs/fsverity.c2
-rwxr-xr-xscripts/do-release.sh101
-rwxr-xr-xscripts/run-sparse.sh2
-rwxr-xr-xscripts/run-tests.sh369
13 files changed, 566 insertions, 193 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..309013a
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,169 @@
+# SPDX-License-Identifier: MIT
+# Copyright 2021 Google LLC
+#
+# 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.
+
+name: CI
+on: [pull_request]
+
+jobs:
+ static-linking-test:
+ name: Test building static library
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - run: scripts/run-tests.sh static_linking
+
+ dynamic-linking-test:
+ name: Test building dynamic library
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - run: scripts/run-tests.sh dynamic_linking
+
+ cplusplus-test:
+ name: Test using library from C++ program
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - run: scripts/run-tests.sh cplusplus
+
+ uninstall-test:
+ name: Test uninstalling
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - run: scripts/run-tests.sh uninstall
+
+ dash-test:
+ name: Test building using the dash shell
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - run: scripts/run-tests.sh dash
+
+ license-test:
+ name: Test for correct license info
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - run: scripts/run-tests.sh license
+
+ gcc-test:
+ name: Test with gcc
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - run: scripts/run-tests.sh gcc
+
+ clang-test:
+ name: Test with clang
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y clang
+ - run: scripts/run-tests.sh clang
+
+ _32bit-test:
+ name: Test building 32-bit binaries
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install dependencies
+ run: |
+ sudo dpkg --add-architecture i386
+ sudo apt-get update
+ sudo apt-get install -y gcc-multilib libssl-dev:i386
+ - run: scripts/run-tests.sh 32bit
+
+ sanitizers-test:
+ name: Test with sanitizers enabled
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y clang llvm
+ - run: scripts/run-tests.sh sanitizers
+
+ valgrind-test:
+ name: Test with valgrind enabled
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y valgrind
+ - run: scripts/run-tests.sh valgrind
+
+ boringssl-test:
+ name: Test with BoringSSL
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Cache BoringSSL build
+ uses: actions/cache@v2
+ with:
+ key: boringssl
+ path: boringssl
+ - run: make boringssl
+ - run: scripts/run-tests.sh boringssl
+
+ char-test:
+ name: Test with unsigned/signed char
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - run: scripts/run-tests.sh unsigned_char signed_char
+
+ # FIXME: need a Windows build of libcrypto for this to work
+ #windows-build-test:
+ #name: Windows build tests
+ #runs-on: ubuntu-latest
+ #steps:
+ #- uses: actions/checkout@v2
+ #- name: Install dependencies
+ #run: |
+ #sudo apt-get update
+ #sudo apt-get install -y gcc-mingw-w64-i686 gcc-mingw-w64-x86-64
+ # - run: scripts/run-tests.sh windows_build
+
+ sparse-test:
+ name: Run sparse
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y sparse
+ - run: scripts/run-tests.sh sparse
+
+ clang-analyzer-test:
+ name: Run clang static analyzer
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y clang-tools
+ - run: scripts/run-tests.sh clang_analyzer
+
+ shellcheck-test:
+ name: Run shellcheck
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y shellcheck
+ - run: scripts/run-tests.sh shellcheck
diff --git a/.gitignore b/.gitignore
index eba6ab6..3ea5ca6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,8 @@
*.so
*.so.*
/.build-config
+/boringssl
+/boringssl.tar.gz
/fsverity
/fsverity.sig
/run-tests.log
diff --git a/METADATA b/METADATA
index 52ec89e..b0d1913 100644
--- a/METADATA
+++ b/METADATA
@@ -5,12 +5,12 @@ third_party {
type: GIT
value: "https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/fsverity-utils.git"
}
- version: "4258209301d54512956d536149b0eef0c695cfe6"
+ version: "20e87c13075a8e5660a8d69fd6c93d4f7c5f01a5"
# would be NOTICE save for common/fsverity_uapi.h
license_type: RESTRICTED
last_upgrade_date {
- year: 2021
- month: 12
- day: 20
+ year: 2022
+ month: 2
+ day: 7
}
}
diff --git a/Makefile b/Makefile
index 81b7b6d..2304a21 100644
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,7 @@ endif
# Set the CFLAGS. First give the warning-related flags (unconditionally, though
# the user can override any of them by specifying the opposite flag); then give
-# the user-specifed CFLAGS, defaulting to -O2 if none were specified.
+# the user-specified CFLAGS, defaulting to -O2 if none were specified.
#
# Use -Wno-deprecated-declarations to avoid warnings about the Engine API having
# been deprecated in OpenSSL 3.0; the replacement isn't ready yet.
@@ -213,6 +213,21 @@ EXTRA_TARGETS += $(MAN_PAGES)
##############################################################################
+# Support for downloading and building BoringSSL. The purpose of this is to
+# allow testing builds of fsverity-utils that link to BoringSSL instead of
+# OpenSSL, without having to use a system that uses BoringSSL natively.
+
+boringssl:
+ rm -rf boringssl boringssl.tar.gz
+ curl -s -o boringssl.tar.gz \
+ https://boringssl.googlesource.com/boringssl/+archive/refs/heads/master.tar.gz
+ mkdir boringssl
+ tar xf boringssl.tar.gz -C boringssl
+ cmake -B boringssl/build boringssl
+ $(MAKE) -C boringssl/build $(MAKEFLAGS)
+
+##############################################################################
+
SPECIAL_TARGETS := all test_programs check install install-man uninstall \
help clean
diff --git a/NEWS.md b/NEWS.md
index be8d12f..c63dff9 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,5 +1,16 @@
# fsverity-utils release notes
+## Version 1.5
+
+* Made the `fsverity sign` command and the `libfsverity_sign_digest()` function
+ support PKCS#11 tokens.
+
+* Avoided a compiler error when building with musl libc.
+
+* Avoided compiler warnings when building with OpenSSL 3.0.
+
+* Improved documentation and test scripts.
+
## Version 1.4
* Added a manual page for the `fsverity` utility.
diff --git a/README.md b/README.md
index 14c7bbe..ffa25fd 100644
--- a/README.md
+++ b/README.md
@@ -102,11 +102,44 @@ against a trusted value.
### Using builtin signatures
-With `CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y`, the filesystem supports
-automatically verifying a signed file digest that has been included in
-the verity metadata. The signature is verified against the set of
-X.509 certificates that have been loaded into the ".fs-verity" kernel
-keyring. Here's an example:
+First, note that fs-verity is essentially just a way of hashing a
+file; it doesn't mandate a specific way of handling signatures.
+There are several possible ways that signatures could be handled:
+
+* Do it entirely in userspace
+* Use IMA appraisal (work-in-progress)
+* Use fs-verity built-in signatures
+
+Any such solution needs two parts: (a) a policy that determines which
+files are required to have fs-verity enabled and have a valid
+signature, and (b) enforcement of the policy. Each part could happen
+either in a trusted userspace program(s) or in the kernel.
+
+fs-verity built-in signatures (which are supported when the kernel was
+built with `CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y`) are a hybrid
+solution where the policy of which files are required to be signed is
+determined and enforced by a trusted userspace program, but the actual
+signature verification happens in the kernel. Specifically, with
+built-in signatures, the filesystem supports storing a signed file
+digest in each file's verity metadata. Before allowing access to the
+file, the filesystem will automatically verify the signature against
+the set of X.509 certificates in the ".fs-verity" kernel keyring. If
+set, the sysctl `fs.verity.require_signatures=1` will make the kernel
+enforce that every verity file has a valid built-in signature.
+
+fs-verity built-in signatures are primarily intended as a
+proof-of-concept; they reuse the kernel code that verifies the
+signatures of loadable kernel modules. This solution still requires a
+trusted userspace program to enforce that particular files have
+fs-verity enabled. Also, this solution uses PKCS#7 signatures, which
+are complex and prone to security bugs.
+
+Thus, if possible one of the other solutions should be used instead.
+For example, the trusted userspace program could verify signatures
+itself, using a simple signature format using a modern algorithm such
+as Ed25519.
+
+That being said, here are some examples of using built-in signatures:
```bash
# Generate a new certificate and private key:
@@ -137,15 +170,6 @@ keyring. Here's an example:
fsverity digest file --compact --for-builtin-sig | tr -d '\n' | xxd -p -r | openssl smime -sign -in /dev/stdin ...
```
-By default, it's not required that verity files have a signature.
-This can be changed with `sysctl fs.verity.require_signatures=1`.
-When set, it's guaranteed that the contents of every verity file has
-been signed by one of the certificates in the keyring.
-
-Note: applications generally still need to check whether the file
-they're accessing really is a verity file, since an attacker could
-replace a verity file with a regular one.
-
### With IMA
IMA support for fs-verity is planned.
diff --git a/include/libfsverity.h b/include/libfsverity.h
index fe89371..a0a1527 100644
--- a/include/libfsverity.h
+++ b/include/libfsverity.h
@@ -22,7 +22,7 @@ extern "C" {
#include <stdint.h>
#define FSVERITY_UTILS_MAJOR_VERSION 1
-#define FSVERITY_UTILS_MINOR_VERSION 4
+#define FSVERITY_UTILS_MINOR_VERSION 5
#define FS_VERITY_HASH_ALG_SHA256 1
#define FS_VERITY_HASH_ALG_SHA512 2
@@ -186,13 +186,13 @@ libfsverity_compute_digest(void *fd, libfsverity_read_fn_t read_fn,
struct libfsverity_digest **digest_ret);
/**
- * libfsverity_sign_digest() - Sign previously computed digest of a file
- * This signature is used by the filesystem to validate the signed file
- * digest against a public key loaded into the .fs-verity kernel
- * keyring, when CONFIG_FS_VERITY_BUILTIN_SIGNATURES is enabled. The
- * signature is formatted as PKCS#7 stored in DER format. See
- * Documentation/filesystems/fsverity.rst in the kernel source tree for
- * further details.
+ * libfsverity_sign_digest() - Sign a file for built-in signature verification
+ * Sign a file digest in a way that is compatible with the Linux
+ * kernel's fs-verity built-in signature verification support. The
+ * resulting signature will be a PKCS#7 message in DER format. Note
+ * that this is not the only way to do signatures with fs-verity. For
+ * more details, refer to the fsverity-utils README and to
+ * Documentation/filesystems/fsverity.rst in the kernel source tree.
* @digest: pointer to previously computed digest
* @sig_params: pointer to the certificate and private key information
* @sig_ret: Pointer to pointer for signed digest
diff --git a/lib/libfsverity.pc.in b/lib/libfsverity.pc.in
index 03496fe..4c9bb20 100644
--- a/lib/libfsverity.pc.in
+++ b/lib/libfsverity.pc.in
@@ -4,7 +4,7 @@ includedir=@INCDIR@
Name: libfsverity
Description: fs-verity library
-Version: 1.4
+Version: 1.5
Libs: -L${libdir} -lfsverity
Requires.private: libcrypto
Cflags: -I${includedir}
diff --git a/man/fsverity.1.md b/man/fsverity.1.md
index a983912..dd54964 100644
--- a/man/fsverity.1.md
+++ b/man/fsverity.1.md
@@ -1,6 +1,6 @@
-% FSVERITY(1) fsverity-utils v1.4 | User Commands
+% FSVERITY(1) fsverity-utils v1.5 | User Commands
%
-% June 2021
+% February 2022
# NAME
@@ -161,6 +161,10 @@ token, provide **\-\-pkcs11-engine**, **\-\-pkcs11-module**, **\-\-cert**, and
optionally **\-\-pkcs11-keyid**. PKCS#11 token support is unavailable when
fsverity-utils was built with BoringSSL rather than OpenSSL.
+**fsverity sign** should only be used if you need compatibility with fs-verity
+built-in signatures. It is not the only way to do signatures with fs-verity.
+For more information, see the fsverity-utils README.
+
Options accepted by **fsverity sign**:
**\-\-block-size**=*BLOCK_SIZE*
diff --git a/programs/fsverity.c b/programs/fsverity.c
index 813ea2a..e4e348b 100644
--- a/programs/fsverity.c
+++ b/programs/fsverity.c
@@ -56,7 +56,7 @@ static const struct fsverity_command {
}, {
.name = "sign",
.func = fsverity_cmd_sign,
- .short_desc = "Sign a file for fs-verity",
+ .short_desc = "Sign a file for fs-verity built-in signature verification",
.usage_str =
" fsverity sign FILE OUT_SIGFILE\n"
" [--key=KEYFILE] [--cert=CERTFILE] [--pkcs11-engine=SOFILE]\n"
diff --git a/scripts/do-release.sh b/scripts/do-release.sh
index 9f6bf73..3f68497 100755
--- a/scripts/do-release.sh
+++ b/scripts/do-release.sh
@@ -9,44 +9,73 @@
set -e -u -o pipefail
cd "$(dirname "$0")/.."
-if [ $# != 1 ]; then
- echo "Usage: $0 VERS" 1>&2
- echo " e.g. $0 1.0" 1>&2
+usage()
+{
+ echo "Usage: $0 prepare|publish VERS" 1>&2
+ echo " e.g. $0 prepare 1.0" 1>&2
+ echo " $0 publish 1.0" 1>&2
exit 2
+}
+
+if [ $# != 2 ]; then
+ usage
fi
-VERS=$1
+PUBLISH=false
+case $1 in
+publish)
+ PUBLISH=true
+ ;;
+prepare)
+ ;;
+*)
+ usage
+ ;;
+esac
+VERS=$2
PKG=fsverity-utils-$VERS
-git checkout -f
-git clean -fdx
-./scripts/run-tests.sh
-git clean -fdx
-
-major=$(echo "$VERS" | cut -d. -f1)
-minor=$(echo "$VERS" | cut -d. -f2)
-month=$(LC_ALL=C date +%B)
-year=$(LC_ALL=C date +%Y)
-
-sed -E -i -e "/FSVERITY_UTILS_MAJOR_VERSION/s/[0-9]+/$major/" \
- -e "/FSVERITY_UTILS_MINOR_VERSION/s/[0-9]+/$minor/" \
- include/libfsverity.h
-sed -E -i "/Version:/s/[0-9]+\.[0-9]+/$VERS/" \
- lib/libfsverity.pc.in
-sed -E -i -e "/^% /s/fsverity-utils v[0-9]+(\.[0-9]+)+/fsverity-utils v$VERS/" \
- -e "/^% /s/[a-zA-Z]+ 2[0-9]{3}/$month $year/" \
- man/*.[1-9].md
-git commit -a --signoff --message="v$VERS"
-git tag --sign "v$VERS" --message="$PKG"
-
-git archive "v$VERS" --prefix="$PKG/" > "$PKG.tar"
-tar xf "$PKG.tar"
-( cd "$PKG" && make check )
-rm -r "$PKG"
-
-gpg --detach-sign --armor "$PKG.tar"
-DESTDIR=/pub/linux/kernel/people/ebiggers/fsverity-utils/v$VERS
-kup mkdir "$DESTDIR"
-kup put "$PKG.tar" "$PKG.tar.asc" "$DESTDIR/$PKG.tar.gz"
-git push
-git push --tags
+prepare_release()
+{
+ git checkout -f
+ git clean -fdx
+ ./scripts/run-tests.sh
+ git clean -fdx
+
+ major=$(echo "$VERS" | cut -d. -f1)
+ minor=$(echo "$VERS" | cut -d. -f2)
+ month=$(LC_ALL=C date +%B)
+ year=$(LC_ALL=C date +%Y)
+
+ sed -E -i -e "/FSVERITY_UTILS_MAJOR_VERSION/s/[0-9]+/$major/" \
+ -e "/FSVERITY_UTILS_MINOR_VERSION/s/[0-9]+/$minor/" \
+ include/libfsverity.h
+ sed -E -i "/Version:/s/[0-9]+\.[0-9]+/$VERS/" \
+ lib/libfsverity.pc.in
+ sed -E -i -e "/^% /s/fsverity-utils v[0-9]+(\.[0-9]+)+/fsverity-utils v$VERS/" \
+ -e "/^% /s/[a-zA-Z]+ 2[0-9]{3}/$month $year/" \
+ man/*.[1-9].md
+ git commit -a --signoff --message="v$VERS"
+ git tag --sign "v$VERS" --message="$PKG"
+
+ git archive "v$VERS" --prefix="$PKG/" > "$PKG.tar"
+ tar xf "$PKG.tar"
+ ( cd "$PKG" && make check )
+ rm -r "$PKG"
+}
+
+publish_release()
+{
+ gpg --detach-sign --armor "$PKG.tar"
+ DESTDIR=/pub/linux/kernel/people/ebiggers/fsverity-utils/v$VERS
+ kup mkdir "$DESTDIR"
+ kup put "$PKG.tar" "$PKG.tar.asc" "$DESTDIR/$PKG.tar.gz"
+ git push
+ git push --tags
+}
+
+if $PUBLISH; then
+ publish_release
+else
+ prepare_release
+fi
diff --git a/scripts/run-sparse.sh b/scripts/run-sparse.sh
index f75b837..b8d37c1 100755
--- a/scripts/run-sparse.sh
+++ b/scripts/run-sparse.sh
@@ -8,7 +8,7 @@
set -e -u -o pipefail
-find . -name '*.c' | while read -r file; do
+find programs lib -name '*.c' | while read -r file; do
sparse "$file" -gcc-base-dir "$(gcc --print-file-name=)" \
-Iinclude -D_FILE_OFFSET_BITS=64 -Wbitwise -D_GNU_SOURCE
done
diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh
index fb21c39..e2a4e38 100755
--- a/scripts/run-tests.sh
+++ b/scripts/run-tests.sh
@@ -17,11 +17,13 @@
set -e -u -o pipefail
cd "$(dirname "$0")/.."
-log() {
+log()
+{
echo "[$(date)] $*" 1>&2
}
-fail() {
+fail()
+{
echo "FAIL: $*" 1>&2
exit 1
}
@@ -38,31 +40,44 @@ exec 2> >(tee -ia run-tests.log 1>&2)
MAKE="make -j$(getconf _NPROCESSORS_ONLN)"
-log "Build and test with statically linking"
-$MAKE CFLAGS="-Werror"
-if ldd fsverity | grep libfsverity.so; then
- fail "fsverity binary should be statically linked to libfsverity by default"
-fi
-./fsverity --version
-
-log "Check that all global symbols are prefixed with \"libfsverity_\""
-if nm libfsverity.a | grep ' T ' | grep -v " libfsverity_"; then
- fail "Some global symbols are not prefixed with \"libfsverity_\""
-fi
+TEST_FUNCS=()
-log "Build and test with dynamic linking"
-$MAKE CFLAGS="-Werror" USE_SHARED_LIB=1 check
-if ! ldd fsverity | grep libfsverity.so; then
- fail "fsverity binary should be dynamically linked to libfsverity when USE_SHARED_LIB=1"
-fi
+static_linking_test()
+{
+ log "Build and test with statically linking"
+ $MAKE CFLAGS="-Werror"
+ if ldd fsverity | grep libfsverity.so; then
+ fail "fsverity binary should be statically linked to libfsverity by default"
+ fi
+ ./fsverity --version
+
+ log "Check that all global symbols are prefixed with \"libfsverity_\""
+ if nm libfsverity.a | grep ' T ' | grep -v " libfsverity_"; then
+ fail "Some global symbols are not prefixed with \"libfsverity_\""
+ fi
+}
+TEST_FUNCS+=(static_linking_test)
-log "Check that all exported symbols are prefixed with \"libfsverity_\""
-if nm libfsverity.so | grep ' T ' | grep -v " libfsverity_"; then
- fail "Some exported symbols are not prefixed with \"libfsverity_\""
-fi
+dynamic_linking_test()
+{
+ log "Build and test with dynamic linking"
+ $MAKE CFLAGS="-Werror" USE_SHARED_LIB=1 check
+ if ! ldd fsverity | grep libfsverity.so; then
+ fail "fsverity binary should be dynamically linked to libfsverity when USE_SHARED_LIB=1"
+ fi
+
+ log "Check that all exported symbols are prefixed with \"libfsverity_\""
+ if nm libfsverity.so | grep ' T ' | grep -v " libfsverity_"; then
+ fail "Some exported symbols are not prefixed with \"libfsverity_\""
+ fi
+}
+TEST_FUNCS+=(dynamic_linking_test)
-log "Test using libfsverity from C++ program"
-cat > "$TMPDIR/test.cc" <<EOF
+cplusplus_test()
+{
+ $MAKE CFLAGS="-Werror" libfsverity.so
+ log "Test using libfsverity from C++ program"
+ cat > "$TMPDIR/test.cc" <<EOF
#include <libfsverity.h>
#include <iostream>
int main()
@@ -70,127 +85,231 @@ int main()
std::cout << libfsverity_get_digest_size(FS_VERITY_HASH_ALG_SHA256) << std::endl;
}
EOF
-c++ -Wall -Werror "$TMPDIR/test.cc" -Iinclude -L. -lfsverity -o "$TMPDIR/test"
-[ "$(LD_LIBRARY_PATH=. "$TMPDIR/test")" = "32" ]
-rm "${TMPDIR:?}"/*
-
-log "Check that build doesn't produce untracked files"
-$MAKE CFLAGS="-Werror" all test_programs
-if git status --short | grep -q '^??'; then
- git status
- fail "Build produced untracked files (check 'git status'). Missing gitignore entry?"
-fi
+ c++ -Wall -Werror "$TMPDIR/test.cc" -Iinclude -L. -lfsverity -o "$TMPDIR/test"
+ [ "$(LD_LIBRARY_PATH=. "$TMPDIR/test")" = "32" ]
+ rm "${TMPDIR:?}"/*
+}
+TEST_FUNCS+=(cplusplus_test)
-log "Test that 'make uninstall' uninstalls all files"
-make DESTDIR="$TMPDIR" install
-if [ "$(find "$TMPDIR" -type f -o -type l | wc -l)" = 0 ]; then
- fail "'make install' didn't install any files"
-fi
-make DESTDIR="$TMPDIR" uninstall
-if [ "$(find "$TMPDIR" -type f -o -type l | wc -l)" != 0 ]; then
- fail "'make uninstall' didn't uninstall all files"
-fi
-rm -r "${TMPDIR:?}"/*
-
-log "Build, install, and uninstall with dash"
-make clean SHELL=/bin/dash
-make DESTDIR="$TMPDIR" SHELL=/bin/dash install
-make DESTDIR="$TMPDIR" SHELL=/bin/dash uninstall
-
-log "Check that all files have license and copyright info"
-list="$TMPDIR/filelist"
-filter_license_info() {
- # files to exclude from license and copyright info checks
- grep -E -v '(\.gitignore|LICENSE|.*\.md|testdata|fsverity_uapi\.h|libfsverity\.pc\.in)'
-}
-git grep -L 'SPDX-License-Identifier: MIT' \
- | filter_license_info > "$list" || true
-if [ -s "$list" ]; then
- fail "The following files are missing an appropriate SPDX license identifier: $(<"$list")"
-fi
-# For now some people still prefer a free-form license statement, not just SPDX.
-git grep -L 'Use of this source code is governed by an MIT-style' \
- | filter_license_info > "$list" || true
-if [ -s "$list" ]; then
- fail "The following files are missing an appropriate license statement: $(<"$list")"
-fi
-git grep -L '\<Copyright\>' | filter_license_info > "$list" || true
-if [ -s "$list" ]; then
- fail "The following files are missing a copyright statement: $(<"$list")"
-fi
-rm "$list"
+untracked_files_test()
+{
+ log "Check that build doesn't produce untracked files"
+ $MAKE CFLAGS="-Werror" all test_programs
+ if git status --short | grep -q '^??'; then
+ git status
+ fail "Build produced untracked files (check 'git status'). Missing gitignore entry?"
+ fi
+}
+TEST_FUNCS+=(untracked_files_test)
-log "Build and test with gcc (-O2)"
-$MAKE CC=gcc CFLAGS="-O2 -Werror" check
+uninstall_test()
+{
+ log "Test that 'make uninstall' uninstalls all files"
+ make DESTDIR="$TMPDIR" install
+ if [ "$(find "$TMPDIR" -type f -o -type l | wc -l)" = 0 ]; then
+ fail "'make install' didn't install any files"
+ fi
+ make DESTDIR="$TMPDIR" uninstall
+ if [ "$(find "$TMPDIR" -type f -o -type l | wc -l)" != 0 ]; then
+ fail "'make uninstall' didn't uninstall all files"
+ fi
+ rm -r "${TMPDIR:?}"/*
+}
+TEST_FUNCS+=(uninstall_test)
-log "Build and test with gcc (-O3)"
-$MAKE CC=gcc CFLAGS="-O3 -Werror" check
+dash_test()
+{
+ log "Build, install, and uninstall with dash"
+ make clean SHELL=/bin/dash
+ make DESTDIR="$TMPDIR" SHELL=/bin/dash install
+ make DESTDIR="$TMPDIR" SHELL=/bin/dash uninstall
+}
+TEST_FUNCS+=(dash_test)
+
+license_test()
+{
+ log "Check that all files have license and copyright info"
+ list="$TMPDIR/filelist"
+ filter_license_info() {
+ # files to exclude from license and copyright info checks
+ grep -E -v '(\.gitignore|LICENSE|.*\.md|testdata|fsverity_uapi\.h|libfsverity\.pc\.in)'
+ }
+ git grep -L 'SPDX-License-Identifier: MIT' \
+ | filter_license_info > "$list" || true
+ if [ -s "$list" ]; then
+ fail "The following files are missing an appropriate SPDX license identifier: $(<"$list")"
+ fi
+ # For now some people still prefer a free-form license statement, not just SPDX.
+ git grep -L 'Use of this source code is governed by an MIT-style' \
+ | filter_license_info > "$list" || true
+ if [ -s "$list" ]; then
+ fail "The following files are missing an appropriate license statement: $(<"$list")"
+ fi
+ git grep -L '\<Copyright\>' | filter_license_info > "$list" || true
+ if [ -s "$list" ]; then
+ fail "The following files are missing a copyright statement: $(<"$list")"
+ fi
+ rm "$list"
+}
+TEST_FUNCS+=(license_test)
+
+gcc_test()
+{
+ log "Build and test with gcc (-O2)"
+ $MAKE CC=gcc CFLAGS="-O2 -Werror" check
-log "Build and test with gcc (32-bit)"
-$MAKE CC=gcc CFLAGS="-O2 -Werror -m32" check
+ log "Build and test with gcc (-O3)"
+ $MAKE CC=gcc CFLAGS="-O3 -Werror" check
+}
+TEST_FUNCS+=(gcc_test)
-log "Build and test with clang (-O2)"
-$MAKE CC=clang CFLAGS="-O2 -Werror" check
+clang_test()
+{
+ log "Build and test with clang (-O2)"
+ $MAKE CC=clang CFLAGS="-O2 -Werror" check
-log "Build and test with clang (-O3)"
-$MAKE CC=clang CFLAGS="-O3 -Werror" check
+ log "Build and test with clang (-O3)"
+ $MAKE CC=clang CFLAGS="-O3 -Werror" check
+}
+TEST_FUNCS+=(clang_test)
-log "Build and test with clang + UBSAN"
-$MAKE CC=clang \
- CFLAGS="-O2 -Werror -fsanitize=undefined -fno-sanitize-recover=undefined" \
- check
+32bit_test()
+{
+ log "Build and test with gcc (32-bit)"
+ $MAKE CC=gcc CFLAGS="-O2 -Werror -m32" check
+}
+TEST_FUNCS+=(32bit_test)
-log "Build and test with clang + ASAN"
-$MAKE CC=clang \
- CFLAGS="-O2 -Werror -fsanitize=address -fno-sanitize-recover=address" \
- check
+sanitizers_test()
+{
+ log "Build and test with clang + UBSAN"
+ $MAKE CC=clang \
+ CFLAGS="-O2 -Werror -fsanitize=undefined -fno-sanitize-recover=undefined" \
+ check
+
+ log "Build and test with clang + ASAN"
+ $MAKE CC=clang \
+ CFLAGS="-O2 -Werror -fsanitize=address -fno-sanitize-recover=address" \
+ check
+
+ log "Build and test with clang + unsigned integer overflow sanitizer"
+ $MAKE CC=clang \
+ CFLAGS="-O2 -Werror -fsanitize=unsigned-integer-overflow -fno-sanitize-recover=unsigned-integer-overflow" \
+ check
+
+ log "Build and test with clang + CFI"
+ $MAKE CC=clang CFLAGS="-O2 -Werror -fsanitize=cfi -flto -fvisibility=hidden" \
+ AR=llvm-ar check
+}
+TEST_FUNCS+=(sanitizers_test)
-log "Build and test with clang + unsigned integer overflow sanitizer"
-$MAKE CC=clang \
- CFLAGS="-O2 -Werror -fsanitize=unsigned-integer-overflow -fno-sanitize-recover=unsigned-integer-overflow" \
- check
+valgrind_test()
+{
+ log "Build and test with valgrind"
+ $MAKE TEST_WRAPPER_PROG="valgrind --quiet --error-exitcode=100 --leak-check=full --errors-for-leak-kinds=all" \
+ CFLAGS="-O2 -Werror" check
+}
+TEST_FUNCS+=(valgrind_test)
-log "Build and test with clang + CFI"
-$MAKE CC=clang CFLAGS="-O2 -Werror -fsanitize=cfi -flto -fvisibility=hidden" \
- check
+boringssl_test()
+{
+ log "Build and test using BoringSSL instead of OpenSSL"
+ log "-> Building BoringSSL"
+ $MAKE boringssl
+ log "-> Building fsverity-utils linked to BoringSSL"
+ $MAKE CFLAGS="-O2 -Werror" LDFLAGS="-Lboringssl/build/crypto" \
+ CPPFLAGS="-Iboringssl/include" LDLIBS="-lcrypto -lpthread" check
+}
+TEST_FUNCS+=(boringssl_test)
-log "Build and test with valgrind"
-$MAKE TEST_WRAPPER_PROG="valgrind --quiet --error-exitcode=100 --leak-check=full --errors-for-leak-kinds=all" \
- CFLAGS="-O2 -Werror" check
+openssl1_test()
+{
+ log "Build and test using OpenSSL 1.0"
+ $MAKE CFLAGS="-O2 -Werror" LDFLAGS="-L/usr/lib/openssl-1.0" \
+ CPPFLAGS="-I/usr/include/openssl-1.0" check
+}
+TEST_FUNCS+=(openssl1_test)
-log "Build and test using BoringSSL instead of OpenSSL"
-BSSL=$HOME/src/boringssl
-$MAKE CFLAGS="-O2 -Werror" LDFLAGS="-L$BSSL/build/crypto" \
- CPPFLAGS="-I$BSSL/include" LDLIBS="-lcrypto -lpthread" check
+openssl3_test()
+{
+ log "Build and test using OpenSSL 3.0"
+ OSSL3=$HOME/src/openssl/inst/usr/local
+ LD_LIBRARY_PATH="$OSSL3/lib64" $MAKE CFLAGS="-O2 -Werror" \
+ LDFLAGS="-L$OSSL3/lib64" CPPFLAGS="-I$OSSL3/include" check
+}
+TEST_FUNCS+=(openssl3_test)
-log "Build and test using OpenSSL 1.0"
-$MAKE CFLAGS="-O2 -Werror" LDFLAGS="-L/usr/lib/openssl-1.0" \
- CPPFLAGS="-I/usr/include/openssl-1.0" check
+unsigned_char_test()
+{
+ log "Build and test using -funsigned-char"
+ $MAKE CFLAGS="-O2 -Werror -funsigned-char" check
+}
+TEST_FUNCS+=(unsigned_char_test)
-log "Build and test using OpenSSL 3.0"
-OSSL3=$HOME/src/openssl/inst/usr/local
-LD_LIBRARY_PATH="$OSSL3/lib64" $MAKE CFLAGS="-O2 -Werror" \
- LDFLAGS="-L$OSSL3/lib64" CPPFLAGS="-I$OSSL3/include" check
+signed_char_test()
+{
+ log "Build and test using -fsigned-char"
+ $MAKE CFLAGS="-O2 -Werror -fsigned-char" check
+}
+TEST_FUNCS+=(signed_char_test)
-log "Build and test using -funsigned-char"
-$MAKE CFLAGS="-O2 -Werror -funsigned-char" check
+windows_build_test()
+{
+ log "Cross-compile for Windows (32-bit)"
+ $MAKE CC=i686-w64-mingw32-gcc CFLAGS="-O2 -Werror"
-log "Build and test using -fsigned-char"
-$MAKE CFLAGS="-O2 -Werror -fsigned-char" check
+ log "Cross-compile for Windows (64-bit)"
+ $MAKE CC=x86_64-w64-mingw32-gcc CFLAGS="-O2 -Werror"
+}
+TEST_FUNCS+=(windows_build_test)
-log "Cross-compile for Windows (32-bit)"
-$MAKE CC=i686-w64-mingw32-gcc CFLAGS="-O2 -Werror"
+sparse_test()
+{
+ log "Run sparse"
+ ./scripts/run-sparse.sh
+}
+TEST_FUNCS+=(sparse_test)
-log "Cross-compile for Windows (64-bit)"
-$MAKE CC=x86_64-w64-mingw32-gcc CFLAGS="-O2 -Werror"
+clang_analyzer_test()
+{
+ log "Run clang static analyzer"
+ scan-build --status-bugs make CFLAGS="-O2 -Werror" all test_programs
+}
+TEST_FUNCS+=(clang_analyzer_test)
-log "Run sparse"
-./scripts/run-sparse.sh
+shellcheck_test()
+{
+ log "Run shellcheck"
+ shellcheck scripts/*.sh 1>&2
+}
+TEST_FUNCS+=(shellcheck_test)
-log "Run clang static analyzer"
-scan-build --status-bugs make CFLAGS="-O2 -Werror" all test_programs
+test_exists()
+{
+ local tst=$1
+ local func
+ for func in "${TEST_FUNCS[@]}"; do
+ if [ "${tst}_test" = "$func" ]; then
+ return 0
+ fi
+ done
+ return 1
+}
-log "Run shellcheck"
-shellcheck scripts/*.sh 1>&2
+if [[ $# == 0 ]]; then
+ for func in "${TEST_FUNCS[@]}"; do
+ eval "$func"
+ done
+else
+ for tst; do
+ if ! test_exists "$tst"; then
+ echo 1>&2 "Unknown test: $tst"
+ exit 2
+ fi
+ done
+ for tst; do
+ eval "${tst}_test"
+ done
+fi
log "All tests passed!"