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' "

Reply via email to