Hello,
I could reproduce an segfault at my Jessie/testing (on amd64).
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffd37fe700 (LWP 18338)]
sock_destroy (info=info@entry=0x7fff000001f0,
ShutdownMethod=ShutdownMethod@entry=2) at src/genlib/net/sock.c:95
95 if (info->socket != INVALID_SOCKET) {
(gdb) bt
#0 sock_destroy (info=info@entry=0x7fff000001f0,
ShutdownMethod=ShutdownMethod@entry=2) at src/genlib/net/sock.c:95
#1 0x00007ffff79a8daa in http_CloseHttpGet (Handle=0x7fff00000000) at
src/genlib/net/http/httpreadwrite.c:1456
#2 0x000055555555cb8a in FileBuffer_Read (file=0x7fffcc007020,
buffer=0x7fffc8015710 "\377\330\377", <incomplete sequence \340>, size=16384,
offset=0) at file_buffer.c:238
#3 0x0000555555562d3d in fs_read (path=<optimized out>, buf=<optimized out>,
size=<optimized out>, offset=<optimized out>, fi=<optimized out>) at
fuse_main.c:327
#4 0x00007ffff734d574 in fuse_fs_read_buf (fs=0x555555773100,
path=0x7fffc8000af0 "/AVM FRITZ!Mediaserver/Bilder/Alle
Bilder/FRITZ-Picture.jpg", bufp=0x7fffd37fdca0, size=16384, off=0,
fi=0x7fffd37fdd40) at fuse.c:1829
#5 0x00007ffff734d732 in fuse_lib_read (req=0x7fffc80122c0, ino=22,
size=16384, off=0, fi=0x7fffd37fdd40) at fuse.c:3287
#6 0x00007ffff735608e in do_read (req=<optimized out>, nodeid=<optimized out>,
inarg=<optimized out>) at fuse_lowlevel.c:1232
#7 0x00007ffff7356895 in fuse_ll_process_buf (data=0x555555773290,
buf=0x7fffd37fdf00, ch=<optimized out>) at fuse_lowlevel.c:2441
#8 0x00007ffff7353394 in fuse_do_work (data=0x555555772f10) at
fuse_loop_mt.c:117
#9 0x00007ffff712b0a4 in start_thread (arg=0x7fffd37fe700) at
pthread_create.c:309
#10 0x00007ffff6e5fccd in clone () at
../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb) print *info
Cannot access memory at address 0x7fff000001f0
(gdb) up
#1 0x00007ffff79a8daa in http_CloseHttpGet (Handle=0x7fff00000000) at
src/genlib/net/http/httpreadwrite.c:1456
1456 sock_destroy(&handle->sock_info, SD_BOTH);
(gdb) print *handle
Cannot access memory at address 0x7fff00000000
In my case this happens because function UpnpReadHttpGet gets
as parameter a pointer to a size variable and is set inside.
Unfortunately this variable of type unsigned int is only 4 bytes.
Inside UpnpReadHttpGet it is written as size_t with 8 bytes.
Therefore the variable handle is corrupted and the later access
to it results in the crash.
When building the djmount package there is already a warning
about this difference shown.
When using size_t instead of unsigned int in declaration of
variable read_size (file_buffer.c:215) the warning is gone and
the crash does not happen when browsing the directory structure
or accessing files.
(See attached patch; excerpts of the gdb session are also attached)
Kind regards,
Bernhard
mkdir /home/bernhard/debian/djmount; cd /home/bernhard/debian/djmount
mkdir djmount; cd djmount
apt-get source djmount
cd djmount-0.71
dpkg-buildpackage
cd ../..
mkdir libfuse2; cd libfuse2
apt-get source libfuse2
cd fuse-2.9.3/
dpkg-buildpackage
cd ../..
mkdir libupnp6; cd libupnp6
apt-get source libupnp6
cd libupnp-1.6.19+git20141001/
dpkg-buildpackage
cd ../..
mkdir /mnt/djmount
LD_LIBRARY_PATH=/home/bernhard/debian/djmount/libfuse2/fuse-2.9.3/lib/.libs:/home/bernhard/debian/djmount/libupnp6/libupnp-1.6.19+git20141001/upnp/.libs/
gdb --args /home/bernhard/debian/djmount/djmount/djmount-0.71/djmount/djmount
-f /mnt/djmount
...
(gdb) run
...
# navigate e.g. in dolphin the mounted structure
...
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffd37fe700 (LWP 18338)]
sock_destroy (info=info@entry=0x7fff000001f0,
ShutdownMethod=ShutdownMethod@entry=2) at src/genlib/net/sock.c:95
95 if (info->socket != INVALID_SOCKET) {
(gdb) bt
#0 sock_destroy (info=info@entry=0x7fff000001f0,
ShutdownMethod=ShutdownMethod@entry=2) at src/genlib/net/sock.c:95
#1 0x00007ffff79a8daa in http_CloseHttpGet (Handle=0x7fff00000000) at
src/genlib/net/http/httpreadwrite.c:1456
#2 0x000055555555cb8a in FileBuffer_Read (file=0x7fffcc007020,
buffer=0x7fffc8015710 "\377\330\377", <incomplete sequence \340>, size=16384,
offset=0) at file_buffer.c:238
#3 0x0000555555562d3d in fs_read (path=<optimized out>, buf=<optimized out>,
size=<optimized out>, offset=<optimized out>, fi=<optimized out>) at
fuse_main.c:327
#4 0x00007ffff734d574 in fuse_fs_read_buf (fs=0x555555773100,
path=0x7fffc8000af0 "/AVM FRITZ!Mediaserver/Bilder/Alle
Bilder/FRITZ-Picture.jpg", bufp=0x7fffd37fdca0, size=16384, off=0,
fi=0x7fffd37fdd40) at fuse.c:1829
#5 0x00007ffff734d732 in fuse_lib_read (req=0x7fffc80122c0, ino=22,
size=16384, off=0, fi=0x7fffd37fdd40) at fuse.c:3287
#6 0x00007ffff735608e in do_read (req=<optimized out>, nodeid=<optimized out>,
inarg=<optimized out>) at fuse_lowlevel.c:1232
#7 0x00007ffff7356895 in fuse_ll_process_buf (data=0x555555773290,
buf=0x7fffd37fdf00, ch=<optimized out>) at fuse_lowlevel.c:2441
#8 0x00007ffff7353394 in fuse_do_work (data=0x555555772f10) at
fuse_loop_mt.c:117
#9 0x00007ffff712b0a4 in start_thread (arg=0x7fffd37fe700) at
pthread_create.c:309
#10 0x00007ffff6e5fccd in clone () at
../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb) print *info
Cannot access memory at address 0x7fff000001f0
(gdb) up
#1 0x00007ffff79a8daa in http_CloseHttpGet (Handle=0x7fff00000000) at
src/genlib/net/http/httpreadwrite.c:1456
1456 sock_destroy(&handle->sock_info, SD_BOTH);
(gdb) print *handle
Cannot access memory at address 0x7fff00000000
(gdb) up
#2 0x000055555555cb8a in FileBuffer_Read (file=0x7fffcc007020,
buffer=0x7fffc8015710 "\377\330\377", <incomplete sequence \340>, size=16384,
offset=0) at file_buffer.c:238
238 rc = UpnpCloseHttpGet (handle);
(gdb) print handle
$3 = (void *) 0x7fff00000000
(gdb) b 195
Breakpoint 1 at 0x55555555ca1a: file file_buffer.c, line 195.
(gdb) kill
Kill the program being debugged? (y or n) y
...
#in another shell
fusermount -u /mnt/djmount
#back in the same gdb session
(gdb) run
...
# navigate e.g. in dolphin the mounted structure
...
Breakpoint 1, FileBuffer_Read (file=0x7fffdc0053d0, buffer=0x7fffc0007d20
"\200i", size=16384, offset=0) at file_buffer.c:195
195 void* handle = NULL;
(gdb) next
196 int contentLength = 0;
(gdb) print handle
$4 = (void *) 0x0
(gdb) watch handle
Hardware watchpoint 2: handle
(gdb) cont
Continuing.
Hardware watchpoint 2: handle
Old value = (void *) 0x0
New value = (void *) 0x7fffc00023f0
0x00007ffff79aaea3 in http_OpenHttpGetEx (url_str=0x7fffd37fd800 "5n",
Handle=0x7fffd37fdbd8, contentType=0x7fffd37fdbe0, contentLength=0x0,
httpStatus=0x7fffd37fdbd0, lowRange=-1073713611, highRange=16384, timeout=30)
at src/genlib/net/http/httpreadwrite.c:2114
2114 *Handle = handle;
(gdb) print handle
$5 = (http_get_handle_t *) 0x7fffc00023f0
(gdb) print *handle
$6 = {response = {msg = {initialized = 1, method = HTTPMETHOD_POST, uri = {type
= ABSOLUTE, scheme = {buff = 0x0, size = 0}, path_type = ABS_PATH, pathquery =
{buff = 0x0, size = 0}, fragment = {buff = 0x0, size = 0}, hostport = {
text = {buff = 0x0, size = 0}, IPaddress = {ss_family = 0, __ss_align
= 0, __ss_padding = '\000' <repeats 111 times>}}}, request_method =
HTTPMETHOD_GET, status_code = 206, status_msg = {
buf = 0x7fffc00046d0 "Partial Content", length = 15, capacity = 15,
size_inc = 5}, amount_discarded = 0, is_request = 0, major_version = 1,
minor_version = 1, headers = {head = {prev = 0x0, next = 0x7fffc0002f80, item =
0x0},
tail = {prev = 0x7fffc0006d50, next = 0x0, item = 0x0}, size = 11,
freeNodeList = {head = 0x0, element_size = 24, maxFreeListLength = 100,
freeListLength = 0}, free_func = 0x7ffff79a50e0 <httpheader_free>,
cmp_func = 0x7ffff79a5100 <httpmsg_compare>}, entity = {buf =
0x7fffc000be93 "\377\330\377", <incomplete sequence \340>, length = 0}, msg = {
buf = 0x7fffc000bd30 "HTTP/1.1 206 Partial Content\r\nAccept-Ranges:
bytes\r\nCache-Control: max-age=120\r\nConnection: close\r\nContent-Length:
16385\r\nContent-Range: bytes 0-16384/30192\r\nContent-Type:
image/jpeg\r\nDate: Fri, 12 De"..., length = 2048, capacity = 2048, size_inc =
5}, urlbuf = 0x0}, http_error_code = 400, valid_ssdp_notify_hack = 0, position
= POS_ENTITY, ent_position = 2, content_length = 16385, chunk_size = 0,
entity_start_position = 355,
scanner = {msg = 0x7fffc0002578, cursor = 355, entire_msg_loaded = 0}},
sock_info = {socket = 10, foreign_sockaddr = {ss_family = 0, __ss_align = 0,
__ss_padding = '\000' <repeats 111 times>}}, entity_offset = 0, cancel = 0}
(gdb) cont
Continuing.
Hardware watchpoint 2: handle
Old value = (void *) 0x7fffc00023f0
New value = (void *) 0x7fff00000000
0x00007ffff79a8cde in http_ReadHttpGet (Handle=0x7fffc00023f0,
buf=0x7fffc0007d20 "\200i", size=0x7fffd37fdbd4, timeout=30) at
src/genlib/net/http/httpreadwrite.c:1362
1362 *size = handle->response.msg.entity.length -
(gdb) print size
$7 = (size_t *) 0x7fffd37fdbd4
(gdb) print *size
$8 = 16385
(gdb) bt
#0 0x00007ffff79a8cde in http_ReadHttpGet (Handle=0x7fffc00023f0,
buf=0x7fffc0007d20 "\200i", size=0x7fffd37fdbd4, timeout=30) at
src/genlib/net/http/httpreadwrite.c:1362
#1 0x000055555555cae0 in FileBuffer_Read (file=0x7fffdc0053d0,
buffer=0x7fffc0007d20 "\200i", size=16384, offset=0) at file_buffer.c:224
#2 0x0000555555562d3d in fs_read (path=<optimized out>, buf=<optimized out>,
size=<optimized out>, offset=<optimized out>, fi=<optimized out>) at
fuse_main.c:327
#3 0x00007ffff734d574 in fuse_fs_read_buf (fs=0x555555773100,
path=0x7fffc0000990 "/AVM FRITZ!Mediaserver/Bilder/Alle
Bilder/FRITZ-Picture.jpg", bufp=0x7fffd37fdca0, size=16384, off=0,
fi=0x7fffd37fdd40) at fuse.c:1829
#4 0x00007ffff734d732 in fuse_lib_read (req=0x7fffc0006b90, ino=21,
size=16384, off=0, fi=0x7fffd37fdd40) at fuse.c:3287
#5 0x00007ffff735608e in do_read (req=<optimized out>, nodeid=<optimized out>,
inarg=<optimized out>) at fuse_lowlevel.c:1232
#6 0x00007ffff7356895 in fuse_ll_process_buf (data=0x555555773290,
buf=0x7fffd37fdf00, ch=<optimized out>) at fuse_lowlevel.c:2441
#7 0x00007ffff7353394 in fuse_do_work (data=0x7fffc80008c0) at
fuse_loop_mt.c:117
#8 0x00007ffff712b0a4 in start_thread (arg=0x7fffd37fe700) at
pthread_create.c:309
#9 0x00007ffff6e5fccd in clone () at
../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb) up
#1 0x000055555555cae0 in FileBuffer_Read (file=0x7fffdc0053d0,
buffer=0x7fffc0007d20 "\200i", size=16384, offset=0) at file_buffer.c:224
224 rc = UpnpReadHttpGet (handle, buffer + n,
&read_size,
(gdb) print &read_size
$9 = (unsigned int *) 0x7fffd37fdbd4
(gdb) print &handle
$10 = (void **) 0x7fffd37fdbd8
(gdb) print sizeof(size_t)
$11 = 8
(gdb) print sizeof(unsigned int)
$12 = 4
-----------------
upnpapi.c:
int UpnpReadHttpGet(void *Handle, char *buf, size_t *size, int timeout)
when building the package this warning is also visible:
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -D_FORTIFY_SOURCE=2 -I../gl -pthread
-I/usr/include/upnp -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse
-DFUSE_USE_VERSION=22 -g -O2 -fstack-protector-strong -Wformat
-Werror=format-security -fPIE -fstack-protector-strong -D_FORTIFY_SOURCE=2
-Wformat -Wformat-security -Werror=format-security -Wall -pthread -MT
file_buffer.o -MD -MP -MF ".deps/file_buffer.Tpo" -c -o file_buffer.o
file_buffer.c; \
then mv -f ".deps/file_buffer.Tpo" ".deps/file_buffer.Po"; else rm -f
".deps/file_buffer.Tpo"; exit 1; fi
file_buffer.c: In function ‘FileBuffer_Read’:
file_buffer.c:224:46: warning: passing argument 3 of ‘UpnpReadHttpGet’ from
incompatible pointer type
rc = UpnpReadHttpGet (handle, buffer + n, &read_size,
^
In file included from file_buffer.c:37:0:
/usr/include/upnp/upnp.h:2451:17: note: expected ‘size_t *’ but argument is
of type ‘unsigned int *’
EXPORT_SPEC int UpnpReadHttpGet(
^
Description: Avoid crash by using size_t instead of unsigned int
Author: Bernhard Ãbelacker <[email protected]>
Bug-Debian: https://bugs.debian.org/701680
Last-Update: <2014-12-12>
--- djmount-0.71.orig/djmount/file_buffer.c
+++ djmount-0.71/djmount/file_buffer.c
@@ -212,7 +212,7 @@ FileBuffer_Read (FileBuffer* file, char*
* to return the exact number of bytes requested.
*/
do {
- unsigned int read_size = size - n;
+ size_t read_size = size - n;
if (n > 0) {
Log_Printf (LOG_DEBUG,
"UpnpReadHttpGet loop ! url '%s' "