Eric Blake
2019-Aug-28 21:09 UTC
[Libguestfs] [nbdkit PATCH] offset: Better handling of parameters
The man page claims both offset and range are optional (matching the code), but the --help text claims offset is mandatory, and the comment to the no-op offset_config_complete claims we require both parameters. We did not check for an offset larger than the underlying size when there was no range, and even when there is a range, we were not careful about integer overflow (offset=5E range=5E happily claims to export a 5E image; but all bets are off if you later try to access beyond the real underlying size). And in several cases, such as if the plugin's get_size fails but range was not provided, we are not returning -1 for failure. Fixes: 3db69f56 Signed-off-by: Eric Blake <eblake@redhat.com> --- The first post-1.14 bugfix. Too bad I didn't spot it earlier today. filters/offset/offset.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/filters/offset/offset.c b/filters/offset/offset.c index 7df1ed13..1039a577 100644 --- a/filters/offset/offset.c +++ b/filters/offset/offset.c @@ -64,16 +64,9 @@ offset_config (nbdkit_next_config *next, void *nxdata, return next (nxdata, key, value); } -/* Check the user did pass both parameters. */ -static int -offset_config_complete (nbdkit_next_config_complete *next, void *nxdata) -{ - return next (nxdata); -} - #define offset_config_help \ - "offset=<OFFSET> (required) The start offset to serve.\n" \ - "range=<LENGTH> The total size to serve." + "offset=<OFFSET> The start offset to serve (default 0).\n" \ + "range=<LENGTH> The total size to serve (default rest of file)." /* Get the file size. */ static int64_t @@ -82,16 +75,23 @@ offset_get_size (struct nbdkit_next_ops *next_ops, void *nxdata, { int64_t real_size = next_ops->get_size (nxdata); + if (real_size == -1) + return -1; + if (range >= 0) { - if (offset + range > real_size) { + if (offset > real_size - range) { nbdkit_error ("offset+range is larger than the real size " "of the underlying file or device"); return -1; } return range; } - else - return real_size - offset; + else if (offset > real_size) { + nbdkit_error ("offset is larger than the real size " + "of the underlying file or device"); + return -1; + } + return real_size - offset; } /* Read data. */ @@ -176,7 +176,6 @@ static struct nbdkit_filter filter = { .longname = "nbdkit offset filter", .version = PACKAGE_VERSION, .config = offset_config, - .config_complete = offset_config_complete, .config_help = offset_config_help, .get_size = offset_get_size, .pread = offset_pread, -- 2.21.0
Richard W.M. Jones
2019-Aug-29 10:16 UTC
Re: [Libguestfs] [nbdkit PATCH] offset: Better handling of parameters
On Wed, Aug 28, 2019 at 04:09:24PM -0500, Eric Blake wrote:> The man page claims both offset and range are optional (matching the > code), but the --help text claims offset is mandatory, and the comment > to the no-op offset_config_complete claims we require both parameters. > We did not check for an offset larger than the underlying size when > there was no range, and even when there is a range, we were not > careful about integer overflow (offset=5E range=5E happily claims to > export a 5E image; but all bets are off if you later try to access > beyond the real underlying size). And in several cases, such as if > the plugin's get_size fails but range was not provided, we are not > returning -1 for failure. > > Fixes: 3db69f56 > Signed-off-by: Eric Blake <eblake@redhat.com> > --- > > The first post-1.14 bugfix. Too bad I didn't spot it earlier today.The patch looks good, ACK. We can backport these fixes easily to 1.14.1, but let's give it a few days as I'm sure there will be several more bugs that we find. However do please push this today, because I will do a final [probably] 1.12 stable branch release later today. Thanks, Rich.> filters/offset/offset.c | 25 ++++++++++++------------- > 1 file changed, 12 insertions(+), 13 deletions(-) > > diff --git a/filters/offset/offset.c b/filters/offset/offset.c > index 7df1ed13..1039a577 100644 > --- a/filters/offset/offset.c > +++ b/filters/offset/offset.c > @@ -64,16 +64,9 @@ offset_config (nbdkit_next_config *next, void *nxdata, > return next (nxdata, key, value); > } > > -/* Check the user did pass both parameters. */ > -static int > -offset_config_complete (nbdkit_next_config_complete *next, void *nxdata) > -{ > - return next (nxdata); > -} > - > #define offset_config_help \ > - "offset=<OFFSET> (required) The start offset to serve.\n" \ > - "range=<LENGTH> The total size to serve." > + "offset=<OFFSET> The start offset to serve (default 0).\n" \ > + "range=<LENGTH> The total size to serve (default rest of file)." > > /* Get the file size. */ > static int64_t > @@ -82,16 +75,23 @@ offset_get_size (struct nbdkit_next_ops *next_ops, void *nxdata, > { > int64_t real_size = next_ops->get_size (nxdata); > > + if (real_size == -1) > + return -1; > + > if (range >= 0) { > - if (offset + range > real_size) { > + if (offset > real_size - range) { > nbdkit_error ("offset+range is larger than the real size " > "of the underlying file or device"); > return -1; > } > return range; > } > - else > - return real_size - offset; > + else if (offset > real_size) { > + nbdkit_error ("offset is larger than the real size " > + "of the underlying file or device"); > + return -1; > + } > + return real_size - offset; > } > > /* Read data. */ > @@ -176,7 +176,6 @@ static struct nbdkit_filter filter = { > .longname = "nbdkit offset filter", > .version = PACKAGE_VERSION, > .config = offset_config, > - .config_complete = offset_config_complete, > .config_help = offset_config_help, > .get_size = offset_get_size, > .pread = offset_pread, > -- > 2.21.0 > > _______________________________________________ > Libguestfs mailing list > Libguestfs@redhat.com > https://www.redhat.com/mailman/listinfo/libguestfs-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/
Possibly Parallel Threads
- [PATCH nbdkit filters-v2 3/5] filters: Add nbdkit-offset-filter.
- [PATCH nbdkit filters-v2 5/5] INCOMPLETE filters: Add nbdkit-partition-filter.
- [PATCH nbdkit filters-v2 0/5] Introduce filters.
- [nbdkit PATCH] offset, partition: Fix .extents with non-zero offset
- [PATCH nbdkit filters-v3 0/7] Introduce filters.