Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More array abstraction use in ptp2 #1040

Merged
merged 19 commits into from
Oct 14, 2024
Merged

More array abstraction use in ptp2 #1040

merged 19 commits into from
Oct 14, 2024

Conversation

axxel
Copy link
Contributor

@axxel axxel commented Oct 14, 2024

More use of the new array abstraction in the ptp2 camlib and some minor cleanups along the way. The PTPParams struct is now completely converted to use the array macros. Also more preparation steps towards merging dpd_cache and canon_props.

There is a new TODO and a FIXME comment related to old/potential bugs.

axxel added 19 commits October 12, 2024 17:45
To be able to use the array macros in PTP and GP error "contexts", this
makes translate_ptp_result() tolerate both "types" of errors.

I added a comment regarding the use of the GP_ERROR_NO_MEMORY use. This is
related to gphoto#1008.
…leaks

ptp_free_object was leaking the memory of the mtp_props member and
ptp_ptp_free_devicepropvalue was leaking array memory of certain types.
This prepares the merging of the dpd_cache and the canon_props members of
PTPParams.
Now dpd_cache and canon_props have the same type and can be merged.
This reduces code bloat and hopefully helps with not forgetting to call
the destructor of freed objects before freeing the array.
This also fixes a likely memcopy out of bounds error, see TODO comment.
Make it more obvious that array_extend (now array_extend_capacity) only
increases the allocated memory but does not change the len parameter.
Comment on lines +43 to +49
/* FIXME: GP_ERROR_NO_MEMORY is used to communicate two completely differnt
* things, which have nothing to do with each other:
* - the camera went out of memory because the storage space ran out, this
* is totally "normal"
* - a malloc on the host computer failed: this will completely interrupt
* the functionality and likely crash the process soonish
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it could be fixed alongside other changes?

@msmeissn msmeissn merged commit adafc61 into gphoto:master Oct 14, 2024
5 checks passed
@axxel axxel deleted the more-arrays branch October 14, 2024 13:19
@msmeissn
Copy link
Contributor

This causes problems found in fuzzing.

==2477413==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf1d03bf4 at pc 0xf2529aff bp 0xffff3f38 sp 0xffff3f2c
READ of size 4 at 0xf1d03bf4 thread T0
#0 0xf2529afe in find_child ptp2/library.c:8034
#1 0xf256de6c in get_info_func ptp2/library.c:9378
#2 0xf78a9761 in gp_filesystem_get_info /home/marcus/projects/afl/libgphoto2/libgphoto2/gphoto2-filesys.c:1867
#3 0xf787dc7a in gp_camera_file_get_info /home/marcus/projects/afl/libgphoto2/libgphoto2/gphoto2-camera.c:1594
#4 0x804d0a7 in recursive_directory /home/marcus/projects/afl/libgphoto2/examples/sample-afl.c:79
#5 0x804cdc9 in recursive_directory /home/marcus/projects/afl/libgphoto2/examples/sample-afl.c:54
#6 0x804b26f in main /home/marcus/projects/afl/libgphoto2/examples/sample-afl.c:199
#7 0xf748cd42 in __libc_start_call_main (/lib/libc.so.6+0x24d42) (BuildId: f7c4dd2ccb33969978ca0f5f4ee1df60da37b43b)
#8 0xf748ce07 in __libc_start_main@GLIBC_2.0 (/lib/libc.so.6+0x24e07) (BuildId: f7c4dd2ccb33969978ca0f5f4ee1df60da37b43b)
#9 0x804c687 in _start ../sysdeps/i386/start.S:110

0xf1d03bf4 is located 0 bytes after 500-byte region [0xf1d03a00,0xf1d03bf4)
allocated by thread T0 here:
#0 0xf7a35967 (/lib/libasan.so.8+0xec967) (BuildId: 73a4cd09d0f4b5e83f4566f3b3246a2460ce6d18)
#1 0xf251a906 in ptp_object_find_or_insert ptp2/ptp.c:9407
#2 0xf251a906 in ptp_object_find_or_insert ptp2/ptp.c:9360

SUMMARY: AddressSanitizer: heap-buffer-overflow ptp2/library.c:8034 in find_child
Shadow bytes around the buggy address:
0xf1d03900: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0xf1d03980: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0xf1d03a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xf1d03a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

@axxel
Copy link
Contributor Author

axxel commented Oct 17, 2024

At a first glance, I assume this is caused by the fact that ptp_object_want may change the list that we are just iterating over. When working on this, I stumbled upon that fact, which is also mentioned as e.g. "DANGEROUS" in several places throughout the code base. I came to the conclusion that this needs to change and wanted to look into that next. I have not expected that any of my changes made the situation worse with regards to this issue, but it might very well be the case.

I'll look into this soon. Can you maybe give me a hint on how to reproduce your fuzzing?

@msmeissn
Copy link
Contributor

I debugged a bit, and it might have been there before already.

The ptp_object_want call ptp_getobjectinfo and that fails in the fuzzer run, and that causes the object to be removed from the list in ptp_object_want (instead of the assumption of always adding to the list).

I think this removal is risky. perhaps better mark it as "no longer present" object or so (or one that can reappear).

@msmeissn
Copy link
Contributor

Reproducer:

in libgphoto2/libgphoto2_port/vusb/vcamera.h change:

-#undef FUZZING
+#define FUZZING

unzip crash.zip
CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -O2 -Wall -g" ./configure --enable-vusb --prefix=/usr --libdir=/usr/lib64
make
make check
sudo make install
sudo rm /usr/lib64/libgphoto2_port/0.12.2/usb*

examples/.libs/sample-afl crash

crash.zip

The object array is initially 8 entries, but the find_child loop shrinks it to 4 and then crashes.

I kind of feel the loop tries to remove TWO entries at once somehow, so the ENTRY.val+ENTRY.len!=PTR end of array check does not trigger and it overreads the list.

@axxel
Copy link
Contributor Author

axxel commented Oct 17, 2024

I think this removal is risky. perhaps better mark it as "no longer present" object or so (or one that can reappear).

That was exactly my thinking as well. And I thought about splitting ptp_object_want in a part that might change the list and a part that does not. I have to get a full picture of all it's uses first, though.

@msmeissn
Copy link
Contributor

msmeissn commented Oct 18, 2024

 #define for_each(TYPE, PTR, ARRAY) \
-       for (TYPE PTR = ARRAY.val; PTR != ARRAY.val + ARRAY.len; ++PTR)
+       for (TYPE PTR = ARRAY.val; PTR < ARRAY.val + ARRAY.len; ++PTR)

seems to "workaround" it.

@axxel axxel mentioned this pull request Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants