diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2d07496 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +SOURCES/libguestfs.keyring +SOURCES/libnbd-1.10.5.tar.gz diff --git a/.libnbd.metadata b/.libnbd.metadata new file mode 100644 index 0000000..c70b7df --- /dev/null +++ b/.libnbd.metadata @@ -0,0 +1,2 @@ +cc1b37b9cfafa515aab3eefd345ecc59aac2ce7b SOURCES/libguestfs.keyring +ae15a534a451d34bfc13397b6ca7a7287cf2371a SOURCES/libnbd-1.10.5.tar.gz diff --git a/SOURCES/0001-api-Add-new-API-nbd_set_pread_initialize.patch b/SOURCES/0001-api-Add-new-API-nbd_set_pread_initialize.patch new file mode 100644 index 0000000..4befdbd --- /dev/null +++ b/SOURCES/0001-api-Add-new-API-nbd_set_pread_initialize.patch @@ -0,0 +1,469 @@ +From c79706af4e7475bf58861a143b77b77a54e7a1cd Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Wed, 9 Feb 2022 15:39:49 -0600 +Subject: [PATCH] api: Add new API nbd_set_pread_initialize() + +The recent patch series for CVE-2022-0485 demonstrated that when +applications using libnbd are not careful about error checking, the +difference on whether a data leak is at least sanitized (all zeroes, +partial reads, or data leftover from a prior read) vs. a dangerous +information leak (uninitialized data from the heap) was partly under +libnbd's control. The previous two patches changed libnbd to always +sanitize, as a security hardening technique that prevents heap leaks +no matter how buggy the client app is. But a blind memset() also adds +an execution delay, even if it doesn't show up as the hot spot in our +profiling when compared to the time spent with network traffic. + +At any rate, if client apps choose to pre-initialize their buffers, or +otherwise audit their code to take on their own risk about not +dereferencing a buffer on failure paths, then the time spent by libnbd +doing memset() is wasted; so it is worth adding a knob to let a user +opt in to faster execution at the expense of giving up our memset() +hardening on their behalf. + +In addition to adding two new APIs, this patch also causes changes to +the four existing APIs nbd_{aio_,}pread{,_structured}, with those +generated lib/api.c changes looking like: + +| --- lib/api.c.bak 2022-02-10 08:17:09.973381979 -0600 +| +++ lib/api.c 2022-02-10 08:22:27.503428024 -0600 +| @@ -2871,7 +2914,8 @@ nbd_pread (struct nbd_handle *h, void *b +| debug (h, "enter: buf= count=%zu offset=%" PRIu64 " flags=0x%x", count, offset, flags); +| } +| +| - memset (buf, 0, count); +| + if (h->pread_initialize) +| + memset (buf, 0, count); +| if (unlikely (!pread_in_permitted_state (h))) { +| ret = -1; +| goto out; + +Message-Id: <20220209220726.1902761-4-eblake@redhat.com> +Acked-by: Laszlo Ersek +[eblake: enhance commit message to show generated file diff, mention CVE +in doc text] +Reviewed-by: Richard W.M. Jones + +(cherry picked from commit e0953cb71250947bb97b25e34ff1ea34bd504bf3) +--- + generator/API.ml | 90 ++++++++++++++++--- + generator/C.ml | 3 +- + .../libnbd/libnbd_110_defaults_test.go | 10 ++- + .../libnbd_120_set_non_defaults_test.go | 12 +++ + lib/handle.c | 17 +++- + lib/internal.h | 5 +- + ocaml/tests/test_110_defaults.ml | 4 +- + ocaml/tests/test_120_set_non_defaults.ml | 5 +- + python/t/110-defaults.py | 3 +- + python/t/120-set-non-defaults.py | 4 +- + tests/errors.c | 25 +++++- + 11 files changed, 156 insertions(+), 22 deletions(-) + +diff --git a/generator/API.ml b/generator/API.ml +index d8df7c8..00ab34f 100644 +--- a/generator/API.ml ++++ b/generator/API.ml +@@ -778,6 +778,49 @@ the time of compilation."; + Link "aio_is_created"; Link "aio_is_ready"]; + }; + ++ "set_pread_initialize", { ++ default_call with ++ args = [Bool "request"]; ret = RErr; ++ shortdesc = "control whether libnbd pre-initializes read buffers"; ++ longdesc = "\ ++By default, libnbd will pre-initialize the contents of a buffer ++passed to calls such as L to all zeroes prior to ++checking for any other errors, so that even if a client application ++passed in an uninitialized buffer but fails to check for errors, it ++will not result in a potential security risk caused by an accidental ++leak of prior heap contents (see CVE-2022-0485 in ++L for an example of a security hole in an ++application built against an earlier version of libnbd that lacked ++consistent pre-initialization). However, for a client application ++that has audited that an uninitialized buffer is never dereferenced, ++or which performs its own pre-initialization, libnbd's sanitization ++efforts merely pessimize performance (although the time spent in ++pre-initialization may pale in comparison to time spent waiting on ++network packets). ++ ++Calling this function with C set to false tells libnbd to ++skip the buffer initialization step in read commands."; ++ see_also = [Link "get_pread_initialize"; ++ Link "set_strict_mode"; ++ Link "pread"; Link "pread_structured"; Link "aio_pread"; ++ Link "aio_pread_structured"]; ++ }; ++ ++ "get_pread_initialize", { ++ default_call with ++ args = []; ret = RBool; ++ may_set_error = false; ++ shortdesc = "see whether libnbd pre-initializes read buffers"; ++ longdesc = "\ ++Return whether libnbd performs a pre-initialization of a buffer passed ++to L and similar to all zeroes, as set by ++L."; ++ see_also = [Link "set_pread_initialize"; ++ Link "set_strict_mode"; ++ Link "pread"; Link "pread_structured"; Link "aio_pread"; ++ Link "aio_pread_structured"]; ++ }; ++ + "set_strict_mode", { + default_call with + args = [ Flags ("flags", strict_flags) ]; ret = RErr; +@@ -1825,11 +1868,16 @@ C. + The C parameter must be C<0> for now (it exists for future NBD + protocol extensions). + +-Note that if this command fails, it is unspecified whether the contents +-of C will read as zero or as partial results from the server." ++Note that if this command fails, and L ++returns true, then libnbd sanitized C, but it is unspecified ++whether the contents of C will read as zero or as partial results ++from the server. If L returns false, ++then libnbd did not sanitize C, and the contents are undefined ++on failure." + ^ strict_call_description; + see_also = [Link "aio_pread"; Link "pread_structured"; +- Link "get_block_size"; Link "set_strict_mode"]; ++ Link "get_block_size"; Link "set_strict_mode"; ++ Link "set_pread_initialize"]; + example = Some "examples/fetch-first-sector.c"; + }; + +@@ -1907,12 +1955,16 @@ more than one fragment (if that is supported - some servers cannot do + this, see L). Libnbd does not validate that the server + actually obeys the flag. + +-Note that if this command fails, it is unspecified whether the contents +-of C will read as zero or as partial results from the server." ++Note that if this command fails, and L ++returns true, then libnbd sanitized C, but it is unspecified ++whether the contents of C will read as zero or as partial results ++from the server. If L returns false, ++then libnbd did not sanitize C, and the contents are undefined ++on failure." + ^ strict_call_description; + see_also = [Link "can_df"; Link "pread"; + Link "aio_pread_structured"; Link "get_block_size"; +- Link "set_strict_mode"]; ++ Link "set_strict_mode"; Link "set_pread_initialize"]; + }; + + "pwrite", { +@@ -2420,14 +2472,19 @@ as described in L. + Note that you must ensure C is valid until the command has + completed. Furthermore, if the C parameter to + C is set or if L +-reports failure, it is unspecified whether the contents +-of C will read as zero or as partial results from the server. ++reports failure, and if L returns true, ++then libnbd sanitized C, but it is unspecified whether the ++contents of C will read as zero or as partial results from the ++server. If L returns false, then ++libnbd did not sanitize C, and the contents are undefined ++on failure. ++ + Other parameters behave as documented in L." + ^ strict_call_description; + example = Some "examples/aio-connect-read.c"; + see_also = [SectionLink "Issuing asynchronous commands"; + Link "aio_pread_structured"; Link "pread"; +- Link "set_strict_mode"]; ++ Link "set_strict_mode"; Link "set_pread_initialize"]; + }; + + "aio_pread_structured", { +@@ -2449,13 +2506,18 @@ as described in L. + Note that you must ensure C is valid until the command has + completed. Furthermore, if the C parameter to + C is set or if L +-reports failure, it is unspecified whether the contents +-of C will read as zero or as partial results from the server. ++reports failure, and if L returns true, ++then libnbd sanitized C, but it is unspecified whether the ++contents of C will read as zero or as partial results from the ++server. If L returns false, then ++libnbd did not sanitize C, and the contents are undefined ++on failure. ++ + Other parameters behave as documented in L." + ^ strict_call_description; + see_also = [SectionLink "Issuing asynchronous commands"; + Link "aio_pread"; Link "pread_structured"; +- Link "set_strict_mode"]; ++ Link "set_strict_mode"; Link "set_pread_initialize"]; + }; + + "aio_pwrite", { +@@ -3093,6 +3155,10 @@ let first_version = [ + "get_private_data", (1, 8); + "get_uri", (1, 8); + ++ (* Added in 1.11.x development cycle, will be stable and supported in 1.12. *) ++ "set_pread_initialize", (1, 12); ++ "get_pread_initialize", (1, 12); ++ + (* These calls are proposed for a future version of libnbd, but + * have not been added to any released version so far. + "get_tls_certificates", (1, ??); +diff --git a/generator/C.ml b/generator/C.ml +index 4a5bb58..2b6198c 100644 +--- a/generator/C.ml ++++ b/generator/C.ml +@@ -496,7 +496,8 @@ let generate_lib_api_c () = + function + | BytesOut (n, count) + | BytesPersistOut (n, count) -> +- pr " memset (%s, 0, %s);\n" n count ++ pr " if (h->pread_initialize)\n"; ++ pr " memset (%s, 0, %s);\n" n count + | _ -> () + ) args; + +diff --git a/golang/src/libguestfs.org/libnbd/libnbd_110_defaults_test.go b/golang/src/libguestfs.org/libnbd/libnbd_110_defaults_test.go +index b3ceb45..ca7c1c4 100644 +--- a/golang/src/libguestfs.org/libnbd/libnbd_110_defaults_test.go ++++ b/golang/src/libguestfs.org/libnbd/libnbd_110_defaults_test.go +@@ -1,5 +1,5 @@ + /* libnbd golang tests +- * Copyright (C) 2013-2021 Red Hat Inc. ++ * Copyright (C) 2013-2022 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -59,6 +59,14 @@ func Test110Defaults(t *testing.T) { + t.Fatalf("unexpected structured replies state") + } + ++ init, err := h.GetPreadInitialize() ++ if err != nil { ++ t.Fatalf("could not get pread initialize state: %s", err) ++ } ++ if init != true { ++ t.Fatalf("unexpected pread initialize state") ++ } ++ + flags, err := h.GetHandshakeFlags() + if err != nil { + t.Fatalf("could not get handshake flags: %s", err) +diff --git a/golang/src/libguestfs.org/libnbd/libnbd_120_set_non_defaults_test.go b/golang/src/libguestfs.org/libnbd/libnbd_120_set_non_defaults_test.go +index f112456..029f0db 100644 +--- a/golang/src/libguestfs.org/libnbd/libnbd_120_set_non_defaults_test.go ++++ b/golang/src/libguestfs.org/libnbd/libnbd_120_set_non_defaults_test.go +@@ -93,6 +93,18 @@ func Test120SetNonDefaults(t *testing.T) { + t.Fatalf("unexpected structured replies state") + } + ++ err = h.SetPreadInitialize(false) ++ if err != nil { ++ t.Fatalf("could not set pread initialize state: %s", err) ++ } ++ init, err := h.GetPreadInitialize() ++ if err != nil { ++ t.Fatalf("could not get pread initialize state: %s", err) ++ } ++ if init != false { ++ t.Fatalf("unexpected pread initialize state") ++ } ++ + err = h.SetHandshakeFlags(HANDSHAKE_FLAG_MASK + 1) + if err == nil { + t.Fatalf("expect failure for out-of-range flags") +diff --git a/lib/handle.c b/lib/handle.c +index 67aa875..ac6c16e 100644 +--- a/lib/handle.c ++++ b/lib/handle.c +@@ -1,5 +1,5 @@ + /* NBD client library in userspace +- * Copyright (C) 2013-2020 Red Hat Inc. ++ * Copyright (C) 2013-2022 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -64,6 +64,7 @@ nbd_create (void) + h->unique = 1; + h->tls_verify_peer = true; + h->request_sr = true; ++ h->pread_initialize = true; + + h->uri_allow_transports = LIBNBD_ALLOW_TRANSPORT_MASK; + h->uri_allow_tls = LIBNBD_TLS_ALLOW; +@@ -393,6 +394,20 @@ nbd_unlocked_get_handshake_flags (struct nbd_handle *h) + return h->gflags; + } + ++int ++nbd_unlocked_set_pread_initialize (struct nbd_handle *h, bool request) ++{ ++ h->pread_initialize = request; ++ return 0; ++} ++ ++/* NB: may_set_error = false. */ ++int ++nbd_unlocked_get_pread_initialize (struct nbd_handle *h) ++{ ++ return h->pread_initialize; ++} ++ + int + nbd_unlocked_set_strict_mode (struct nbd_handle *h, uint32_t flags) + { +diff --git a/lib/internal.h b/lib/internal.h +index 0e205ab..525499a 100644 +--- a/lib/internal.h ++++ b/lib/internal.h +@@ -1,5 +1,5 @@ + /* nbd client library in userspace: internal definitions +- * Copyright (C) 2013-2020 Red Hat Inc. ++ * Copyright (C) 2013-2022 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -123,6 +123,9 @@ struct nbd_handle { + /* Full info mode. */ + bool full_info; + ++ /* Sanitization for pread. */ ++ bool pread_initialize; ++ + /* Global flags from the server. */ + uint16_t gflags; + +diff --git a/ocaml/tests/test_110_defaults.ml b/ocaml/tests/test_110_defaults.ml +index b36949f..04aa744 100644 +--- a/ocaml/tests/test_110_defaults.ml ++++ b/ocaml/tests/test_110_defaults.ml +@@ -1,6 +1,6 @@ + (* hey emacs, this is OCaml code: -*- tuareg -*- *) + (* libnbd OCaml test case +- * Copyright (C) 2013-2020 Red Hat Inc. ++ * Copyright (C) 2013-2022 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -28,6 +28,8 @@ let () = + assert (tls = NBD.TLS.DISABLE); + let sr = NBD.get_request_structured_replies nbd in + assert (sr = true); ++ let init = NBD.get_pread_initialize nbd in ++ assert (init = true); + let flags = NBD.get_handshake_flags nbd in + assert (flags = NBD.HANDSHAKE_FLAG.mask); + let opt = NBD.get_opt_mode nbd in +diff --git a/ocaml/tests/test_120_set_non_defaults.ml b/ocaml/tests/test_120_set_non_defaults.ml +index 67928bb..f949807 100644 +--- a/ocaml/tests/test_120_set_non_defaults.ml ++++ b/ocaml/tests/test_120_set_non_defaults.ml +@@ -1,6 +1,6 @@ + (* hey emacs, this is OCaml code: -*- tuareg -*- *) + (* libnbd OCaml test case +- * Copyright (C) 2013-2020 Red Hat Inc. ++ * Copyright (C) 2013-2022 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -42,6 +42,9 @@ let () = + NBD.set_request_structured_replies nbd false; + let sr = NBD.get_request_structured_replies nbd in + assert (sr = false); ++ NBD.set_pread_initialize nbd false; ++ let init = NBD.get_pread_initialize nbd in ++ assert (init = false); + (try + NBD.set_handshake_flags nbd [ NBD.HANDSHAKE_FLAG.UNKNOWN 2 ]; + assert false +diff --git a/python/t/110-defaults.py b/python/t/110-defaults.py +index fb961cf..a4262da 100644 +--- a/python/t/110-defaults.py ++++ b/python/t/110-defaults.py +@@ -1,5 +1,5 @@ + # libnbd Python bindings +-# Copyright (C) 2010-2020 Red Hat Inc. ++# Copyright (C) 2010-2022 Red Hat Inc. + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +@@ -22,5 +22,6 @@ assert h.get_export_name() == "" + assert h.get_full_info() is False + assert h.get_tls() == nbd.TLS_DISABLE + assert h.get_request_structured_replies() is True ++assert h.get_pread_initialize() is True + assert h.get_handshake_flags() == nbd.HANDSHAKE_FLAG_MASK + assert h.get_opt_mode() is False +diff --git a/python/t/120-set-non-defaults.py b/python/t/120-set-non-defaults.py +index 3da0c23..e71c6ad 100644 +--- a/python/t/120-set-non-defaults.py ++++ b/python/t/120-set-non-defaults.py +@@ -1,5 +1,5 @@ + # libnbd Python bindings +-# Copyright (C) 2010-2020 Red Hat Inc. ++# Copyright (C) 2010-2022 Red Hat Inc. + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +@@ -33,6 +33,8 @@ if h.supports_tls(): + assert h.get_tls() == nbd.TLS_ALLOW + h.set_request_structured_replies(False) + assert h.get_request_structured_replies() is False ++h.set_pread_initialize(False) ++assert h.get_pread_initialize() is False + try: + h.set_handshake_flags(nbd.HANDSHAKE_FLAG_MASK + 1) + assert False +diff --git a/tests/errors.c b/tests/errors.c +index f597b7e..0298da8 100644 +--- a/tests/errors.c ++++ b/tests/errors.c +@@ -213,7 +213,15 @@ main (int argc, char *argv[]) + } + + +- /* Issue a connected command when not connected. */ ++ /* Issue a connected command when not connected. pread_initialize defaults ++ * to set. ++ */ ++ if (nbd_get_pread_initialize (nbd) != 1) { ++ fprintf (stderr, "%s: test failed: " ++ "nbd_get_pread_initialize gave unexpected result\n", ++ argv[0]); ++ exit (EXIT_FAILURE); ++ } + buf[0] = '1'; + if (nbd_pread (nbd, buf, 512, 0, 0) != -1) { + fprintf (stderr, "%s: test failed: " +@@ -294,7 +302,14 @@ main (int argc, char *argv[]) + } + check (EINVAL, "nbd_aio_command_completed: "); + +- /* Read from an invalid offset, client-side */ ++ /* Read from an invalid offset, client-side. When pread_initialize is off, ++ * libnbd should not have touched our buffer. ++ */ ++ if (nbd_set_pread_initialize (nbd, false) == -1) { ++ fprintf (stderr, "%s\n", nbd_get_error ()); ++ exit (EXIT_FAILURE); ++ } ++ buf[0] = '1'; + strict = nbd_get_strict_mode (nbd) | LIBNBD_STRICT_BOUNDS; + if (nbd_set_strict_mode (nbd, strict) == -1) { + fprintf (stderr, "%s\n", nbd_get_error ()); +@@ -307,6 +322,12 @@ main (int argc, char *argv[]) + exit (EXIT_FAILURE); + } + check (EINVAL, "nbd_aio_pread: "); ++ if (buf[0] != '1') { ++ fprintf (stderr, "%s: test failed: " ++ "nbd_pread incorrectly sanitized buffer on client-side error\n", ++ argv[0]); ++ exit (EXIT_FAILURE); ++ } + + /* We guarantee callbacks will be freed even on all error paths. */ + if (nbd_aio_pread_structured (nbd, buf, 512, -1, +-- +2.31.1 + diff --git a/SOURCES/copy-patches.sh b/SOURCES/copy-patches.sh new file mode 100755 index 0000000..83867ef --- /dev/null +++ b/SOURCES/copy-patches.sh @@ -0,0 +1,55 @@ +#!/bin/bash - + +set -e + +# Maintainer script to copy patches from the git repo to the current +# directory. Use it like this: +# ./copy-patches.sh + +rhel_version=9.0 + +# Check we're in the right directory. +if [ ! -f libnbd.spec ]; then + echo "$0: run this from the directory containing 'libnbd.spec'" + exit 1 +fi + +git_checkout=$HOME/d/libnbd-rhel-$rhel_version +if [ ! -d $git_checkout ]; then + echo "$0: $git_checkout does not exist" + echo "This script is only for use by the maintainer when preparing a" + echo "libnbd release on RHEL." + exit 1 +fi + +# Get the base version of libnbd. +version=`grep '^Version:' libnbd.spec | awk '{print $2}'` +tag="v$version" + +# Remove any existing patches. +git rm -f [0-9]*.patch ||: +rm -f [0-9]*.patch + +# Get the patches. +(cd $git_checkout; rm -f [0-9]*.patch; git format-patch -N $tag) +mv $git_checkout/[0-9]*.patch . + +# Remove any not to be applied. +rm -f *NOT-FOR-RPM*.patch + +# Add the patches. +git add [0-9]*.patch + +# Print out the patch lines. +echo +echo "--- Copy the following text into libnbd.spec file" +echo + +echo "# Patches." +for f in [0-9]*.patch; do + n=`echo $f | awk -F- '{print $1}'` + echo "Patch$n: $f" +done + +echo +echo "--- End of text" diff --git a/SOURCES/libnbd-1.10.5.tar.gz.sig b/SOURCES/libnbd-1.10.5.tar.gz.sig new file mode 100644 index 0000000..39755f0 --- /dev/null +++ b/SOURCES/libnbd-1.10.5.tar.gz.sig @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- + +iQJFBAABCAAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAmIFM4YRHHJpY2hAYW5u +ZXhpYS5vcmcACgkQkXOPc+G3aKDrPhAAjwTeg6XxTtPAbBFqwgYeux742i4ufnrL +xdCQgtmyF4jFhW6E0q/dYKr32iUxL6BabswcbmHHhjU4XEa16mSPbkbYAMNvsPJa +FpzW4KMJh+vHCarqm3UFiBwVKEEu+VXbOVh9bVjpCdJRx+jE6hbr5tlR9CHQuNQY +3LoZ7YU+QvQyIVQDOzDSD/8swyfOeX1c4D4Wok0w9qgHsT54GQmT4VTQ93Z/8RXK +D3vCNOt2J+bnJx9WNkboNIfS/FI4L6j4TpuB7tucJlk8Wtfj7LI526LBZwaLYO8E +MH63xr0dvbSA19kNY8M3Sff+YqOEKcufZREt5pX6LJLM/ARXKc0KwmaXR+U2zoNy +gFomzICsvhGusP6mgLc60VYSUO+od9qZDYsmGZ0mtNL18ISKqIjRRxEXWG6z6mT7 +kkbifoZC4tOQqKzvswzlWb0upaC5IOju8tGSwpuZosoVcAs63CmU71/CIA7CT4s0 +qUw+g0ISJYXMFGp3gNzkie9d/a8fAhaCYQKuSxtb5bCNaFegc/6djLy5/MAa65x0 +difLH3sHYEtB4CzPQnQ8wM5khZ/D789CtqGFtI4fz1aMShW0AJfnsUU8DtAi9pAg +3wcjR0N8wQLq68Evj0+VO2rzq/2FSKaR9P7r2cobHC+ucAdvZRAzWOMcHIzfszkN +vMYr5xX3G8o= +=1qAE +-----END PGP SIGNATURE----- diff --git a/SPECS/libnbd.spec b/SPECS/libnbd.spec new file mode 100644 index 0000000..b1800b5 --- /dev/null +++ b/SPECS/libnbd.spec @@ -0,0 +1,665 @@ +# If we should verify tarball signature with GPGv2. +%global verify_tarball_signature 1 + +# If there are patches which touch autotools files, set this to 1. +%global patches_touch_autotools 1 + +# The source directory. +%global source_directory 1.10-stable + +Name: libnbd +Version: 1.10.5 +Release: 1%{?dist} +Summary: NBD client library in userspace + +License: LGPLv2+ +URL: https://gitlab.com/nbdkit/libnbd + +Source0: http://libguestfs.org/download/libnbd/%{source_directory}/%{name}-%{version}.tar.gz +Source1: http://libguestfs.org/download/libnbd/%{source_directory}/%{name}-%{version}.tar.gz.sig +# Keyring used to verify tarball signature. This contains the single +# key from here: +# https://pgp.key-server.io/pks/lookup?search=rjones%40redhat.com&fingerprint=on&op=vindex +Source2: libguestfs.keyring + +# Maintainer script which helps with handling patches. +Source3: copy-patches.sh + +# Patches are stored in the upstream repository: +# https://gitlab.com/nbdkit/libnbd/-/commits/rhel-9.0/ + +# Patches. +Patch0001: 0001-api-Add-new-API-nbd_set_pread_initialize.patch + +%if 0%{patches_touch_autotools} +BuildRequires: autoconf, automake, libtool +%endif + +%if 0%{verify_tarball_signature} +BuildRequires: gnupg2 +%endif + +# For the core library. +BuildRequires: gcc +BuildRequires: make +BuildRequires: /usr/bin/pod2man +BuildRequires: gnutls-devel +BuildRequires: libxml2-devel + +# For nbdfuse. +BuildRequires: fuse3, fuse3-devel + +# For the Python 3 bindings. +BuildRequires: python3-devel + +# For the OCaml bindings. +BuildRequires: ocaml +BuildRequires: ocaml-findlib-devel +BuildRequires: ocaml-ocamldoc + +# Only for building the examples. +BuildRequires: glib2-devel + +# For bash-completion. +BuildRequires: bash-completion + +# Only for running the test suite. +BuildRequires: coreutils +BuildRequires: gcc-c++ +BuildRequires: gnutls-utils +BuildRequires: iproute +BuildRequires: jq +%if !0%{?rhel} +BuildRequires: nbd +%endif +BuildRequires: util-linux + +# On RHEL, maybe even in Fedora in future, we do not build qemu-img or +# nbdkit for i686. These are only needed for the test suite so make +# them optional. This reduces our test exposure on 32 bit platforms, +# although there is still Fedora/armv7 and some upstream testing. +%ifnarch %{ix86} +BuildRequires: qemu-img +BuildRequires: nbdkit +BuildRequires: nbdkit-data-plugin +BuildRequires: nbdkit-eval-plugin +BuildRequires: nbdkit-memory-plugin +BuildRequires: nbdkit-null-plugin +BuildRequires: nbdkit-pattern-plugin +BuildRequires: nbdkit-sh-plugin +BuildRequires: nbdkit-sparse-random-plugin +%endif + + +%description +NBD — Network Block Device — is a protocol for accessing Block Devices +(hard disks and disk-like things) over a Network. + +This is the NBD client library in userspace, a simple library for +writing NBD clients. + +The key features are: + + * Synchronous and asynchronous APIs, both for ease of use and for + writing non-blocking, multithreaded clients. + + * High performance. + + * Minimal dependencies for the basic library. + + * Well-documented, stable API. + + * Bindings in several programming languages. + + +%package devel +Summary: Development headers for %{name} +License: LGPLv2+ and BSD +Requires: %{name}%{?_isa} = %{version}-%{release} + + +%description devel +This package contains development headers for %{name}. + + +%package -n ocaml-%{name} +Summary: OCaml language bindings for %{name} +Requires: %{name}%{?_isa} = %{version}-%{release} + + +%description -n ocaml-%{name} +This package contains OCaml language bindings for %{name}. + + +%package -n ocaml-%{name}-devel +Summary: OCaml language development package for %{name} +Requires: ocaml-%{name}%{?_isa} = %{version}-%{release} + + +%description -n ocaml-%{name}-devel +This package contains OCaml language development package for +%{name}. Install this if you want to compile OCaml software which +uses %{name}. + + +%package -n python3-%{name} +Summary: Python 3 bindings for %{name} +Requires: %{name}%{?_isa} = %{version}-%{release} +%{?python_provide:%python_provide python3-%{name}} + +# The Python module happens to be called lib*.so. Don't scan it and +# have a bogus "Provides: libnbdmod.*". +%global __provides_exclude_from ^%{python3_sitearch}/lib.*\\.so + + +%description -n python3-%{name} +python3-%{name} contains Python 3 bindings for %{name}. + + +%package -n nbdfuse +Summary: FUSE support for %{name} +License: LGPLv2+ and BSD +Requires: %{name}%{?_isa} = %{version}-%{release} +Recommends: fuse3 + + +%description -n nbdfuse +This package contains FUSE support for %{name}. + + +%package bash-completion +Summary: Bash tab-completion for %{name} +BuildArch: noarch +Requires: bash-completion >= 2.0 +# Don't use _isa here because it's a noarch package. This dependency +# is just to ensure that the subpackage is updated along with libnbd. +Requires: %{name} = %{version}-%{release} + + +%description bash-completion +Install this package if you want intelligent bash tab-completion +for %{name}. + + +%prep +%if 0%{verify_tarball_signature} +%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' +%endif +%autosetup -p1 +%if 0%{patches_touch_autotools} +autoreconf -i +%endif + + +%build +%configure \ + --disable-static \ + --with-tls-priority=@LIBNBD,SYSTEM \ + PYTHON=%{__python3} \ + --enable-python \ + --enable-ocaml \ + --enable-fuse \ + --disable-golang + +make %{?_smp_mflags} + + +%install +%make_install + +# Delete libtool crap. +find $RPM_BUILD_ROOT -name '*.la' -delete + +# Delete the golang man page since we're not distributing the bindings. +rm $RPM_BUILD_ROOT%{_mandir}/man3/libnbd-golang.3* + + +%check +function skip_test () +{ + for f in "$@"; do + rm -f "$f" + echo 'exit 77' > "$f" + chmod +x "$f" + done +} + +# interop/structured-read.sh fails with the old qemu-nbd in Fedora 29, +# so disable it there. +%if 0%{?fedora} <= 29 +skip_test interop/structured-read.sh +%endif + +# interop/interop-qemu-storage-daemon.sh fails in RHEL 9 because of +# this bug in qemu: +# https://lists.nongnu.org/archive/html/qemu-devel/2021-03/threads.html#03544 +%if 0%{?rhel} +skip_test interop/interop-qemu-storage-daemon.sh +%endif + +# All fuse tests fail in Koji with: +# fusermount: entry for fuse/test-*.d not found in /etc/mtab +# for unknown reasons but probably related to the Koji environment. +skip_test fuse/test-*.sh + +# IPv6 loopback connections fail in Koji. +make -C tests connect-tcp6 ||: +skip_test tests/connect-tcp6 + +make %{?_smp_mflags} check || { + for f in $(find -name test-suite.log); do + echo + echo "==== $f ====" + cat $f + done + exit 1 + } + + +%files +%doc README +%license COPYING.LIB +%{_bindir}/nbdcopy +%{_bindir}/nbdinfo +%{_libdir}/libnbd.so.* +%{_mandir}/man1/nbdcopy.1* +%{_mandir}/man1/nbdinfo.1* + + +%files devel +%doc TODO examples/*.c +%license examples/LICENSE-FOR-EXAMPLES +%{_includedir}/libnbd.h +%{_libdir}/libnbd.so +%{_libdir}/pkgconfig/libnbd.pc +%{_mandir}/man3/libnbd.3* +%{_mandir}/man1/libnbd-release-notes-1.*.1* +%{_mandir}/man3/libnbd-security.3* +%{_mandir}/man3/nbd_*.3* + + +%files -n ocaml-%{name} +%{_libdir}/ocaml/nbd +%exclude %{_libdir}/ocaml/nbd/*.a +%exclude %{_libdir}/ocaml/nbd/*.cmxa +%exclude %{_libdir}/ocaml/nbd/*.cmx +%exclude %{_libdir}/ocaml/nbd/*.mli +%{_libdir}/ocaml/stublibs/dllmlnbd.so +%{_libdir}/ocaml/stublibs/dllmlnbd.so.owner + + +%files -n ocaml-%{name}-devel +%doc ocaml/examples/*.ml +%license ocaml/examples/LICENSE-FOR-EXAMPLES +%{_libdir}/ocaml/nbd/*.a +%{_libdir}/ocaml/nbd/*.cmxa +%{_libdir}/ocaml/nbd/*.cmx +%{_libdir}/ocaml/nbd/*.mli +%{_mandir}/man3/libnbd-ocaml.3* +%{_mandir}/man3/NBD.3* +%{_mandir}/man3/NBD.*.3* + + +%files -n python3-%{name} +%{python3_sitearch}/libnbdmod*.so +%{python3_sitearch}/nbd.py +%{python3_sitearch}/nbdsh.py +%{python3_sitearch}/__pycache__/nbd*.py* +%{_bindir}/nbdsh +%{_mandir}/man1/nbdsh.1* + + +%files -n nbdfuse +%{_bindir}/nbdfuse +%{_mandir}/man1/nbdfuse.1* + + +%files bash-completion +%dir %{_datadir}/bash-completion/completions +%{_datadir}/bash-completion/completions/nbdcopy +%{_datadir}/bash-completion/completions/nbdfuse +%{_datadir}/bash-completion/completions/nbdinfo +%{_datadir}/bash-completion/completions/nbdsh + + +%changelog +* Thu Feb 10 2022 Richard W.M. Jones - 1.10.5-1 +- Rebase to new stable branch version 1.10.5 + resolves: rhbz#2011708 +- Map uint32_t to OCaml int64 to avoid signedness problems + resolves: rhbz#2040610 +- CVE-2022-0485 nbdcopy destination image corruption +- New upstream API to control initialization of pread buffer + resolves: rhbz#2046194 + +* Mon Aug 09 2021 Mohan Boddu - 1.8.2-3 +- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + Related: rhbz#1991688 + +* Fri Jul 30 2021 Richard W.M. Jones - 1.8.2-2 +- Fix nbdcopy progress bar. +- Add nbdinfo --map --totals and --can/--is options. + resolves: rhbz#1950630 + +* Sat Jul 03 2021 Richard W.M. Jones - 1.8.2-1 +- New upstream stable version 1.8.2. + +* Wed Jun 23 2021 Richard W.M. Jones - 1.8.1-2 +- Bump and rebuild + resolves: rhbz#1975316 + +* Fri Jun 11 2021 Richard W.M. Jones - 1.8.1-1 +- New upstream stable version 1.8.1. + +* Mon Jun 07 2021 Richard W.M. Jones - 1.8.0-1 +- New upstream version 1.8.0. + +* Fri Jun 04 2021 Python Maint - 1.7.12-2 +- Rebuilt for Python 3.10 + +* Sat May 29 2021 Richard W.M. Jones - 1.7.12-1 +- New upstream version 1.7.12. + +* Thu May 20 2021 Richard W.M. Jones - 1.7.11-1 +- New upstream version 1.7.11. + +* Fri May 14 2021 Richard W.M. Jones - 1.7.10-1 +- New upstream version 1.7.10. + +* Thu Apr 29 2021 Richard W.M. Jones - 1.7.9-1 +- New upstream version 1.7.9. +- Switch to fuse3. +- Make nbdfuse package recommend fuse3 (to get fusermount3). + +* Sat Apr 24 2021 Richard W.M. Jones - 1.7.8-1 +- New upstream development version 1.7.8. + +* Sat Apr 10 2021 Richard W.M. Jones - 1.7.7-1 +- New upstream development version 1.7.7. +- +BR iproute +- Add skip_test helper function. +- Skip connect-tcp6 test which fails under Koji. + +* Thu Apr 08 2021 Richard W.M. Jones - 1.7.6-1 +- New upstream development version 1.7.6. + +* Sat Apr 03 2021 Richard W.M. Jones - 1.7.5-1 +- New upstream development version 1.7.5. + +* Mon Mar 15 2021 Richard W.M. Jones - 1.7.4-1 +- New upstream development version 1.7.4. + +* Mon Mar 15 2021 Richard W.M. Jones - 1.7.3-3 +- Update documentation for CVE-2021-20286. +- Workaround broken interop/interop-qemu-storage-daemon.sh test in RHEL 9. + +* Thu Mar 4 2021 Richard W.M. Jones - 1.7.3-2 +- Add fix for nbdkit test suite. + +* Tue Mar 2 2021 Richard W.M. Jones - 1.7.3-1 +- New upstream version 1.7.3. + +* Mon Mar 1 2021 Richard W.M. Jones - 1.7.2-3 +- OCaml 4.12.0 build + +* Wed Feb 24 2021 Richard W.M. Jones - 1.7.2-2 +- Disable nbd BR on RHEL. + +* Mon Feb 22 2021 Richard W.M. Jones - 1.7.2-1 +- New upstream version 1.7.2. + +* Fri Jan 29 2021 Richard W.M. Jones - 1.7.1-6 +- Disable BR qemu-img on i686. + +* Thu Jan 28 2021 Richard W.M. Jones - 1.7.1-3 +- Disable BR nbdkit on i686 because it breaks ELN/RHEL 9. + +* Tue Jan 26 2021 Fedora Release Engineering - 1.7.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Wed Jan 20 2021 Richard W.M. Jones - 1.7.1-1 +- New upstream development version 1.7.1. + +* Thu Jan 07 2021 Richard W.M. Jones - 1.6.0-1 +- New upstream stable version 1.6.0. + +* Tue Dec 08 2020 Richard W.M. Jones - 1.5.9-1 +- New upstream development version 1.5.9. + +* Thu Dec 03 2020 Richard W.M. Jones - 1.5.8-1 +- New upstream development version 1.5.8. +- Unify Fedora and RHEL spec files. + +* Wed Nov 25 2020 Richard W.M. Jones - 1.5.7-1 +- New upstream development version 1.5.7. +- Add some more test suite buildrequires lines. +- Fix bogus date in changelog. + +* Thu Nov 12 2020 Richard W.M. Jones - 1.5.6-1 +- New upstream development version 1.5.6. + +* Mon Nov 02 2020 Richard W.M. Jones - 1.5.5-1 +- New upstream development version 1.5.5. + +* Mon Oct 05 2020 Richard W.M. Jones - 1.5.4-1 +- New upstream development version 1.5.4. +- More OCaml man pages. + +* Sat Sep 26 2020 Richard W.M. Jones - 1.5.3-1 +- New upstream development version 1.5.3. + +* Thu Sep 10 2020 Richard W.M. Jones - 1.5.2-1 +- New upstream development version 1.5.2. + +* Tue Sep 08 2020 Richard W.M. Jones - 1.5.1-1 +- New upstream development version 1.5.1. + +* Tue Sep 01 2020 Richard W.M. Jones - 1.4.0-2 +- OCaml 4.11.1 rebuild + +* Tue Aug 25 2020 Richard W.M. Jones - 1.4.0-1 +- New stable release 1.4.0. + +* Fri Aug 21 2020 Richard W.M. Jones - 1.3.12-3 +- Bump release and rebuild. + +* Fri Aug 21 2020 Richard W.M. Jones - 1.3.12-2 +- OCaml 4.11.0 rebuild + +* Thu Aug 20 2020 Richard W.M. Jones - 1.3.12-1 +- New upstream version 1.3.12. + +* Thu Aug 6 2020 Richard W.M. Jones - 1.3.11-1 +- New upstream version 1.3.11. + +* Tue Aug 4 2020 Richard W.M. Jones - 1.3.10-1 +- New upstream version 1.3.10. + +* Wed Jul 29 2020 Richard W.M. Jones - 1.3.9-3 +- Bump and rebuild. + +* Tue Jul 28 2020 Fedora Release Engineering - 1.3.9-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Tue Jul 21 2020 Richard W.M. Jones - 1.3.9-1 +- New upstream version 1.3.9. +- New tool: nbdinfo. + +* Fri Jul 17 2020 Richard W.M. Jones - 1.3.8-2 +- New upstream version 1.3.8. +- New tool: nbdcopy +- Add upstream patch to fix compilation with glibc from Rawhide. + +* Tue May 26 2020 Miro Hrončok - 1.3.7-3 +- Rebuilt for Python 3.9 + +* Mon May 04 2020 Richard W.M. Jones - 1.3.7-2 +- OCaml 4.11.0+dev2-2020-04-22 rebuild + +* Thu Apr 23 2020 Richard W.M. Jones - 1.3.7-1 +- New upstream version 1.3.7. + +* Tue Apr 21 2020 Richard W.M. Jones - 1.3.6-5 +- OCaml 4.11.0 pre-release attempt 2 + +* Fri Apr 17 2020 Richard W.M. Jones - 1.3.6-4 +- OCaml 4.11.0 pre-release +- Add upstream patch to fix one of the tests that fails on slow machines. + +* Thu Apr 02 2020 Richard W.M. Jones - 1.3.6-2 +- Update all OCaml dependencies for RPM 4.16. + +* Tue Mar 31 2020 Richard W.M. Jones - 1.3.6-1 +- New upstream development version 1.3.6. +- Golang bindings are contained in this release but not distributed. + +* Wed Mar 11 2020 Richard W.M. Jones - 1.3.5-2 +- Fix bogus runtime Requires of new bash-completion package. + +* Tue Mar 10 2020 Richard W.M. Jones - 1.3.5-1 +- New upstream development version 1.3.5. +- Add new bash-completion subpackage. + +* Sat Feb 29 2020 Richard W.M. Jones - 1.3.4-1 +- New upstream development version 1.3.4. + +* Wed Feb 26 2020 Richard W.M. Jones - 1.3.3-2 +- OCaml 4.10.0 final. + +* Wed Feb 05 2020 Richard W.M. Jones - 1.3.3-1 +- New upstream development version 1.3.3. + +* Thu Jan 30 2020 Richard W.M. Jones - 1.3.2-1 +- New upstream development version 1.3.2. + +* Wed Jan 29 2020 Fedora Release Engineering - 1.3.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Sun Jan 19 2020 Richard W.M. Jones - 1.3.1-4 +- Bump release and rebuild. + +* Sun Jan 19 2020 Richard W.M. Jones - 1.3.1-3 +- OCaml 4.10.0+beta1 rebuild. + +* Thu Dec 12 2019 Richard W.M. Jones - 1.3.1-2 +- Rebuild for OCaml 4.09.0. + +* Tue Dec 03 2019 Richard W.M. Jones - 1.3.1-1 +- New upstream development version 1.3.1. + +* Wed Nov 27 2019 Richard W.M. Jones - 1.2.0-2 +- Use gpgverify macro instead of explicit gpgv2 command. + +* Thu Nov 14 2019 Richard W.M. Jones - 1.2.0-1 +- New stable release 1.2.0 + +* Sat Nov 09 2019 Richard W.M. Jones - 1.1.9-1 +- New upstream version 1.1.9. +- Add new nbdkit-release-notes-1.2(1) man page. + +* Wed Nov 06 2019 Richard W.M. Jones - 1.1.8-1 +- New upstream version 1.1.8. + +* Thu Oct 24 2019 Richard W.M. Jones - 1.1.7-1 +- New upstream version 1.1.7. + +* Sat Oct 19 2019 Richard W.M. Jones - 1.1.6-1 +- New upstream version 1.1.6. + +* Sat Oct 12 2019 Richard W.M. Jones - 1.1.5-1 +- New upstream version 1.1.5. +- New tool and subpackage nbdfuse. + +* Wed Oct 9 2019 Richard W.M. Jones - 1.1.4-1 +- New upstream version 1.1.4. +- Contains fix for remote code execution vulnerability. +- Add new libnbd-security(3) man page. + +* Tue Oct 1 2019 Richard W.M. Jones - 1.1.3-1 +- New upstream version 1.1.3. + +* Tue Sep 17 2019 Richard W.M. Jones - 1.1.2-1 +- New upstream version 1.1.2. +- Remove patches which are upstream. +- Contains fix for NBD Protocol Downgrade Attack (CVE-2019-14842). + +* Thu Sep 12 2019 Richard W.M. Jones - 1.1.1-2 +- Add upstream patch to fix nbdsh (for nbdkit tests). + +* Sun Sep 08 2019 Richard W.M. Jones - 1.1.1-1 +- New development version 1.1.1. + +* Wed Aug 28 2019 Richard W.M. Jones - 1.0.0-1 +- New upstream version 1.0.0. + +* Wed Aug 21 2019 Miro Hrončok - 0.9.9-2 +- Rebuilt for Python 3.8 + +* Wed Aug 21 2019 Richard W.M. Jones - 0.9.9-1 +- New upstream version 0.9.9. + +* Wed Aug 21 2019 Richard W.M. Jones - 0.9.8-4 +- Fix nbdkit dependencies so we're actually running the tests. +- Add glib2-devel BR so we build the glib main loop example. +- Add upstream patch to fix test error: + nbd_connect_unix: getlogin: No such device or address +- Fix test failure on 32 bit. + +* Tue Aug 20 2019 Richard W.M. Jones - 0.9.8-3 +- Bump and rebuild to fix releng brokenness. + https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/message/2LIDI33G3IEIPYSCCIP6WWKNHY7XZJGQ/ + +* Mon Aug 19 2019 Miro Hrončok - 0.9.8-2 +- Rebuilt for Python 3.8 + +* Thu Aug 15 2019 Richard W.M. Jones - 0.9.8-1 +- New upstream version 0.9.8. +- Package the new nbd_*(3) man pages. + +* Mon Aug 5 2019 Richard W.M. Jones - 0.9.7-1 +- New upstream version 0.9.7. +- Add libnbd-ocaml(3) man page. + +* Sat Aug 3 2019 Richard W.M. Jones - 0.9.6-2 +- Add all upstream patches since 0.9.6 was released. +- Package the ocaml bindings into a subpackage. + +* Tue Jul 30 2019 Richard W.M. Jones - 0.9.6-1 +- New upstream verison 0.9.6. + +* Fri Jul 26 2019 Richard W.M. Jones - 0.1.9-1 +- New upstream version 0.1.9. + +* Thu Jul 25 2019 Fedora Release Engineering - 0.1.8-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Wed Jul 17 2019 Richard W.M. Jones - 0.1.8-1 +- New upstream version 0.1.8. + +* Tue Jul 16 2019 Richard W.M. Jones - 0.1.7-1 +- New upstream version 0.1.7. + +* Wed Jul 3 2019 Richard W.M. Jones - 0.1.6-1 +- New upstream version 0.1.6. + +* Thu Jun 27 2019 Richard W.M. Jones - 0.1.5-1 +- New upstream version 0.1.5. + +* Sun Jun 09 2019 Richard W.M. Jones - 0.1.4-1 +- New upstream version 0.1.4. + +* Sun Jun 2 2019 Richard W.M. Jones - 0.1.2-2 +- Enable libxml2 for NBD URI support. + +* Thu May 30 2019 Richard W.M. Jones - 0.1.2-1 +- New upstream version 0.1.2. + +* Tue May 28 2019 Richard W.M. Jones - 0.1.1-1 +- Fix license in man pages and examples. +- Add nbdsh(1) man page. +- Include the signature and keyring even if validation is disabled. +- Update devel subpackage license. +- Fix old FSF address in Python tests. +- Filter Python provides. +- Remove executable permission on the tar.gz.sig file. +- Initial release.