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 773207 - audio-converter: incorrect use of memcpy for in-place conversion in do_unpack()
audio-converter: incorrect use of memcpy for in-place conversion in do_unpack()
Status: RESOLVED DUPLICATE of bug 773073
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
1.8.3
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2016-10-19 08:51 UTC by Petr Kulhavy
Modified: 2016-10-26 17:09 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Patch for converter_passthrough() (1.07 KB, patch)
2016-10-19 11:59 UTC, Petr Kulhavy
rejected Details | Review
This is a patch for do_unpack() (1.00 KB, patch)
2016-10-19 12:00 UTC, Petr Kulhavy
none Details | Review
Patch for do_unpack() - version 2 with assertion (1.80 KB, patch)
2016-10-20 17:19 UTC, Petr Kulhavy
rejected Details | Review

Description Petr Kulhavy 2016-10-19 08:51:40 UTC
If in-place unpack is allowed and the format is the default format the do_unpack() function calls memcpy with source and destination being the same pointer. This is forbidden by the library standard:

"The memcpy() function copies n bytes from memory area src to memory area dest.  The memory areas must not overlap.  Use memmove(3) if the memory areas do overlap."

Therefore memmove should be used instead.

The code snippet from do_unpack() :

    if (in_writable && chain->allow_ip) {
      tmp = convert->in_data;
      GST_LOG ("unpack in-place %p, %" G_GSIZE_FORMAT, tmp, num_samples);
    } else {
...
    }

    if (convert->in_data) {
      for (i = 0; i < chain->blocks; i++) {
        if (convert->in_default) {
          GST_LOG ("copy %p, %p, %" G_GSIZE_FORMAT, tmp[i], convert->in_data[i],
              num_samples);
          memcpy (tmp[i], convert->in_data[i], num_samples * chain->stride);
        } else {
...
        }
      }
    } else {
...
Comment 1 Petr Kulhavy 2016-10-19 09:00:33 UTC
The same issue is potentially in converter_passthrough() if called with out==in. But there it's not clear to me if this case can happen at all. For any case it would be useful to either also use memmove there or to mention in a comment that out must not equal in.
Comment 2 Sebastian Dröge (slomo) 2016-10-19 09:11:49 UTC
(In reply to Petr Kulhavy from comment #1)
> The same issue is potentially in converter_passthrough() if called with
> out==in. But there it's not clear to me if this case can happen at all. For
> any case it would be useful to either also use memmove there or to mention
> in a comment that out must not equal in.

Or an assertion instead of a comment to actually enforce it.


Do you plan to provide patches for these two problems?
Comment 3 Petr Kulhavy 2016-10-19 09:31:21 UTC
Yes, I will provide the patches. 

I guess in the do_unpack() this situation can happen, please correct me if I'm wrong. And then the memcpy can be actually just skipped, because it copies the data over itself.

In converter_passthrough() it probably never happens, my experience shows that it is not called at all. So I will put an assert there.

I just don't want to break something due to my ignorance...
Comment 4 Petr Kulhavy 2016-10-19 11:59:38 UTC
Created attachment 338012 [details] [review]
Patch for converter_passthrough()

This is the patch with assert in converter_passthrough()
Comment 5 Petr Kulhavy 2016-10-19 12:00:53 UTC
Created attachment 338013 [details] [review]
This is a patch for do_unpack()

I've realized the check is already there. The memcpy is never called with dst==src. So just add a comment to explicitly point it out.
Comment 6 Sebastian Dröge (slomo) 2016-10-20 11:35:08 UTC
Comment on attachment 338013 [details] [review]
This is a patch for do_unpack()

Adding an assertion for the memcpy() would still seem useful here, or don't you think?

Also just adding that to gst_audio_converter_samples() would make sense IMHO
Comment 7 Petr Kulhavy 2016-10-20 12:21:05 UTC
(In reply to Sebastian Dröge (slomo) from comment #6)

> Adding an assertion for the memcpy() would still seem useful here, or don't
> you think?

It is actually not needed. The long if:

if (!chain->allow_ip || !in_writable || !convert->in_default)

takes care of that. The condition is equal to !(chain->allow_ip && in_writable && convert->in_default) which is exactly the only case when the memcpy() is called with dst==src.
Comment 8 Sebastian Dröge (slomo) 2016-10-20 13:31:19 UTC
Yes I mean making exactly this explicit in the memcpy() branch. Someone might add code there later which breaks this assumption otherwise :)
Comment 9 Petr Kulhavy 2016-10-20 17:19:13 UTC
Created attachment 338108 [details] [review]
Patch for do_unpack() - version 2 with assertion

Now I see what you mean. That makes sense. Attaching a new patch.
I also moved the if out of the loop, which will slightly speed up the processing for non-interleaved channels.
Comment 10 Petr Kulhavy 2016-10-26 17:04:50 UTC
With the changes in https://bugzilla.gnome.org/show_bug.cgi?id=773073
the patch for converter passthrough is no longer relevant.
Comment 11 Sebastian Dröge (slomo) 2016-10-26 17:09:32 UTC

*** This bug has been marked as a duplicate of bug 773073 ***