diff options
51 files changed, 293 insertions, 747 deletions
diff --git a/.clang-tidy b/.clang-tidy index b496044c..ecc9a621 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,6 +1,42 @@ --- -Checks: 'bugprone-*,cert-*,-cert-dcl03-c,-clang-analyzer-unix.Malloc,-clang-analyzer-deadcode.DeadStores,-clang-analyzer-valist.Uninitialized,readability-*,-readability-braces-*,-readability-else-after-return,-readability-redundant-declaration,-readability-non-const-parameter,google-readability-casting,misc-*,-misc-static-assert,-misc-macro-parentheses,-misc-unused-parameters' -WarningsAsErrors: 'cert-*,misc-*,readability-*,clang-analyzer-*,-readability-non-const-parameter' +Checks: + - bugprone-* + - cert-* + - google-readability-casting + - misc-* + - readability-* + + - -bugprone-assignment-in-if-condition # we explicitly put assignments into parentheses so they are very visible + - -bugprone-branch-clone + - -bugprone-easily-swappable-parameters + - -bugprone-inc-dec-in-conditions + - -bugprone-multi-level-implicit-pointer-conversion + - -bugprone-narrowing-conversions + - -bugprone-sizeof-expression # may be useful, but it's utterly broken + - -bugprone-suspicious-string-compare + - -cert-dcl03-c + - -clang-analyzer-deadcode.DeadStores + - -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling + - -clang-analyzer-unix.Malloc + - -clang-analyzer-valist.Uninitialized + - -clang-analyzer-optin.core.EnumCastOutOfRange # libknot uses enums as flags + - -misc-include-cleaner + - -misc-macro-parentheses + - -misc-no-recursion + - -misc-static-assert + - -misc-unused-parameters + - -readability-avoid-nested-conditional-operator + - -readability-avoid-unconditional-preprocessor-if + - -readability-braces-* + - -readability-cognitive-complexity + - -readability-else-after-return + - -readability-function-cognitive-complexity + - -readability-identifier-length + - -readability-isolate-declaration + - -readability-magic-numbers + - -readability-non-const-parameter + - -readability-redundant-declaration +WarningsAsErrors: 'cert-*,clang-analyzer-*,misc-*,readability-*,-readability-non-const-parameter' HeaderFilterRegex: 'contrib/ucw/*.h' CheckOptions: - key: readability-identifier-naming @@ -65,6 +65,7 @@ /self.key /stamp-h1 /tags +/tests/dnstap/src/dnstap-test/go.sum /tests/pytests/*/tcproxy /tests/pytests/*/tlsproxy /tests/pytests/pytests.*.html diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5a13e7fc..f86908d7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,7 +17,13 @@ variables: PREFIX: $CI_PROJECT_DIR/.local EMAIL: 'ci@nic' -image: $CI_REGISTRY/knot/knot-resolver/ci/debian-11:knot-$KNOT_VERSION + # IMAGE_TAG is a Git branch/tag name from https://gitlab.nic.cz/knot/knot-resolver-ci + # In general, keep it pointing to a tag - use a branch only for development. + # More info in the knot-resolver-ci repository. + IMAGE_TAG: 'v20240506' + IMAGE_PREFIX: '$CI_REGISTRY/knot/knot-resolver-ci' + +image: $IMAGE_PREFIX/debian12-knot_3_3:$IMAGE_TAG default: interruptible: true tags: @@ -63,7 +69,7 @@ stages: .after_build: &after_build <<: *common needs: - - build + - build-stable before_script: # meson detects changes and performs useless rebuild; hide the log - ninja -C build_ci* &>/dev/null @@ -94,6 +100,9 @@ stages: - pkg reports: junit: build_ci*/meson-logs/testlog.junit.xml + before_script: + - "echo \"PATH: $PATH\"" + - "echo \"Using Python at: $(which python)\"" after_script: - ci/fix-meson-junit.sh build_ci*/meson-logs/testlog.junit.xml @@ -103,38 +112,80 @@ archive: script: - apkg make-archive -build: +build-stable: + <<: *build + script: + - meson build_ci_stable --prefix=$PREFIX -Dmalloc=disabled -Dwerror=true -Dextra_tests=enabled + - ninja -C build_ci_stable + - ninja -C build_ci_stable install >/dev/null + - ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite snowflake + +build-deb11-knot31: + <<: *build + image: $IMAGE_PREFIX/debian11-knot_3_1:$IMAGE_TAG + script: + - meson build_ci_deb11_knot31 --prefix=$PREFIX -Dmalloc=disabled -Dwerror=true -Dextra_tests=enabled + - ninja -C build_ci_deb11_knot31 + - ninja -C build_ci_deb11_knot31 install >/dev/null + - ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite snowflake + +build-deb11-knot32: + <<: *build + image: $IMAGE_PREFIX/debian11-knot_3_2:$IMAGE_TAG + script: + - meson build_ci_deb11_knot32 --prefix=$PREFIX -Dmalloc=disabled -Dwerror=true -Dextra_tests=enabled + - ninja -C build_ci_deb11_knot32 + - ninja -C build_ci_deb11_knot32 install >/dev/null + - ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite snowflake + +build-deb12-knot32: <<: *build + image: $IMAGE_PREFIX/debian12-knot_3_2:$IMAGE_TAG script: - - meson build_ci --prefix=$PREFIX -Dmalloc=disabled -Dwerror=true -Dextra_tests=enabled - - ninja -C build_ci - - ninja -C build_ci install >/dev/null + - meson build_ci_deb12_knot32 --prefix=$PREFIX -Dmalloc=disabled -Dwerror=true -Dextra_tests=enabled + - ninja -C build_ci_deb12_knot32 + - ninja -C build_ci_deb12_knot32 install >/dev/null - ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite snowflake -build-knot32: +build-deb12-knot-master: <<: *build - image: $CI_REGISTRY/knot/knot-resolver/ci/debian-11:knot-3.2 + image: $IMAGE_PREFIX/debian12-knot_master:$IMAGE_TAG script: - - meson build_ci_knot32 --prefix=$PREFIX -Dmalloc=disabled -Dwerror=true -Dextra_tests=enabled - - ninja -C build_ci_knot32 - - ninja -C build_ci_knot32 install >/dev/null + - meson build_ci_deb12_knot_master --prefix=$PREFIX -Dmalloc=disabled -Dwerror=true -Dextra_tests=enabled + - ninja -C build_ci_deb12_knot_master + - ninja -C build_ci_deb12_knot_master install >/dev/null - ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite snowflake + allow_failure: true -build-asan: +build-stable-asan-gcc: <<: *build script: - # issues with UBSan and ASan in CI: - # - `ahocorasick.so` causes C++ problems - # - `--default-library=shared` causes link problems - - CC=clang CXX=clang++ CFLAGS=-fno-sanitize-recover=all CXXFLAGS=-fno-sanitize=undefined meson build_ci_asan --default-library=static --prefix=$PREFIX -Dmalloc=jemalloc -Db_sanitize=address,undefined -Dextra_tests=enabled - - ninja -C build_ci_asan - - ninja -C build_ci_asan install >/dev/null - # TODO _leaks: not sure what exactly is wrong in leak detection on config tests - # TODO skip_asan: all three of these disappear locally when using gcc 9.1 (except some leaks) - - MESON_TESTTHREADS=1 ASAN_OPTIONS=detect_leaks=0 ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite skip_asan --no-suite snowflake + - CFLAGS=-fno-sanitize-recover=all meson build_ci_asan_gcc --prefix=$PREFIX -Dmalloc=jemalloc -Db_sanitize=address,undefined -Dextra_tests=enabled + - ninja -C build_ci_asan_gcc + - ninja -C build_ci_asan_gcc install >/dev/null + - MESON_TESTTHREADS=1 ${MESON_TEST} --suite unit --suite dnstap --no-suite skip_asan --no-suite snowflake + - MESON_TESTTHREADS=1 ASAN_OPTIONS=detect_leaks=0 ${MESON_TEST} --suite config --no-suite skip_asan --no-suite snowflake + + +# TODO: Clang sanitizer seems to be broken in the current version of Debian. Use +# GCC above and maybe re-enable the Clang one once we update at some point. + +#build-stable-asan-clang: +# <<: *build +# script: +# # issues with UBSan and ASan in CI: +# # - `ahocorasick.so` causes C++ problems +# # - `--default-library=shared` causes link problems +# - CC=clang CXX=clang++ CFLAGS=-fno-sanitize-recover=all CXXFLAGS=-fno-sanitize=undefined meson build_ci_asan_clang --default-library=static --prefix=$PREFIX -Dmalloc=jemalloc -Db_sanitize=address,undefined -Dextra_tests=enabled +# - ninja -C build_ci_asan_clang +# - ninja -C build_ci_asan_clang install >/dev/null +# # TODO _leaks: not sure what exactly is wrong in leak detection on config tests +# # TODO skip_asan: all three of these disappear locally when using gcc 9.1 (except some leaks) +# - MESON_TESTTHREADS=1 ASAN_OPTIONS=detect_leaks=0 ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite skip_asan --no-suite snowflake build:macOS: <<: *nodep + image: python:3-alpine only: refs: - branches@knot/knot-resolver @@ -142,7 +193,8 @@ build:macOS: when: delayed start_in: 3 minutes # allow some time for mirroring, job creation script: - - ci/gh_actions.py ${CI_COMMIT_REF_NAME} ${CI_COMMIT_SHA} + - pip3 install -U requests + - python3 ./ci/gh_actions.py ${CI_COMMIT_REF_NAME} ${CI_COMMIT_SHA} docker: <<: *nodep @@ -163,25 +215,6 @@ docker: after_script: # remove dangling images to avoid running out of disk space - docker rmi ${DOCKER_IMAGE_NAME} - docker rmi $(docker images -f "dangling=true" -q) - -sonarcloud: - <<: *nodep - stage: build - except: null - only: - - tags - - master@knot/knot-resolver - script: - - meson build_sonarcloud --prefix=$PREFIX -Dmalloc=disabled - - build-wrapper-linux-x86-64 --out-dir bw-output ninja -C build_sonarcloud - - > - sonar-scanner - -Dsonar.organization=cz-nic - -Dsonar.projectKey=CZ-NIC_knot-resolver - -Dsonar.sources=. - -Dsonar.cfamily.build-wrapper-output=bw-output - -Dsonar.host.url=https://sonarcloud.io - -Dsonar.projectVersion="$(git describe)" # }}} # sanity {{{ @@ -230,29 +263,8 @@ lint:pedantic: -Wpedantic -Wno-newline-eof -Wno-gnu-zero-variadic-macro-arguments -Wno-gnu-folding-constant' - ninja -C build_pedantic_clang -lint:scan-build: - <<: *after_build - # TODO migrate lint to debian-11 - image: $CI_REGISTRY/knot/knot-resolver/ci/debian-buster:knot-$KNOT_VERSION - before_script: - # -- end TODO - stage: sanity - artifacts: - when: on_failure - expire_in: '1 day' - paths: - - build_ci*/meson-logs/scanbuild - script: - - export SCANBUILD="$(realpath ./scripts/run-scanbuild-with-args.sh)" - - ninja -C build_ci* scan-build || true - - test "$(ls build_ci*/meson-logs/scanbuild/*/report-*.html | wc -l)" = 23 # we have this many errors ATM :-) - lint:tidy: <<: *after_build - # TODO migrate lint to debian-11 - image: $CI_REGISTRY/knot/knot-resolver/ci/debian-buster:knot-$KNOT_VERSION - before_script: - # -- end TODO stage: sanity script: - ninja -C build_ci* tidy @@ -260,7 +272,7 @@ lint:tidy: # Coverity reference: https://www.synopsys.com/blogs/software-security/integrating-coverity-scan-with-gitlab-ci/ lint:coverity: <<: *sanity - image: $CI_REGISTRY/knot/knot-resolver/ci/debian-11-coverity:knot-$KNOT_VERSION + image: $IMAGE_PREFIX/coverity:$IMAGE_TAG only: refs: - nightly@knot/knot-resolver @@ -281,15 +293,12 @@ lint:coverity: - ninja -C build_ci_lib daemon/kresd - ninja -C build_ci_lib kres-gen - git diff --quiet || (git diff; exit 1) -kres-gen-30: - <<: *kres-gen - image: $CI_REGISTRY/knot/knot-resolver/ci/debian-11:knot-3.0 kres-gen-31: <<: *kres-gen - image: $CI_REGISTRY/knot/knot-resolver/ci/debian-11:knot-3.1 + image: $IMAGE_PREFIX/debian11-knot_3_1:$IMAGE_TAG kres-gen-32: <<: *kres-gen - image: $CI_REGISTRY/knot/knot-resolver/ci/debian-11:knot-3.2 + image: $IMAGE_PREFIX/debian12-knot_3_2:$IMAGE_TAG root.hints: <<: *sanity @@ -298,6 +307,21 @@ root.hints: - /^release.*$/ script: - scripts/update-root-hints.sh + +ci-image-is-tag: + <<: *sanity + image: alpine:3 + variables: + GIT_STRATEGY: none + script: + - apk add git + - ( + git ls-remote --tags --exit-code + https://gitlab.nic.cz/knot/knot-resolver-ci.git + refs/tags/$IMAGE_TAG + && echo "Everything is OK!" + ) + || (echo "'$IMAGE_TAG' is not a tag (probably a branch). Make sure to set it to a tag in production!"; exit 2) # }}} # test {{{ @@ -328,7 +352,7 @@ respdiff:basic: <<: *after_build stage: test needs: - - build-asan + - build-stable-asan-gcc script: - ulimit -n "$(ulimit -Hn)" # applies only for kresd ATM - ./ci/respdiff/start-resolvers.sh @@ -371,7 +395,7 @@ manager: pytests: <<: *test_flaky needs: - - build-asan + - build-stable-asan-gcc artifacts: when: always paths: @@ -678,13 +702,10 @@ pkg:arch: # docs: {{{ docs:build: - image: $CI_REGISTRY/packaging/apkg/lxc/fedora-36 stage: deploy needs: [] script: - git submodule update --init --recursive - - apkg build-dep -y - - dnf install -y python3-sphinx texinfo doxygen - pip3 install -U -r doc/requirements.txt - pip3 install -U sphinx_rtd_theme - meson build_doc -Ddoc=enabled diff --git a/ci/images/README.md b/ci/images/README.md deleted file mode 100644 index 52e49faf..00000000 --- a/ci/images/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# Container images for CI - -## Image purpose - -### debian-11 - -The main image used by shared runners to execute most CI builds and tests. - -### debian-11-coverity - -A stripped down version of `debian-11`. It only contains build (not test) -dependencies of `kresd`. It also contains the `cov-build` tool for generating -inputs for [Coverity Scan](https://scan.coverity.com/). - -It is used by the `coverity` CI job to generate and send data to Coverity Scan -for analysis. - -To build this image, you need to retrieve the Coverity Scan token from the -dashboard and pass it to the `build.sh` script using the `COVERITY_SCAN_TOKEN` -environment variable, e.g.: - -``` -$ COVERITY_SCAN_TOKEN=the_secret_token ./build.sh debian-11-coverity -``` - -Sometimes, the Coverity Scan binaries need to be updated in order to maintain -compatibility with the cloud service. Simply rebuild this image and push it to -the registry to achieve this, no other changes (e.g. to the `Dockerfile`) are -required. - -### debian-buster (10) - -Used to serve the same purpose as `debian-11`. As of 2022-03-09, it is still -used by some jobs (linters). - -## Maintenance - -The `ci/images/` directory contains utility scripts to build, push or update -the container images. - -``` -$ ./build.sh debian-11 # builds a debian-11 image locally -$ ./push.sh debian-11 # pushes the local image into target registry -$ ./update.sh debian-11 # utility wrapper that both builds and pushes the image -$ ./update.sh */ # use shell expansion of dirnames to update all images -``` - -By default, a branch of Knot DNS deemed to be stable is selected according to -the `vars.sh` file. To build an image for a different Knot DNS branch, set the -`KNOT_BRANCH` environment variable to the name of the branch, e.g.: - -``` -$ KNOT_BRANCH='3.2' ./update.sh debian-11 -``` diff --git a/ci/images/build.sh b/ci/images/build.sh deleted file mode 100755 index 1e9eabb5..00000000 --- a/ci/images/build.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# build specified docker image - -CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" -source "${CURRENT_DIR}"/vars.sh "$@" -set -ex - -if [ -n "$COVERITY_SCAN_TOKEN" ]; then - SECRETS="$SECRETS --secret id=coverity-token,env=COVERITY_SCAN_TOKEN" -fi - -DOCKERFILE="$(realpath "${IMAGE}")/Dockerfile" - -cd "$CURRENT_DIR/../.." -export DOCKER_BUILDKIT=1 # Enables using secrets in docker-build -docker build \ - --pull \ - --no-cache \ - --tag "${FULL_NAME}" \ - --file "${DOCKERFILE}" \ - . \ - --build-arg KNOT_BRANCH=${KNOT_BRANCH} \ - $SECRETS diff --git a/ci/images/debian-11-coverity/Dockerfile b/ci/images/debian-11-coverity/Dockerfile deleted file mode 100644 index 19156145..00000000 --- a/ci/images/debian-11-coverity/Dockerfile +++ /dev/null @@ -1,43 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -FROM debian:bullseye -MAINTAINER Knot Resolver <knot-resolver@labs.nic.cz> -# >= 3.0 needed because of --enable-xdp=yes -ARG KNOT_BRANCH=3.1 -ARG COVERITY_SCAN_PROJECT_NAME=CZ-NIC/knot-resolver -ENV DEBIAN_FRONTEND=noninteractive - -WORKDIR /root -CMD ["/bin/bash"] - -# generic cleanup -RUN apt-get update -qq - -# Knot and Knot Resolver dependencies -RUN apt-get install -y -qqq git make cmake pkg-config meson \ - build-essential bsdmainutils libtool autoconf libcmocka-dev \ - liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev \ - libelf-dev libmnl-dev libidn11-dev libuv1-dev \ - libluajit-5.1-dev lua-http libssl-dev libnghttp2-dev - -# LuaJIT binary for stand-alone scripting -RUN apt-get install -y -qqq luajit - -# build and install latest version of Knot DNS -RUN git clone --depth=1 --branch=$KNOT_BRANCH https://gitlab.nic.cz/knot/knot-dns.git /tmp/knot -WORKDIR /tmp/knot -RUN pwd -RUN autoreconf -if -RUN ./configure --prefix=/usr --enable-xdp=yes -RUN CFLAGS="-g" make -RUN make install -RUN ldconfig - -# curl and tar (for downloading Coverity tools and uploading logs) -RUN apt-get install -y curl tar - -RUN --mount=type=secret,id=coverity-token \ - curl -o /tmp/cov-analysis-linux64.tar.gz https://scan.coverity.com/download/cxx/linux64 \ - --form project=$COVERITY_SCAN_PROJECT_NAME --form token=$(cat /run/secrets/coverity-token) -RUN tar xfz /tmp/cov-analysis-linux64.tar.gz -RUN mv cov-analysis-linux64-* /opt/cov-analysis diff --git a/ci/images/debian-11/Dockerfile b/ci/images/debian-11/Dockerfile deleted file mode 100644 index 0241a6d4..00000000 --- a/ci/images/debian-11/Dockerfile +++ /dev/null @@ -1,146 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -FROM debian:bullseye -MAINTAINER Knot Resolver <knot-resolver@labs.nic.cz> -# >= 3.0 needed because of --enable-xdp=yes -ARG KNOT_BRANCH=3.1 -ENV DEBIAN_FRONTEND=noninteractive - -WORKDIR /root -CMD ["/bin/bash"] - -# generic cleanup -RUN apt-get update -qq - -# Knot and Knot Resolver dependencies -RUN apt-get install -y -qqq git make cmake pkg-config meson \ - build-essential bsdmainutils libtool autoconf libcmocka-dev \ - liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev \ - libelf-dev libmnl-dev libidn11-dev libuv1-dev libjemalloc-dev \ - libluajit-5.1-dev lua-http libssl-dev libnghttp2-dev - -# Build and testing deps for Resolver's dnstap module (go stuff is just for testing) -RUN apt-get install -y -qqq \ - protobuf-c-compiler libprotobuf-c-dev libfstrm-dev \ - golang-any -COPY ./tests/dnstap /root/tests/dnstap -WORKDIR /root/tests/dnstap/src/dnstap-test -RUN go get . -WORKDIR /root - -# documentation dependencies -RUN apt-get install -y -qqq doxygen python3-sphinx python3-breathe python3-sphinx-rtd-theme - -# Python packages required for Deckard CI -# Python: grab latest versions from PyPi -# (Augeas binding in Debian packages are slow and buggy) -RUN apt-get install -y -qqq python3-pip wget augeas-tools -RUN pip3 install --upgrade pip -RUN pip3 install pylint -RUN pip3 install pep8 -# FIXME replace with dnspython >= 2.2.0 once released -RUN pip3 install git+https://github.com/bwelling/dnspython.git@72348d4698a8f8b209fbdf9e72738904ad31b930 -# tests/pytest dependencies: skip over broken versions -RUN pip3 install jinja2 'pytest != 6.0.0' pytest-html pytest-xdist pytest-forked -# apkg for packaging -RUN pip3 install apkg - -# packet capture tools for Deckard -RUN apt-get install --no-install-suggests --no-install-recommends -y -qqq tcpdump wireshark-common - -# Faketime for Deckard -RUN apt-get install -y -qqq faketime - -# C dependencies for python-augeas -RUN apt-get install -y -qqq libaugeas-dev libffi-dev -# Python dependencies for Deckard -RUN wget https://gitlab.nic.cz/knot/deckard/raw/master/requirements.txt -O /tmp/deckard-req.txt -RUN pip3 install -r /tmp/deckard-req.txt - -# build and install latest version of Knot DNS -RUN git clone --depth=1 --branch=$KNOT_BRANCH https://gitlab.nic.cz/knot/knot-dns.git /tmp/knot -WORKDIR /tmp/knot -RUN pwd -RUN autoreconf -if -RUN ./configure --prefix=/usr --enable-xdp=yes -RUN CFLAGS="-g" make -RUN make install -RUN ldconfig - -# Valgrind for kresd CI -RUN apt-get install valgrind -y -qqq -RUN wget https://github.com/LuaJIT/LuaJIT/raw/v2.1.0-beta3/src/lj.supp -O /lj.supp -# TODO: rebuild LuaJIT with Valgrind support - -# Lua lint for kresd CI -RUN apt-get install luarocks -y -qqq -RUN luarocks --lua-version 5.1 install luacheck - -# respdiff for kresd CI -RUN apt-get install lmdb-utils -y -qqq -RUN git clone --depth=1 https://gitlab.nic.cz/knot/respdiff /var/opt/respdiff -RUN pip3 install -r /var/opt/respdiff/requirements.txt - -# Python static analysis for respdiff -RUN pip3 install mypy -RUN pip3 install flake8 - -# Python requests for CI scripts -RUN pip3 install requests - -# docker-py for packaging tests -RUN pip3 install docker - -# Unbound for respdiff -RUN apt-get install unbound unbound-anchor -y -qqq -RUN printf "server:\n interface: 127.0.0.1@53535\n use-syslog: yes\n do-ip6: no\nremote-control:\n control-enable: no\n" >> /etc/unbound/unbound.conf - -# BIND for respdiff -RUN apt-get install bind9 -y -qqq -RUN printf '\nOPTIONS="-4 $OPTIONS"' >> /etc/default/bind9 -RUN printf 'options {\n directory "/var/cache/bind";\n listen-on port 53533 { 127.0.0.1; };\n listen-on-v6 port 53533 { ::1; };\n};\n' > /etc/bind/named.conf.options - -# PowerDNS Recursor for Deckard CI -RUN apt-get install pdns-recursor -y -qqq - -# dnsdist for Deckard CI -RUN apt-get install dnsdist -y -qqq - -# code coverage -RUN apt-get install -y -qqq lcov -RUN luarocks --lua-version 5.1 install luacov - -# LuaJIT binary for stand-alone scripting -RUN apt-get install -y -qqq luajit - -# clang for kresd CI, version updated as debian updates it -RUN apt-get install -y -qqq clang clang-tools clang-tidy - -# OpenBuildService CLI tool -RUN apt-get install -y osc - -# curl (API) -RUN apt-get install -y curl - -# configure knot-resolver-testing OBS repo for dependencies missing in Debian -RUN echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-testing/Debian_11/ /' > /etc/apt/sources.list.d/knot-resolver-testing.list -RUN wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-testing/Debian_11/Release.key -O Release.key -RUN APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key add Release.key -RUN rm Release.key -RUN apt-get update -qq - -# packages from our knot-resolver-testing repo -RUN apt-get update -RUN apt-get install -y -qqq lua-psl - -# en_US.UTF-8 locale for scripts.update-authors.sh -RUN apt-get install -y -qqq locales -RUN sed -i "/en_US.UTF-8/ s/^#\(.*\)/\1/" /etc/locale.gen -RUN locale-gen - -# SonarCloud scanner -RUN wget -O /var/opt/wrapper.zip https://sonarcloud.io/static/cpp/build-wrapper-linux-x86.zip -RUN wget -O /var/opt/scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip -RUN unzip -d /var/opt /var/opt/wrapper.zip -RUN unzip -d /var/opt /var/opt/scanner.zip -ENV PATH "$PATH:/var/opt/build-wrapper-linux-x86:/var/opt/sonar-scanner-5.0.1.3006-linux/bin" diff --git a/ci/images/debian-buster/Dockerfile b/ci/images/debian-buster/Dockerfile deleted file mode 100644 index 39f43277..00000000 --- a/ci/images/debian-buster/Dockerfile +++ /dev/null @@ -1,146 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -FROM debian:buster -MAINTAINER Knot Resolver <knot-resolver@labs.nic.cz> -# >= 3.0 needed because of --enable-xdp=yes -ARG KNOT_BRANCH=3.0 -ENV DEBIAN_FRONTEND=noninteractive - -WORKDIR /root -CMD ["/bin/bash"] - -# generic cleanup -RUN apt-get update -qq -# TODO: run upgrade once buster reaches a stable release -# RUN apt-get upgrade -y -qqq - -# Knot and Knot Resolver dependencies -RUN apt-get install -y -qqq git make cmake pkg-config meson \ - build-essential bsdmainutils libtool autoconf libcmocka-dev \ - liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev \ - libelf-dev libmnl-dev libidn11-dev libuv1-dev \ - libluajit-5.1-dev lua-http libssl-dev libnghttp2-dev - -# Build and testing deps for Resolver's dnstap module (go stuff is just for testing) -RUN apt-get install -y -qqq \ - protobuf-c-compiler libprotobuf-c-dev libfstrm-dev \ - golang-any -COPY ./tests/dnstap /root/tests/dnstap -WORKDIR /root/tests/dnstap/src/dnstap-test -RUN go get . -WORKDIR /root - -# documentation dependencies -RUN apt-get install -y -qqq doxygen python3-sphinx python3-breathe python3-sphinx-rtd-theme - -# Python packages required for Deckard CI -# Python: grab latest versions from PyPi -# (Augeas binding in Debian packages are slow and buggy) -RUN apt-get install -y -qqq python3-pip wget augeas-tools -RUN pip3 install --upgrade pip -RUN pip3 install pylint -RUN pip3 install pep8 -RUN pip3 install pytest-xdist -# tests/pytest dependencies: skip over broken versions -RUN pip3 install 'dnspython != 2.0.0' 'jinja2 == 2.11.3' 'pytest != 6.0.0' pytest-html pytest-xdist - -# packet capture tools for Deckard -RUN apt-get install --no-install-suggests --no-install-recommends -y -qqq tcpdump wireshark-common - -# Faketime for Deckard -RUN apt-get install -y -qqq faketime - -# C dependencies for python-augeas -RUN apt-get install -y -qqq libaugeas-dev libffi-dev -# Python dependencies for Deckard -RUN wget https://gitlab.nic.cz/knot/deckard/raw/master/requirements.txt -O /tmp/deckard-req.txt -RUN pip3 install -r /tmp/deckard-req.txt - -# build and install latest version of Knot DNS -RUN git clone --depth=1 --branch=$KNOT_BRANCH https://gitlab.nic.cz/knot/knot-dns.git /tmp/knot -WORKDIR /tmp/knot -RUN pwd -RUN autoreconf -if -RUN ./configure --prefix=/usr --enable-xdp=yes -RUN CFLAGS="-g" make -RUN make install -RUN ldconfig - -# Valgrind for kresd CI -RUN apt-get install valgrind -y -qqq -RUN wget https://github.com/LuaJIT/LuaJIT/raw/v2.1.0-beta3/src/lj.supp -O /lj.supp -# TODO: rebuild LuaJIT with Valgrind support - -# Lua lint for kresd CI -RUN apt-get install luarocks -y -qqq -RUN luarocks --lua-version 5.1 install luacheck - -# respdiff for kresd CI -RUN apt-get install lmdb-utils -y -qqq -RUN git clone --depth=1 https://gitlab.nic.cz/knot/respdiff /var/opt/respdiff -RUN pip3 install -r /var/opt/respdiff/requirements.txt - -# Python static analysis for respdiff -RUN pip3 install mypy -RUN pip3 install flake8 - -# Python requests for CI scripts -RUN pip3 install requests - -# docker-py for packaging tests -RUN pip3 install docker - -# Unbound for respdiff -RUN apt-get install unbound unbound-anchor -y -qqq -RUN printf "server:\n interface: 127.0.0.1@53535\n use-syslog: yes\n do-ip6: no\nremote-control:\n control-enable: no\n" >> /etc/unbound/unbound.conf - -# BIND for respdiff -RUN apt-get install bind9 -y -qqq -RUN printf '\nOPTIONS="-4 $OPTIONS"' >> /etc/default/bind9 -RUN printf 'options {\n directory "/var/cache/bind";\n listen-on port 53533 { 127.0.0.1; };\n listen-on-v6 port 53533 { ::1; };\n};\n' > /etc/bind/named.conf.options - -# PowerDNS Recursor for Deckard CI -RUN apt-get install pdns-recursor -y -qqq - -# code coverage -RUN apt-get install -y -qqq lcov -RUN luarocks --lua-version 5.1 install luacov - -# LuaJIT binary for stand-alone scripting -RUN apt-get install -y -qqq luajit - -# clang for kresd CI, version updated as debian updates it -RUN apt-get install -y -qqq clang clang-tools clang-tidy - -# OpenBuildService CLI tool -RUN apt-get install -y osc - -# curl (API) -RUN apt-get install -y curl - -# configure knot-resolver-testing OBS repo for dependencies missing in Debian -RUN echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-testing/Debian_10/ /' > /etc/apt/sources.list.d/knot-resolver-testing.list -RUN wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-testing/Debian_10/Release.key -O Release.key -RUN APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key add Release.key -RUN rm Release.key -RUN apt-get update -qq - -# packages from our knot-resolver-testing repo -RUN apt-get install -y -qqq lua-http lua-psl - -# en_US.UTF-8 locale for scripts.update-authors.sh -RUN apt-get install -y -qqq locales -RUN sed -i "/en_US.UTF-8/ s/^#\(.*\)/\1/" /etc/locale.gen -RUN locale-gen - -# SonarCloud scanner -RUN wget -O /var/opt/wrapper.zip https://sonarcloud.io/static/cpp/build-wrapper-linux-x86.zip -RUN wget -O /var/opt/scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.4.0.2170-linux.zip -RUN unzip -d /var/opt /var/opt/wrapper.zip -RUN unzip -d /var/opt /var/opt/scanner.zip -ENV PATH "$PATH:/var/opt/build-wrapper-linux-x86:/var/opt/sonar-scanner-4.4.0.2170-linux/bin" - -# let's get newer meson from backports -RUN echo 'deb http://deb.debian.org/debian buster-backports main' > /etc/apt/sources.list.d/backports.list -RUN apt-get update -qq -RUN apt-get -t buster-backports install -y -qqq meson diff --git a/ci/images/push.sh b/ci/images/push.sh deleted file mode 100755 index 75f5f878..00000000 --- a/ci/images/push.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# upload docker image into registry - -CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" -source "${CURRENT_DIR}"/vars.sh "$@" -set -ex - -docker push "${FULL_NAME}" diff --git a/ci/images/update.sh b/ci/images/update.sh deleted file mode 100755 index 7be51727..00000000 --- a/ci/images/update.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# build and upload docker image(s) into registry -# -# this is a simple wrapper around build.sh and update.sh -# -# to build & upload all images: ./update.sh */ - -if [[ $# -le 0 ]]; then - echo "usage: $0 IMAGE..." - exit 1 -fi -set -e - -for ARG in "$@" -do - IMAGE=${ARG%/} - echo "Building $IMAGE..." - ./build.sh $IMAGE - echo "Pushing $IMAGE..." - ./push.sh $IMAGE -done - diff --git a/ci/images/vars.sh b/ci/images/vars.sh deleted file mode 100755 index f2ea4655..00000000 --- a/ci/images/vars.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -# define common variables for image build scripts - -KNOT_BRANCH="${KNOT_BRANCH:-3.1}" - -REGISTRY="registry.nic.cz/knot/knot-resolver/ci" -IMAGE=$1 -if [ -z "${IMAGE}" ]; then - echo "image name not provided" - exit 1 -fi -TAG="knot-${KNOT_BRANCH}" -FULL_NAME="${REGISTRY}/${IMAGE}:${TAG}" diff --git a/daemon/bindings/net.c b/daemon/bindings/net.c index d278ed17..aaeef238 100644 --- a/daemon/bindings/net.c +++ b/daemon/bindings/net.c @@ -468,7 +468,7 @@ static int net_interfaces(lua_State *L) /* Hardware address. */ char *p = buf; for (int k = 0; k < sizeof(iface.phys_addr); ++k) { - sprintf(p, "%.2x:", (uint8_t)iface.phys_addr[k]); + (void)sprintf(p, "%.2x:", (uint8_t)iface.phys_addr[k]); p += 3; } p[-1] = '\0'; @@ -788,7 +788,7 @@ static int net_tls_client(lua_State *L) /* Sort the strings for easier comparison later. */ if (newcfg->ca_files.len) { qsort(&newcfg->ca_files.at[0], newcfg->ca_files.len, - sizeof(newcfg->ca_files.at[0]), strcmp_p); + array_member_size(newcfg->ca_files), strcmp_p); } } lua_pop(L, 1); @@ -828,7 +828,7 @@ static int net_tls_client(lua_State *L) /* Sort the raw strings for easier comparison later. */ if (newcfg->pins.len) { qsort(&newcfg->pins.at[0], newcfg->pins.len, - sizeof(newcfg->pins.at[0]), cmp_sha256); + array_member_size(newcfg->pins), cmp_sha256); } } lua_pop(L, 1); @@ -1031,7 +1031,11 @@ static int net_tls_sticket_secret_file(lua_State *L) STR(net_tls_sticket_MIN_SECRET_LEN) " bytes", file_name); } - fclose(fp); + if (fclose(fp) == EOF) { + lua_error_p(L, + "net.tls_sticket_secret_file - reading of file '%s' failed", + file_name); + } tls_session_ticket_ctx_destroy(the_network->tls_session_ticket_ctx); the_network->tls_session_ticket_ctx = diff --git a/daemon/engine.c b/daemon/engine.c index 275718ee..509915df 100644 --- a/daemon/engine.c +++ b/daemon/engine.c @@ -29,8 +29,6 @@ #include "lib/dnssec/ta.h" #include "lib/log.h" -/* Cleanup engine state every 5 minutes */ -const size_t CLEANUP_TIMER = 5*60*1000; /* Execute byte code */ #define l_dobytecode(L, arr, len, name) \ @@ -544,7 +542,7 @@ int init_lua(void) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat" /* %1$ is not in C standard */ /* Save original package.path to package._path */ - snprintf(l_paths, MAXPATHLEN - 1, + (void)snprintf(l_paths, MAXPATHLEN - 1, "if package._path == nil then package._path = package.path end\n" "package.path = '%1$s/?.lua;%1$s/?/init.lua;'..package._path\n" "if package._cpath == nil then package._cpath = package.cpath end\n" diff --git a/daemon/io.c b/daemon/io.c index ea98a7f0..a32f5a3f 100644 --- a/daemon/io.c +++ b/daemon/io.c @@ -107,7 +107,7 @@ static int family_to_freebind_option(sa_family_t sa_family, int *level, int *nam #define LOG_NO_FB kr_log_error(NETWORK, "your system does not support 'freebind', " \ "please remove it from your configuration\n") switch (sa_family) { - case AF_INET: + case AF_INET: // NOLINT(bugprone-branch-clone): The branches are only cloned for specific macro configs *level = IPPROTO_IP; #if defined(IP_FREEBIND) *name = IP_FREEBIND; @@ -790,18 +790,27 @@ void io_tty_process_input(uv_stream_t *stream, ssize_t nread, const uv_buf_t *bu len_s = 0; } uint32_t len_n = htonl(len_s); - fwrite(&len_n, sizeof(len_n), 1, out); - if (len_s > 0) - fwrite(message, len_s, 1, out); + if (fwrite(&len_n, sizeof(len_n), 1, out) != 1) + goto finish; + if (len_s > 0) { + if (fwrite(message, len_s, 1, out) != 1) + goto finish; + } break; case IO_MODE_TEXT: /* Human-readable and console-printable mode */ - if (message) - fprintf(out, "%s", message); - if (message || !args->quiet) - fprintf(out, "\n"); - if (!args->quiet) - fprintf(out, "> "); + if (message) { + if (fprintf(out, "%s", message) < 0) + goto finish; + } + if (message || !args->quiet) { + if (fprintf(out, "\n") < 0) + goto finish; + } + if (!args->quiet) { + if (fprintf(out, "> ") < 0) + goto finish; + } break; } @@ -824,7 +833,7 @@ void io_tty_process_input(uv_stream_t *stream, ssize_t nread, const uv_buf_t *bu finish: /* Close if redirected */ if (stream_fd != STDIN_FILENO) { - fclose(out); + (void)fclose(out); } /* If a LMDB transaction got open, we can't leave it hanging. * We accept the changes, if any. */ diff --git a/daemon/main.c b/daemon/main.c index 53ecb3e8..8185c1c6 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -447,9 +447,9 @@ int main(int argc, char **argv) { kr_log_group_reset(); if (setvbuf(stdout, NULL, _IONBF, 0) || setvbuf(stderr, NULL, _IONBF, 0)) { - kr_log_error(SYSTEM, "failed to to set output buffering (ignored): %s\n", + kr_log_error(SYSTEM, "failed to set output buffering (ignored): %s\n", strerror(errno)); - fflush(stderr); + (void)fflush(stderr); } if (strcmp("linux", OPERATING_SYSTEM) != 0) kr_log_warning(SYSTEM, "Knot Resolver is tested on Linux, other platforms might exhibit bugs.\n" @@ -512,7 +512,7 @@ int main(int argc, char **argv) if (ret) { kr_log_error(SYSTEM, "failed to get or set file-descriptor limit: %s\n", strerror(errno)); - } else if (rlim.rlim_cur < 512*1024) { + } else if (rlim.rlim_cur < (rlim_t)512 * 1024) { kr_log_warning(SYSTEM, "warning: hard limit for number of file-descriptors is only %ld but recommended value is 524288\n", (long)rlim.rlim_cur); } diff --git a/daemon/proxyv2.c b/daemon/proxyv2.c index 73eb5769..ce0ea0a6 100644 --- a/daemon/proxyv2.c +++ b/daemon/proxyv2.c @@ -277,6 +277,7 @@ ssize_t proxy_process_header(struct proxy_result *out, &addr->ipv6_addr.dst_addr, sizeof(out->dst_addr.ip6.sin6_addr.s6_addr)); break; + default:; /* Keep zero from initializer. */ } /* Process additional information */ @@ -285,7 +286,7 @@ ssize_t proxy_process_header(struct proxy_result *out, case TLV_TYPE_SSL: out->has_tls = true; break; - /* TODO: add more TLV types if needed */ + default:; /* Ignore others - add more if needed */ } } diff --git a/daemon/tls.c b/daemon/tls.c index e8dff76c..09c99508 100644 --- a/daemon/tls.c +++ b/daemon/tls.c @@ -24,7 +24,7 @@ #include "daemon/worker.h" #include "daemon/session2.h" -#define EPHEMERAL_CERT_EXPIRATION_SECONDS_RENEW_BEFORE (60*60*24*7) +#define EPHEMERAL_CERT_EXPIRATION_SECONDS_RENEW_BEFORE ((time_t)60*60*24*7) #define GNUTLS_PIN_MIN_VERSION 0x030400 #define UNWRAP_BUF_SIZE 131072 #define TLS_CHUNK_SIZE (16 * 1024) @@ -442,7 +442,7 @@ static int str_replace(char **where_ptr, const char *with) return kr_ok(); } -static time_t _get_end_entity_expiration(gnutls_certificate_credentials_t creds) +static time_t get_end_entity_expiration(gnutls_certificate_credentials_t creds) { gnutls_datum_t data; gnutls_x509_crt_t cert = NULL; @@ -514,7 +514,7 @@ int tls_certificate_set(const char *tls_cert, const char *tls_key) return kr_error(EINVAL); } /* record the expiration date: */ - tls_credentials->valid_until = _get_end_entity_expiration(tls_credentials->credentials); + tls_credentials->valid_until = get_end_entity_expiration(tls_credentials->credentials); /* Exchange the x509 credentials */ struct tls_credentials *old_credentials = the_network->tls_credentials; diff --git a/daemon/tls.h b/daemon/tls.h index b8cf7af6..9fd45fb6 100644 --- a/daemon/tls.h +++ b/daemon/tls.h @@ -30,7 +30,7 @@ * So it takes 2 RTT. * As we use session tickets, there are additional messages, add one RTT mode. */ -#define TLS_MAX_HANDSHAKE_TIME (KR_CONN_RTT_MAX * 3) +#define TLS_MAX_HANDSHAKE_TIME (KR_CONN_RTT_MAX * (uint64_t)3) /** Transport session (opaque). */ struct session2; diff --git a/daemon/tls_ephemeral_credentials.c b/daemon/tls_ephemeral_credentials.c index a27dcd2d..768942bb 100644 --- a/daemon/tls_ephemeral_credentials.c +++ b/daemon/tls_ephemeral_credentials.c @@ -17,19 +17,19 @@ #define EPHEMERAL_PRIVKEY_FILENAME "ephemeral_key.pem" #define INVALID_HOSTNAME "dns-over-tls.invalid" -#define EPHEMERAL_CERT_EXPIRATION_SECONDS (60*60*24*90) +#define EPHEMERAL_CERT_EXPIRATION_SECONDS ((time_t)60*60*24*90) /* This is an attempt to grab an exclusive, advisory, non-blocking * lock based on a filename. At the moment it's POSIX-only, but it * should be abstract enough of an interface to make an implementation * for non-posix systems if anyone cares. */ typedef int lock_t; -static bool _lock_is_invalid(lock_t lock) +static bool lock_is_invalid(lock_t lock) { return lock == -1; } /* a blocking lock on a given filename */ -static lock_t _lock_filename(const char *fname) +static lock_t lock_filename(const char *fname) { lock_t lockfd = open(fname, O_RDONLY|O_CREAT, 0400); if (lockfd == -1) @@ -41,9 +41,9 @@ static lock_t _lock_filename(const char *fname) } return lockfd; /* for cleanup later */ } -static void _lock_unlock(lock_t *lock, const char *fname) +static void lock_unlock(lock_t *lock, const char *fname) { - if (lock && !_lock_is_invalid(*lock)) { + if (lock && !lock_is_invalid(*lock)) { flock(*lock, LOCK_UN); close(*lock); *lock = -1; @@ -61,8 +61,8 @@ static gnutls_x509_privkey_t get_ephemeral_privkey (void) /* Take a lock to ensure that two daemons started concurrently * with a shared cache don't both create the same privkey: */ - lock = _lock_filename(EPHEMERAL_PRIVKEY_FILENAME ".lock"); - if (_lock_is_invalid(lock)) { + lock = lock_filename(EPHEMERAL_PRIVKEY_FILENAME ".lock"); + if (lock_is_invalid(lock)) { kr_log_error(TLS, "unable to lock lockfile " EPHEMERAL_PRIVKEY_FILENAME ".lock\n"); goto done; } @@ -141,7 +141,7 @@ static gnutls_x509_privkey_t get_ephemeral_privkey (void) } } done: - _lock_unlock(&lock, EPHEMERAL_PRIVKEY_FILENAME ".lock"); + lock_unlock(&lock, EPHEMERAL_PRIVKEY_FILENAME ".lock"); if (datafd != -1) { close(datafd); } @@ -220,7 +220,7 @@ struct tls_credentials * tls_get_ephemeral_credentials(void) if ((privkey = get_ephemeral_privkey()) == NULL) { goto failure; } - if ((cert = get_ephemeral_cert(privkey, creds->ephemeral_servicename, now - 60*15, creds->valid_until)) == NULL) { + if ((cert = get_ephemeral_cert(privkey, creds->ephemeral_servicename, now - ((time_t)60 * 15), creds->valid_until)) == NULL) { goto failure; } if ((err = gnutls_certificate_set_x509_key(creds->credentials, &cert, 1, privkey)) < 0) { diff --git a/daemon/tls_session_ticket-srv.c b/daemon/tls_session_ticket-srv.c index b1989030..26d41862 100644 --- a/daemon/tls_session_ticket-srv.c +++ b/daemon/tls_session_ticket-srv.c @@ -188,7 +188,7 @@ static void tst_key_check(uv_timer_t *timer, bool force_update) const uint64_t remain_ms = (tv_sec_next - now.tv_sec - 1) * (uint64_t)1000 + ms_until_second + 1; /* ^ +1 because we don't want to wake up half a millisecond before the epoch! */ - if (kr_fails_assert(remain_ms < (TST_KEY_LIFETIME + 1 /*rounding tolerance*/) * 1000)) + if (kr_fails_assert(remain_ms < ((uint64_t)TST_KEY_LIFETIME + 1 /*rounding tolerance*/) * 1000)) return; kr_log_debug(TLS, "session ticket: epoch %"PRIu64 ", scheduling rotation check in %"PRIu64" ms\n", diff --git a/daemon/udp_queue.c b/daemon/udp_queue.c index a03af8d7..68d67ec6 100644 --- a/daemon/udp_queue.c +++ b/daemon/udp_queue.c @@ -112,11 +112,11 @@ void udp_queue_push(int fd, const struct sockaddr *sa, char *buf, size_t buf_len /* Get a valid correct queue. */ if (fd >= state.udp_queues_len) { const int new_len = fd + 1; - state.udp_queues = realloc(state.udp_queues, - sizeof(state.udp_queues[0]) * new_len); + state.udp_queues = realloc(state.udp_queues, // NOLINT(bugprone-suspicious-realloc-usage): we just abort() below, so it's fine + sizeof(state.udp_queues[0]) * new_len); // NOLINT(bugprone-sizeof-expression): false-positive if (!state.udp_queues) abort(); memset(state.udp_queues + state.udp_queues_len, 0, - sizeof(state.udp_queues[0]) * (new_len - state.udp_queues_len)); + sizeof(state.udp_queues[0]) * (new_len - state.udp_queues_len)); // NOLINT(bugprone-sizeof-expression): false-positive state.udp_queues_len = new_len; } if (unlikely(state.udp_queues[fd] == NULL)) diff --git a/daemon/worker.c b/daemon/worker.c index 2d293ba9..2e9f4523 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -194,7 +194,7 @@ static inline struct mempool *pool_borrow(void) { /* The implementation used to have extra caching layer, * but it didn't work well. Now it's very simple. */ - return mp_new(16 * 1024); + return mp_new((size_t)16 * 1024); } /** Return a mempool. */ static inline void pool_release(struct mempool *mp) diff --git a/daemon/zimport.c b/daemon/zimport.c index 8d395270..30edcaec 100644 --- a/daemon/zimport.c +++ b/daemon/zimport.c @@ -98,7 +98,7 @@ static int key_get(char buf[KEY_LEN], const knot_dname_t *name, char *lf = (char *)knot_dname_lf(name, (uint8_t *)buf); if (kr_fails_assert(lf && key_p)) return kr_error(EINVAL); - int len = lf[0]; + int len = (unsigned char)lf[0]; lf++; // point to start of data *key_p = lf; // Check that LF is right-aligned to KNOT_DNAME_MAXLEN in buf. @@ -282,7 +282,7 @@ do_digest: // hexdump the hash for logging char hash_str[digs[i].size * 2 + 1]; for (ssize_t j = 0; j < digs[i].size; ++j) - sprintf(hash_str + 2*j, "%02x", digs[i].data[j]); + (void)sprintf(hash_str + 2*j, "%02x", digs[i].data[j]); if (!z_import->digests[i].expected) { kr_log_error(PREFILL, "no ZONEMD found; computed hash: %s\n", @@ -560,7 +560,7 @@ int zi_zone_import(const zi_config_t config) if (kr_fails_assert(c && c->zone_file)) return kr_error(EINVAL); - knot_mm_t *pool = mm_ctx_mempool2(1024 * 1024); + knot_mm_t *pool = mm_ctx_mempool2((size_t)1024 * 1024); zone_import_ctx_t *z_import = mm_calloc(pool, 1, sizeof(*z_import)); if (!z_import) return kr_error(ENOMEM); z_import->pool = pool; diff --git a/lib/cache/peek.c b/lib/cache/peek.c index 8ab4878b..d12031fc 100644 --- a/lib/cache/peek.c +++ b/lib/cache/peek.c @@ -174,6 +174,7 @@ int peek_nosync(kr_layer_t *ctx, knot_pkt_t *pkt) knot_db_val_bound(v), new_ttl); return ret == kr_ok() ? KR_STATE_DONE : ctx->state; } + default:; // Continue below } /* We have to try proving from NSEC*. */ diff --git a/lib/dnssec.c b/lib/dnssec.c index 9f43bb83..77cec796 100644 --- a/lib/dnssec.c +++ b/lib/dnssec.c @@ -362,7 +362,7 @@ static int kr_rrset_validate_with_key(kr_rrset_validation_ctx_t *vctx, const int covered_labels = knot_dname_labels(covered->owner, NULL) - knot_dname_is_wildcard(covered->owner); - for (uint16_t i = 0; i < vctx->rrs->len; ++i) { + for (size_t i = 0; i < vctx->rrs->len; ++i) { /* Consider every RRSIG that matches and comes from the same query. */ const knot_rrset_t *rrsig = vctx->rrs->at[i]->rr; const bool ok = vctx->rrs->at[i]->qry_uid == vctx->qry_uid diff --git a/lib/generic/array.h b/lib/generic/array.h index 9f351189..9bea546b 100644 --- a/lib/generic/array.h +++ b/lib/generic/array.h @@ -113,7 +113,7 @@ static inline void array_std_free(void *baton, void *p) * Mempool usage: pass kr_memreserve and a knot_mm_t* . * @return 0 if success, <0 on failure */ #define array_reserve_mm(array, n, reserve, baton) \ - (reserve)((baton), (void **) &(array).at, sizeof((array).at[0]), (n), &(array).cap) + (reserve)((baton), (void **) &(array).at, array_member_size((array)), (n), &(array).cap) /** * Push value at the end of the array, resize it if necessary. @@ -122,9 +122,9 @@ static inline void array_std_free(void *baton, void *p) * @return element index on success, <0 on failure */ #define array_push_mm(array, val, reserve, baton) \ - (int)((array).len < (array).cap ? ((array).at[(array).len] = val, (array).len++) \ + (int)((array).len < (array).cap ? ((array).at[(array).len] = (val), (array).len++) \ : (array_reserve_mm(array, ((array).cap + 1), reserve, baton) < 0 ? -1 \ - : ((array).at[(array).len] = val, (array).len++))) + : ((array).at[(array).len] = (val), (array).len++))) /** * Push value at the end of the array, resize it if necessary (plain malloc/free). @@ -152,6 +152,12 @@ static inline void array_std_free(void *baton, void *p) * @warning Undefined if the array is empty. */ #define array_tail(array) \ - (array).at[(array).len - 1] + (array).at[(array).len - 1] + +/** + * Return the size of a singular member in the array. + */ +#define array_member_size(array) \ + (sizeof((array).at[0])) // NOLINT(bugprone-sizeof-expression): usually a false-positive /** @} */ diff --git a/lib/generic/lru.h b/lib/generic/lru.h index 448c1b92..1c1dd81a 100644 --- a/lib/generic/lru.h +++ b/lib/generic/lru.h @@ -130,7 +130,10 @@ #define lru_get_new(table, key_, len_, is_new) \ (__typeof__((table)->pdata_t)) \ lru_get_impl(&(table)->lru, (key_), (len_), \ - sizeof(*(table)->pdata_t), true, is_new) + lru_member_size((table)), true, is_new) + +#define lru_member_size(table) \ + (sizeof(*(table)->pdata_t)) // NOLINT(bugprone-sizeof-expression): usually a false-positive /** * @brief Apply a function to every item in LRU. diff --git a/lib/generic/queue.c b/lib/generic/queue.c index 5bed153e..29609dd2 100644 --- a/lib/generic/queue.c +++ b/lib/generic/queue.c @@ -62,7 +62,7 @@ void * queue_push_impl(struct queue *q) if (t->begin * 2 >= t->cap) { /* Utilization is below 50%, so let's shift (no overlap). * (size_t cast is to avoid unintended sign-extension) */ - memcpy(t->data, t->data + t->begin * q->item_size, + memcpy(t->data, t->data + t->begin * (size_t)q->item_size, (size_t) (t->end - t->begin) * (size_t) q->item_size); t->end -= t->begin; t->begin = 0; @@ -76,7 +76,7 @@ void * queue_push_impl(struct queue *q) kr_require(t->end < t->cap); ++(q->len); ++(t->end); - return t->data + q->item_size * (t->end - 1); + return t->data + (size_t)q->item_size * (t->end - 1); } /* Return pointer to the space for the new element. */ @@ -98,8 +98,8 @@ void * queue_push_head_impl(struct queue *q) * Computations here are simplified due to h->begin == 0. * (size_t cast is to avoid unintended sign-extension) */ const int cnt = h->end; - memcpy(h->data + (h->cap - cnt) * q->item_size, h->data, - (size_t) cnt * (size_t) q->item_size); + memcpy(h->data + ((size_t)h->cap - cnt) * q->item_size, h->data, + (size_t)cnt * (size_t)q->item_size); h->begin = h->cap - cnt; h->end = h->cap; } else { @@ -113,7 +113,7 @@ void * queue_push_head_impl(struct queue *q) kr_require(h->begin > 0); --(h->begin); ++(q->len); - return h->data + q->item_size * h->begin; + return h->data + (size_t)q->item_size * h->begin; } void queue_pop_impl(struct queue *q) diff --git a/lib/generic/queue.h b/lib/generic/queue.h index 3fa52cea..fc2a86f3 100644 --- a/lib/generic/queue.h +++ b/lib/generic/queue.h @@ -71,7 +71,7 @@ /** @brief Initialize a queue. You can malloc() it the usual way. */ #define queue_init(q) do { \ (void)(((__typeof__(((q).pdata_t)))0) == (void *)0); /* typecheck queue_t */ \ - queue_init_impl(&(q).queue, sizeof(*(q).pdata_t)); \ + queue_init_impl(&(q).queue, queue_member_size((q))); \ } while (false) /** @brief De-initialize a queue: make it invalid and free any inner allocations. */ @@ -105,6 +105,10 @@ #define queue_len(q) \ ((const size_t)(q).queue.len) +/** @brief Return the size of a single element in the queue. */ +#define queue_member_size(q) \ + (sizeof(*(q).pdata_t)) // NOLINT(bugprone-sizeof-expression): usually a false-positive + /** @brief Type for queue iterator, parametrized by value type. * It's a simple structure that owns no other resources. diff --git a/lib/generic/trie.c b/lib/generic/trie.c index f9aceda7..21254eb4 100644 --- a/lib/generic/trie.c +++ b/lib/generic/trie.c @@ -470,6 +470,10 @@ static int ns_longer_alloc(nstack_t *ns) memcpy(st, ns->stack, ns->len * sizeof(node_t *)); } else { st = realloc(ns->stack, new_size); + if (st == NULL) { + free(ns->stack); // left behind by realloc, callers bail out + ns->stack = NULL; + } } if (st == NULL) return KNOT_ENOMEM; diff --git a/lib/layer/validate.c b/lib/layer/validate.c index 3bdb205c..af20b2e4 100644 --- a/lib/layer/validate.c +++ b/lib/layer/validate.c @@ -709,7 +709,7 @@ static int check_validation_result(kr_layer_t *ctx, const knot_pkt_t *pkt, ranke invalid_entry = entry; break; } else if (kr_rank_test(entry->rank, KR_RANK_MISSING) && - !invalid_entry) { + !invalid_entry) { // NOLINT(bugprone-branch-clone) invalid_entry = entry; } else if (kr_rank_test(entry->rank, KR_RANK_OMIT)) { continue; @@ -126,7 +126,7 @@ void kr_log_fmt(enum kr_log_group group, kr_log_level_t level, const char *file, } va_start(args, fmt); - vfprintf(stream, fmt, args); + (void)vfprintf(stream, fmt, args); va_end(args); } } diff --git a/lib/resolve.c b/lib/resolve.c index e8a63489..ec00b215 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -715,6 +715,8 @@ int kr_resolve_consume(struct kr_request *request, struct kr_transport **transpo if (transport && !qry->flags.CACHED) { if (!(request->state & KR_STATE_FAIL)) { /* Do not complete NS address resolution on soft-fail. */ + if (kr_fails_assert(packet->wire)) + return KR_STATE_FAIL; const int rcode = knot_wire_get_rcode(packet->wire); if (rcode != KNOT_RCODE_SERVFAIL && rcode != KNOT_RCODE_REFUSED) { qry->flags.AWAIT_IPV6 = false; @@ -748,7 +750,7 @@ int kr_resolve_consume(struct kr_request *request, struct kr_transport **transpo } /* Pop query if resolved. */ - if (request->state == KR_STATE_YIELD) { + if (request->state == KR_STATE_YIELD) { // NOLINT(bugprone-branch-clone) return KR_STATE_PRODUCE; /* Requery */ } else if (qry->flags.RESOLVED) { kr_rplan_pop(rplan, qry); @@ -931,6 +933,7 @@ int kr_resolve_finish(struct kr_request *request, int state) knot_wire_clear_ad(wire); knot_wire_clear_aa(wire); knot_wire_set_rcode(wire, KNOT_RCODE_SERVFAIL); + default:; // Do nothing } } } diff --git a/lib/selection.c b/lib/selection.c index ea3a85ae..9cdd1a60 100644 --- a/lib/selection.c +++ b/lib/selection.c @@ -149,7 +149,7 @@ struct rtt_state get_rtt_state(const uint8_t *ip, size_t len, knot_db_val_t key = cache_key(ip, len); - if (cache->api->read(db, stats, &key, &value, 1)) { + if (cache->api->read(db, stats, &key, &value, 1)) { // NOLINT(bugprone-branch-clone) state = default_rtt_state; } else if (kr_fails_assert(value.len == sizeof(struct rtt_state))) { // shouldn't happen but let's be more robust diff --git a/lib/utils.c b/lib/utils.c index 8b7e1270..2a0635e0 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -921,9 +921,8 @@ int kr_ranked_rrarray_add(ranked_rr_array_t *array, const knot_rrset_t *rr, static int rdata_p_cmp(const void *rp1, const void *rp2) { /* Just correct types of the parameters and pass them dereferenced. */ - const knot_rdata_t - *const *r1 = rp1, - *const *r2 = rp2; + const knot_rdata_t *const *r1 = (const knot_rdata_t *const *)rp1; + const knot_rdata_t *const *r2 = (const knot_rdata_t *const *)rp2; return knot_rdata_cmp(*r1, *r2); } int kr_ranked_rrarray_finalize(ranked_rr_array_t *array, uint32_t qry_uid, knot_mm_t *pool) @@ -948,7 +947,7 @@ int kr_ranked_rrarray_finalize(ranked_rr_array_t *array, uint32_t qry_uid, knot_ } else { /* Multiple RRs; first: sort the array. */ stashed->rr->additional = NULL; - qsort(ra->at, ra->len, sizeof(ra->at[0]), rdata_p_cmp); + qsort((void *)ra->at, ra->len, array_member_size(*ra), rdata_p_cmp); /* Prune duplicates: NULL all except the last instance. */ int dup_count = 0; for (int i = 0; i + 1 < ra->len; ++i) { diff --git a/modules/dnstap/dnstap.c b/modules/dnstap/dnstap.c index ab52bca3..6fcc192c 100644 --- a/modules/dnstap/dnstap.c +++ b/modules/dnstap/dnstap.c @@ -193,6 +193,7 @@ static int dnstap_log(kr_layer_t *ctx, enum dnstap_log_phase phase) { m.socket_family = DNSTAP__SOCKET_FAMILY__INET6; m.has_socket_family = true; break; + default:; } } diff --git a/modules/hints/meson.build b/modules/hints/meson.build index d5046cb4..7e681f11 100644 --- a/modules/hints/meson.build +++ b/modules/hints/meson.build @@ -18,5 +18,5 @@ hints_mod = shared_module( ) config_tests += [ - ['hints', files('tests/hints.test.lua'), ['skip_asan']], + ['hints', files('tests/hints.test.lua')], ] diff --git a/modules/http/meson.build b/modules/http/meson.build index 9d20c929..7d892159 100644 --- a/modules/http/meson.build +++ b/modules/http/meson.build @@ -21,7 +21,7 @@ lua_mod_src += [ config_tests += [ ['http', files('http.test.lua')], ['http.doh', files('http_doh.test.lua')], - ['http.tls', files('test_tls/tls.test.lua')], + ['http.tls', files('test_tls/tls.test.lua'), ['skip_asan']], ] # install static files diff --git a/modules/stats/stats.c b/modules/stats/stats.c index a8a29de2..d0386738 100644 --- a/modules/stats/stats.c +++ b/modules/stats/stats.c @@ -125,7 +125,7 @@ static inline int collect_key(char *key, const knot_dname_t *name, uint16_t type if (key_len < 0) { return kr_error(key_len); } - return key_len + sizeof(type); + return key_len + (int)sizeof(type); } static void collect_sample(struct stat_data *data, struct kr_rplan *rplan) @@ -323,26 +323,26 @@ static char* stats_get(void *env, struct kr_module *module, const char *args) struct stat_data *data = module->data; /* Expecting CHAR_BIT to be 8, this is a safe bet */ - char *ret = malloc(3 * sizeof(size_t) + 2); - if (!ret) { - return NULL; - } + char *str_value = NULL; + int ret = 0; /* Check if it exists in const map. */ for (unsigned i = 0; i < metric_const_end; ++i) { if (strcmp(const_metrics[i].key, args) == 0) { - sprintf(ret, "%zu", const_metrics[i].val); - return ret; + ret = asprintf(&str_value, "%zu", const_metrics[i].val); + if (ret < 0) + return NULL; + return str_value; } } /* Check in variable map */ trie_val_t *val = trie_get_try(data->trie, args, strlen(args)); - if (!val) { - free(ret); + if (!val) return NULL; - } - sprintf(ret, "%zu", (size_t) *val); - return ret; + ret = asprintf(&str_value, "%zu", (size_t) *val); + if (ret < 0) + return NULL; + return str_value; } /** Checks whether: @@ -366,7 +366,7 @@ static int list_entry(const char *key, uint32_t key_len, trie_val_t *val, void * struct list_entry_context *ctx = baton; if (!key_matches_prefix(key, key_len, ctx->key_prefix, ctx->key_prefix_len)) return 0; - size_t number = (size_t) *val; + size_t number = (size_t)*val; uint32_t dot_index = 0; for (uint32_t i = 0; i < key_len; i++) { @@ -387,10 +387,10 @@ static int list_entry(const char *key, uint32_t key_len, trie_val_t *val, void * } if (kr_fails_assert(sup)) return 0; - json_append_member(sup, sub_key_nt, json_mknumber(number)); + json_append_member(sup, sub_key_nt, json_mknumber((double)number)); } else { auto_free char *key_nt = strndup(key, key_len); - json_append_member(ctx->root, key_nt, json_mknumber(number)); + json_append_member(ctx->root, key_nt, json_mknumber((double)number)); } return 0; } @@ -415,7 +415,7 @@ static char* stats_list(void *env, struct kr_module *module, const char *args) } if (kr_fails_assert(sup)) break; - json_append_member(sup, elm->sub_key, json_mknumber(elm->val)); + json_append_member(sup, elm->sub_key, json_mknumber((double)elm->val)); } } struct list_entry_context ctx = { diff --git a/tests/config/meson.build b/tests/config/meson.build index a739222d..dc345a88 100644 --- a/tests/config/meson.build +++ b/tests/config/meson.build @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later config_tests += [ - ['basic', files('basic.test.lua'), ['skip_asan']], - ['cache', files('cache.test.lua'), ['skip_asan']], + ['basic', files('basic.test.lua')], + ['cache', files('cache.test.lua')], ['net', files('net.test.lua'), ['config_net']], ['doh2', files('doh2.test.lua')], ['lru', files('lru.test.lua')], diff --git a/tests/dnstap/src/dnstap-test/go.mod b/tests/dnstap/src/dnstap-test/go.mod index 6b650889..2eb72879 100644 --- a/tests/dnstap/src/dnstap-test/go.mod +++ b/tests/dnstap/src/dnstap-test/go.mod @@ -1,6 +1,6 @@ module gitlab.nic.cz/knot/knot-resolver/tests/dnstap-test -go 1.17 +go 1.15 require ( github.com/cloudflare/dns v0.0.0-20151007113418-e20ffa3da443 diff --git a/tests/dnstap/src/dnstap-test/go.sum b/tests/dnstap/src/dnstap-test/go.sum deleted file mode 100644 index 1860f9ef..00000000 --- a/tests/dnstap/src/dnstap-test/go.sum +++ /dev/null @@ -1,44 +0,0 @@ -github.com/cloudflare/dns v0.0.0-20151007113418-e20ffa3da443 h1:dYR6/V5rx/uaHsy4m1JuWfKYZO0r+G89BLD+XN7s9AI= -github.com/cloudflare/dns v0.0.0-20151007113418-e20ffa3da443/go.mod h1:pa4p3oKOxzbXjrV5AGD1v5xjL7skv9BvO4J0Llo3P+s= -github.com/dnstap/golang-dnstap v0.4.0 h1:KRHBoURygdGtBjDI2w4HifJfMAhhOqDuktAokaSa234= -github.com/dnstap/golang-dnstap v0.4.0/go.mod h1:FqsSdH58NAmkAvKcpyxht7i4FoBjKu8E4JUPt8ipSUs= -github.com/farsightsec/golang-framestream v0.3.0 h1:/spFQHucTle/ZIPkYqrfshQqPe2VQEzesH243TjIwqA= -github.com/farsightsec/golang-framestream v0.3.0/go.mod h1:eNde4IQyEiA5br02AouhEHCu3p3UzrCdFR4LuQHklMI= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo= -github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe h1:6fAMxZRR6sl1Uq8U61gxU+kPTs2tR8uOySCbBP7BN/M= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/tests/dnstap/src/dnstap-test/run.sh b/tests/dnstap/src/dnstap-test/run.sh index 37822b75..70d82254 100755 --- a/tests/dnstap/src/dnstap-test/run.sh +++ b/tests/dnstap/src/dnstap-test/run.sh @@ -8,16 +8,13 @@ echo "$GOPATH" cd "$(dirname $0)" DNSTAP_TEST=dnstap-test -if [ -z "$GITLAB_CI" ]; then - type -P go >/dev/null || exit 77 - echo "Building the dnstap test and its dependencies..." - # some packages may be missing on the system right now - go get . -else - # In CI we've prebuilt dependencies into the default GOPATH. - # We're in a scratch container, so we just add the dnstap test inside. - export GOPATH=/root/go -fi +go mod tidy + +type -P go >/dev/null || exit 77 +echo "Building the dnstap test and its dependencies..." +# some packages may be missing on the system right now +go get . + DTAP_DIR="$GOPATH/src" DTAP="$DTAP_DIR/$DNSTAP_TEST" mkdir -p "$DTAP_DIR" diff --git a/tests/pytests/conftest.py b/tests/pytests/conftest.py index 4c711f84..fcf4b05f 100644 --- a/tests/pytests/conftest.py +++ b/tests/pytests/conftest.py @@ -86,7 +86,7 @@ def query_before(request): # whether to send an initial query return request.param -@pytest.mark.optionalhook +@pytest.hookimpl(optionalhook=True) def pytest_metadata(metadata): # filter potentially sensitive data from GitLab CI keys_to_delete = [] for key in metadata.keys(): diff --git a/tests/pytests/test_tls.py b/tests/pytests/test_tls.py index 3e1328ab..2187efbc 100644 --- a/tests/pytests/test_tls.py +++ b/tests/pytests/test_tls.py @@ -1,15 +1,8 @@ # SPDX-License-Identifier: GPL-3.0-or-later """TLS-specific tests""" -import itertools -import os -from socket import AF_INET, AF_INET6 import ssl -import sys - import pytest - -from kresd import make_kresd import utils @@ -41,43 +34,3 @@ def test_tls_cert_hostname_mismatch(kresd_tt, sock_family): with pytest.raises(ssl.CertificateError): ssock.connect(dest) - - -@pytest.mark.skipif(sys.version_info < (3, 6), - reason="requires python3.6 or higher") -@pytest.mark.parametrize('sf1, sf2, sf3', itertools.product( - [AF_INET, AF_INET6], [AF_INET, AF_INET6], [AF_INET, AF_INET6])) -def test_tls_session_resumption(tmpdir, sf1, sf2, sf3): - """Attempt TLS session resumption against the same kresd instance and a different one.""" - # TODO ensure that session can't be resumed after session ticket key regeneration - # at the first kresd instance - - # NOTE TLS 1.3 is intentionally disabled for session resumption tests, - # because python's SSLSocket.session isn't compatible with TLS 1.3 - # https://docs.python.org/3/library/ssl.html?highlight=ssl%20ticket#tls-1-3 - - def connect(kresd, ctx, sf, session=None): - sock, dest = kresd.stream_socket(sf, tls=True) - ssock = ctx.wrap_socket( - sock, server_hostname='transport-test-server.com', session=session) - ssock.connect(dest) - new_session = ssock.session - assert new_session.has_ticket - assert ssock.session_reused == (session is not None) - utils.ping_alive(ssock) - ssock.close() - return new_session - - workdir = os.path.join(str(tmpdir), 'kresd') - os.makedirs(workdir) - - with make_kresd(workdir, 'tt') as kresd: - ctx = utils.make_ssl_context( - verify_location=kresd.tls_cert_path, extra_options=[ssl.OP_NO_TLSv1_3]) - session = connect(kresd, ctx, sf1) # initial conn - connect(kresd, ctx, sf2, session) # resume session on the same instance - - workdir2 = os.path.join(str(tmpdir), 'kresd2') - os.makedirs(workdir2) - with make_kresd(workdir2, 'tt') as kresd2: - connect(kresd2, ctx, sf3, session) # resume session on a different instance diff --git a/tests/pytests/utils.py b/tests/pytests/utils.py index 4b995d4b..8af71aad 100644 --- a/tests/pytests/utils.py +++ b/tests/pytests/utils.py @@ -99,7 +99,7 @@ def ping_alive(sock, msgid=None): @contextmanager def expect_kresd_close(rst_ok=False): - with pytest.raises(BrokenPipeError): + with pytest.raises((BrokenPipeError, ssl.SSLEOFError)): try: time.sleep(0.2) # give kresd time to close connection with TCP FIN yield @@ -110,17 +110,12 @@ def expect_kresd_close(rst_ok=False): pytest.fail("kresd didn't close the connection") -def make_ssl_context(insecure=False, verify_location=None, extra_options=None): - # set TLS v1.2+ - context = ssl.SSLContext(ssl.PROTOCOL_TLS) - context.options |= ssl.OP_NO_SSLv2 - context.options |= ssl.OP_NO_SSLv3 - context.options |= ssl.OP_NO_TLSv1 - context.options |= ssl.OP_NO_TLSv1_1 - - if extra_options is not None: - for option in extra_options: - context.options |= option +def make_ssl_context(insecure=False, verify_location=None, + minimum_tls=ssl.TLSVersion.TLSv1_2, + maximum_tls=ssl.TLSVersion.MAXIMUM_SUPPORTED): + context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + context.minimum_version = minimum_tls + context.maximum_version = maximum_tls if insecure: # turn off certificate verification diff --git a/utils/cache_gc/categories.c b/utils/cache_gc/categories.c index 19dec45c..aaa1ae53 100644 --- a/utils/cache_gc/categories.c +++ b/utils/cache_gc/categories.c @@ -18,7 +18,7 @@ static bool rrtype_is_infrastructure(uint16_t r) } } -static int get_random(int to) +static unsigned int get_random(int to) { // We don't need these to be really unpredictable, // but this should be cheap enough not to be noticeable. diff --git a/utils/cache_gc/db.c b/utils/cache_gc/db.c index 76a2b5fa..0e8f90c1 100644 --- a/utils/cache_gc/db.c +++ b/utils/cache_gc/db.c @@ -9,11 +9,13 @@ #include <time.h> #include <sys/stat.h> +#define MDB_FILE "/data.mdb" + int kr_gc_cache_open(const char *cache_path, struct kr_cache *kres_db, knot_db_t ** libknot_db) { - char cache_data[strlen(cache_path) + 10]; - snprintf(cache_data, sizeof(cache_data), "%s/data.mdb", cache_path); + char cache_data[strlen(cache_path) + sizeof(MDB_FILE)]; + (void)snprintf(cache_data, sizeof(cache_data), "%s" MDB_FILE, cache_path); struct stat st = { 0 }; if (stat(cache_path, &st) || !(st.st_mode & S_IFDIR) diff --git a/utils/cache_gc/kr_cache_gc.c b/utils/cache_gc/kr_cache_gc.c index 5978345c..62465f51 100644 --- a/utils/cache_gc/kr_cache_gc.c +++ b/utils/cache_gc/kr_cache_gc.c @@ -194,12 +194,12 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state) // Mixing ^^ page usage and entry sizes (key+value lengths) didn't work // too well, probably due to internal fragmentation after some GC cycles. // Therefore let's scale this by the ratio of these two sums. - ssize_t cats_sumsize = 0; + size_t cats_sumsize = 0; for (int i = 0; i < CATEGORIES; ++i) { cats_sumsize += cats.categories_sizes[i]; } /* use less precise variant to avoid 32-bit overflow */ - ssize_t amount_tofree = cats_sumsize / 100 * cfg->cache_to_be_freed; + size_t amount_tofree = cats_sumsize / 100 * cfg->cache_to_be_freed; kr_log_debug(CACHE, "tofree: %zd / %zd\n", amount_tofree, cats_sumsize); if (VERBOSE_STATUS) { @@ -212,8 +212,11 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state) } category_t limit_category = CATEGORIES; - while (limit_category > 0 && amount_tofree > 0) { - amount_tofree -= cats.categories_sizes[--limit_category]; + while (limit_category > 0) { + size_t cat_size = cats.categories_sizes[--limit_category]; + if (cat_size > amount_tofree) + break; + amount_tofree -= cat_size; } printf("Cache analyzed in %.0lf msecs, %zu records, limit category is %d.\n", diff --git a/utils/cache_gc/main.c b/utils/cache_gc/main.c index 5adf19f0..fe131cd0 100644 --- a/utils/cache_gc/main.c +++ b/utils/cache_gc/main.c @@ -13,6 +13,7 @@ #include "kr_cache_gc.h" static volatile int killed = 0; +static volatile int exit_code = 0; static void got_killed(int signum) { @@ -21,12 +22,10 @@ static void got_killed(int signum) case 1: break; case 2: - exit(5); + exit_code = 5; break; - case 3: - abort(); default: - kr_assert(false); + abort(); } } @@ -60,16 +59,20 @@ int main(int argc, char *argv[]) { printf("Knot Resolver Cache Garbage Collector, version %s\n", PACKAGE_VERSION); if (setvbuf(stdout, NULL, _IONBF, 0) || setvbuf(stderr, NULL, _IONBF, 0)) { - fprintf(stderr, "Failed to to set output buffering (ignored): %s\n", + (void)fprintf(stderr, "Failed to to set output buffering (ignored): %s\n", strerror(errno)); - fflush(stderr); + (void)fflush(stderr); } - signal(SIGTERM, got_killed); - signal(SIGKILL, got_killed); - signal(SIGPIPE, got_killed); - signal(SIGCHLD, got_killed); - signal(SIGINT, got_killed); + struct sigaction act = { + .sa_handler = got_killed, + .sa_flags = SA_RESETHAND, + }; + sigemptyset(&act.sa_mask); + kr_assert(!sigaction(SIGTERM, &act, NULL)); + kr_assert(!sigaction(SIGPIPE, &act, NULL)); + kr_assert(!sigaction(SIGCHLD, &act, NULL)); + kr_assert(!sigaction(SIGINT, &act, NULL)); kr_cache_gc_cfg_t cfg = { .ro_txn_items = 200, @@ -131,7 +134,6 @@ int main(int argc, char *argv[]) return 1; } - int exit_code = 0; kr_cache_gc_state_t *gc_state = NULL; bool last_espace = false; do { diff --git a/utils/client/.clang-tidy b/utils/client/.clang-tidy new file mode 100644 index 00000000..46c666ca --- /dev/null +++ b/utils/client/.clang-tidy @@ -0,0 +1,2 @@ +--- +Checks: '-*' |