After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 711048 - glocalfileinputstream.c allows skip past end of file
glocalfileinputstream.c allows skip past end of file
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gio
2.38.x
Other Linux
: Normal minor
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2013-10-29 05:59 UTC by Ross Lagerwall
Modified: 2013-11-03 04:59 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gio: Don't allow skipping past the end of GLocalFileInputStream (1.53 KB, patch)
2013-10-29 06:06 UTC, Ross Lagerwall
reviewed Details | Review
gio: Don't allow skipping past the end of GLocalFileInputStream (2.27 KB, patch)
2013-10-29 18:31 UTC, Ross Lagerwall
reviewed Details | Review

Description Ross Lagerwall 2013-10-29 05:59:59 UTC
The efficient skip implementation of glocalfileinputstream.c allows skipping past the end of the file (causing subsequent calls of g_seekable_tell() to give the wrong value) which is incorrect with respect to the documentation:

"""
This is identical to g_input_stream_read(), from a behaviour standpoint, but the bytes that are skipped are not returned to the user. Some streams have an implementation that is more efficient than reading the data.
"""
Comment 1 Ross Lagerwall 2013-10-29 06:06:28 UTC
Created attachment 258406 [details] [review]
gio: Don't allow skipping past the end of GLocalFileInputStream

The overridden implementation of the skip method for
GLocalFileInputStream allows skipping past the end of the file which is
inconsistent with the documentation.  Prevent this by first seeking to
the end of the file and then seeking backwards from there as much as
is necessary.
Comment 2 Colin Walters 2013-10-29 15:23:01 UTC
Review of attachment 258406 [details] [review]:

Ok, a few things:

1) Can you briefly mention the real-world application if any that caused you to find this?  That type of thing can be really useful when tracking down issues later.
Something like "The gvfs mime code uses skip, and hit this error..."  (just an offhand guess).

2) I'm always a lot more confident reviewing patches like this if they come with tests.

3) Do we even need this code at all?  I am confused why we need to both implement GInputStream->skip() and GSeekable.  The base GInputStream skip will just call into the GSeekable implementation for GLocalFileInputStream.  So would it also work to just delete g_local_file_input_stream_skip(), or am I crazy?
Comment 3 Dan Winship 2013-10-29 15:34:54 UTC
(In reply to comment #2)
> 3) Do we even need this code at all?  I am confused why we need to both
> implement GInputStream->skip() and GSeekable.  The base GInputStream skip will
> just call into the GSeekable implementation for GLocalFileInputStream.  So
> would it also work to just delete g_local_file_input_stream_skip(), or am I
> crazy?

in theory we don't need this implementation. see bug 681374. However, the patch there is awkward because it runs into the problem of recursive g_input_stream_set_pending() calls (eg, g_file_input_stream_seek() calls g_input_stream_set_pending(), so it can't be called from inside g_input_stream_skip()). (That problem is also discussed in bug 707912.) So this patch may be a good temporary fix...
Comment 4 Ross Lagerwall 2013-10-29 17:14:35 UTC
(In reply to comment #2)
> Review of attachment 258406 [details] [review]:
> 
> Ok, a few things:
> 
> 1) Can you briefly mention the real-world application if any that caused you to
> find this?  That type of thing can be really useful when tracking down issues
> later.
> Something like "The gvfs mime code uses skip, and hit this error..."  (just an
> offhand guess).

Unfortunately not that interesting.  I'm writing a test suite for gio and the gvfs implementations of it (not published anywhere yet...) and fixing or implementing things as I find them.  Mostly the local file implementation is correct according to the documentation and the gvfs backends have weird corner cases but in this case it was reversed...

Yes, it is a corner case but either it should be fixed or the docs should be changed :-)

> 
> 2) I'm always a lot more confident reviewing patches like this if they come
> with tests.

I haven't looked at the glib test suite before but let me see if I can put something together.

> 
> 3) Do we even need this code at all?  I am confused why we need to both
> implement GInputStream->skip() and GSeekable.  The base GInputStream skip will
> just call into the GSeekable implementation for GLocalFileInputStream.  So
> would it also work to just delete g_local_file_input_stream_skip(), or am I
> crazy?

But doesn't that still allow you to skip past the end of the file if it just defers to seek?

I guess it would work with Dan's patch in #681374.



(In reply to comment #3)
> (In reply to comment #2)
> > 3) Do we even need this code at all?  I am confused why we need to both
> > implement GInputStream->skip() and GSeekable.  The base GInputStream skip will
> > just call into the GSeekable implementation for GLocalFileInputStream.  So
> > would it also work to just delete g_local_file_input_stream_skip(), or am I
> > crazy?
> 
> in theory we don't need this implementation. see bug 681374. However, the patch
> there is awkward because it runs into the problem of recursive
> g_input_stream_set_pending() calls (eg, g_file_input_stream_seek() calls
> g_input_stream_set_pending(), so it can't be called from inside
> g_input_stream_skip()). (That problem is also discussed in bug 707912.) So this
> patch may be a good temporary fix...

Ah, I didn't see that bug.  But yeah, this fix should be good for the meantime.
Comment 5 Colin Walters 2013-10-29 17:19:07 UTC
(In reply to comment #4)
>
> Unfortunately not that interesting.  I'm writing a test suite for gio and the
> gvfs implementations of it (not published anywhere yet...)

glib/gio/tests *is* a test suite for gio (and gvfs to some degree).

> I guess it would work with Dan's patch in #681374.

Ok, I'm going to defer to Dan on this one.  I am not familiar at all with the gio seeking code.  If you feel confident enough to review his patch, please do!
Comment 6 Ross Lagerwall 2013-10-29 18:31:22 UTC
Created attachment 258478 [details] [review]
gio: Don't allow skipping past the end of GLocalFileInputStream

The overridden implementation of the skip method for
GLocalFileInputStream allows skipping past the end of the file which is
inconsistent with the documentation.  Prevent this by first seeking to
the end of the file and then seeking backwards from there as much as
is necessary.
Comment 7 Ross Lagerwall 2013-10-29 18:38:10 UTC
The updated patch adds a test.


(In reply to comment #5)
> (In reply to comment #4)
> >
> > Unfortunately not that interesting.  I'm writing a test suite for gio and the
> > gvfs implementations of it (not published anywhere yet...)
> 
> glib/gio/tests *is* a test suite for gio (and gvfs to some degree).

Yeah, I'm just doing it to familiarize myself with the whole API and where the local backend and the gvfs backends stand in terms of functionality.

> 
> > I guess it would work with Dan's patch in #681374.
> 
> Ok, I'm going to defer to Dan on this one.  I am not familiar at all with the
> gio seeking code.  If you feel confident enough to review his patch, please do!

Nope :-)
Comment 8 Dan Winship 2013-11-02 22:29:09 UTC
Comment on attachment 258478 [details] [review]
gio: Don't allow skipping past the end of GLocalFileInputStream

>+  if (res - start > count)
>+    {
>+      res = lseek (file->priv->fd, count - (res - start), SEEK_CUR);

I think it would be more obvious as:

        res = lseek (file->priv->fd, start + count, SEEK_START);

Also, the function would probably be clearer now if you renamed "res" to "end".


test case looks good. Feel free to commit with the above change.
Comment 9 Ross Lagerwall 2013-11-03 04:59:09 UTC
Pushed to master as 89f9615. Thanks!