When the remote device sends the 'CreateFolder' command, obexd
first tries to verify the path in ftp_setpath(). Because we are
creating a new directory, the verify_path() is expected to fail (it does
not exist yet; ENOENT).
Trap that special case and cause the function to fail directly to the
create directory path.
If session owner disconnect from the bus while g_obex_connect is pending
it may lead to a crash since it is never canceled connected_cb may still
be called after callback_data is freed.
When client queries for the size of a phonebook we fall into a
indefinite loop as g_obex_apparam_encode always returns the same
number of items added to the buffer regardless how often it is
called. In former times where this code wasn't using GObexApparams
a array was reduced each time the headers where added and so we could
easily find out when we've added all headers. However today we need
to solve this a bit differently by also setting the firstpacket flag
when we receive the phonebook size result from the phonebook
implementation which then lets us correctly go through without
falling into a indefinite loop.
If the owner disconnects the session should be destroyed even if the
connection is pending:
obexd/client/session.c:owner_disconnected()
obexd/client/session.c:obc_session_shutdown() 0x822abb8
obexd/client/session.c:obc_session_ref() 0x822abb8: ref=3
obexd/client/session.c:obc_session_unref() 0x822abb8: ref=2
obexd/client/bluetooth.c:transport_connect() port 19
obexd/client/bluetooth.c:transport_callback()
obexd/client/session.c:transport_func()
obexd/client/bluetooth.c:bluetooth_getpacketopt()
obexd/client/pbap.c:pbap_probe() /org/bluez/obex/client/session1
obexd/client/session.c:obc_session_ref() 0x822abb8: ref=3
obexd/client/session.c:obc_session_register() Session(0x822abb8) registered /org/bluez/obex/client/session1
obexd/client/session.c:obc_session_unref() 0x822abb8: ref=2
To fix this the code now checks if the connect callback is pending, in
that case destroy the callback releasing the reference it carrying.
session_process_queue needs to be able to access the request .func in
case an error happen and it later calls pending_request_free so .process
shall not attempt to free the request otherwise it will cause crashes:
Invalid read of size 8
at 0x4349D2: session_process_queue (session.c:857)
by 0x434AC5: setpath_complete.isra.1 (session.c:1026)
by 0x434B29: setpath_cb (session.c:1077)
by 0x416448: handle_response (gobex.c:1128)
by 0x41739D: incoming_data (gobex.c:1402)
by 0x59747FA: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.4200.2)
by 0x5974B97: ??? (in /usr/lib64/libglib-2.0.so.0.4200.2)
by 0x5974EC1: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.4200.2)
by 0x40E23F: main (main.c:322)
Address 0x66e3d30 is 32 bytes inside a block of size 56 free'd
at 0x4C2ACE9: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x597A50E: g_free (in /usr/lib64/libglib-2.0.so.0.4200.2)
by 0x4345F5: pending_request_free (session.c:193)
by 0x4348DF: session_process_setpath (session.c:1131)
by 0x4349C9: session_process_queue (session.c:854)
by 0x434AC5: setpath_complete.isra.1 (session.c:1026)
by 0x434B29: setpath_cb (session.c:1077)
by 0x416448: handle_response (gobex.c:1128)
by 0x41739D: incoming_data (gobex.c:1402)
by 0x59747FA: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.4200.2)
by 0x5974B97: ??? (in /usr/lib64/libglib-2.0.so.0.4200.2)
by 0x5974EC1: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.4200.2)
This adds supported_features support to obc_driver so driver can
provide this information when connecting.
This is required by PBAP 1.2 (page 48):
'Mandatory if the PSE advertises a PbapSupportedFeatures attribute in
its SDP record, else excluded.'
g_str_equal has been used for the session path compare
which is not NULL-safe. Used the g_strcmp0() for the NULL-Safe
string comparision.
*#0 strcmp (p1=0x0, p2=0x7105c "/org/bluez/obex/client/session0")
* at strcmp.c:38
*#1 0xb6e0cd0a in g_str_equal (v1=<value optimized out>,
* v2=<value optimized out>) at ghash.c:1704
*#2 0x000264d8 in find_session (connection=<value optimized out>,
* message=0x55b38, user_data=<value optimized out>)
* at obexd/client/manager.c:162
*#3 remove_session (connection=<value optimized out>, message=0x55b38,
user_data=<value optimized out>) at obexd/client/manager.c:231
CC obexd/plugins/obexd-filesystem.o
In file included from obexd/plugins/filesystem.c:40:0:
/usr/include/wait.h:1:2: error: #warning redirecting incorrect
#include <wait.h> to <sys/wait.h> [-Werror=cpp]
#warning redirecting incorrect #include <wait.h> to <sys/wait.h>
^
cc1: all warnings being treated as errors
Makefile:6447: recipe for target 'obexd/plugins/obexd-filesystem.o' failed
make[1]: *** [obexd/plugins/obexd-filesystem.o] Error 1
In case the transport is disconnected while disconnect command is pending
the session is freed on disconnect_complete but disconnect callback is
still valid causing the following crash:
Invalid read of size 4
at 0x42682A: obc_session_ref (session.c:132)
by 0x42797B: obc_session_shutdown (session.c:580)
by 0x4139DA: incoming_data (gobex.c:1406)
by 0x59712A5: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3800.2)
by 0x5971627: ??? (in /usr/lib64/libglib-2.0.so.0.3800.2)
by 0x5971A39: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3800.2)
by 0x40D78C: main (main.c:320)
Address 0x728d814 is 4 bytes inside a block of size 120 free'd
at 0x4C28577: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x5976F7E: g_free (in /usr/lib64/libglib-2.0.so.0.3800.2)
by 0x4134B9: handle_response (gobex.c:1129)
by 0x4139BD: incoming_data (gobex.c:1403)
by 0x59712A5: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3800.2)
by 0x5971627: ??? (in /usr/lib64/libglib-2.0.so.0.3800.2)
by 0x5971A39: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3800.2)
by 0x40D78C: main (main.c:320)
Remove snprintf error check. Fixes clang warnings below:
...
obexd/client/map.c:471:9: warning: Access to field 'message' results in
a dereference of a null pointer (loaded from variable 'err')
err->message);
^~~~~~~~~~~~
obexd/client/map.c:772:9: warning: Access to field 'message' results in
a dereference of a null pointer (loaded from variable 'err')
err->message);
^~~~~~~~~~~~
...
Requests have the size set to OBJECT_SIZE_DELETE but if the request has
a body header the size should be set to OBJECT_SIZE_UNKNOWN as it no
longer can be considered a delete request:
"3.4.3.6 Put-Delete and Create-Empty Methods
A PUT operation with NO Body or End-of-Body headers whatsoever should
be treated as a delete request."
In case of GET operation the code does not use g_obex_get_req_pkt since
the beggining to be able to read the header from the first response, this
means that the request should be cancel with g_obex_cancel_req not with
g_obex_cancel_transfer.
The old macro PB_LUID_FOLDER had the folder luid on the second level:
/telecom/luid. But the luid folder occurs per IrMC spec on level three
e.g. /telecom/pb/luid.
It's per-user, so we won't try to overwrite somebody else's
files in /tmp when that happens. It's also (unless we have a
particularly bizarre setup) on the same partition as the destination
folder which means we can atomically move the file to the destination
with a unique filename.
When transport is disconnected unexpectedly it can cause the following
crash:
gobex-DEBUG: gobex/gobex.c:g_obex_send_internal() The transport is not connected
Invalid read of size 8
at 0x42662E: session_process_queue (session.c:789)
by 0x42668F: session_process (session.c:719)
by 0x3D46047E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048157: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048559: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x40D5FC: main (main.c:319)
Address 0x5086760 is 32 bytes inside a block of size 56 free'd
at 0x4A074C4: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x3D4604D9AE: g_free (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x426146: session_process_setpath (session.c:1063)
by 0x426629: session_process_queue (session.c:786)
by 0x42668F: session_process (session.c:719)
by 0x3D46047E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048157: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048559: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x40D5FC: main (main.c:319)
The spec clearly states the handles are hexadecimal:
MAP 1.2 - Page 29
""handle" is the message handle in hexadecimal representation with up
to 16 digits; leading zero digits may be used so the MCE shall accept
both handles with and without leading zeros (e.g.,"00000012345678AB"
or "12345678AB")."
Requests need to be cancelled when obc_session_shutdown is called
otherwise they can trigger the callback with invalid/freed data as in
the following backtrace:
Invalid read of size 8
at 0x426684: setpath_cb (session.c:998)
by 0x412AEB: handle_response (gobex.c:949)
by 0x413010: incoming_data (gobex.c:1192)
by 0x3D46047E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048157: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048559: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x40D59C: main (main.c:319)
Address 0x571f598 is 40 bytes inside a block of size 56 free'd
at 0x4A074C4: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x3D4604D9AE: g_free (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x426EA9: obc_session_shutdown (session.c:555)
by 0x4254B4: remove_session (manager.c:62)
by 0x43DC53: process_message.isra.5 (object.c:259)
by 0x3D4981CE85: ??? (in /usr/lib64/libdbus-1.so.3.7.4)
by 0x3D4980FA30: dbus_connection_dispatch (in /usr/lib64/libdbus-1.so.3.7.4)
by 0x43A9D7: message_dispatch (mainloop.c:76)
by 0x3D46048962: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46047E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048157: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048559: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3600.3)
"Sent" flag value was returned instead of "Protected" one.
This also fix following build error:
CC obexd/client/obexd-map.o
obexd/client/map.c:711:17: error: ‘get_protected’ defined but not
used [-Werror=unused-function]
cc1: all warnings being treated as errors
This fix following build error:
CC obexd/client/obexd-dbus.o
obexd/client/dbus.c:70:13: error: ‘append_array_variant’ defined but
not used [-Werror=unused-function]
obexd/client/dbus.c:97:13: error: ‘append_dict_variant’ defined but
not used [-Werror=unused-function]
This can happen only if there is a bug in obexd code.
This fix following build error:
CC obexd/client/obexd-transfer.o
obexd/client/transfer.c: In function ‘status2str’:
obexd/client/transfer.c:277:1: error: control reaches end of non-void
function [-Werror=return-type]
This fix following build error:
CC obexd/client/obexd-map.o
obexd/client/map.c: In function ‘msg_element’:
obexd/client/map.c:1113:2: error: implicit declaration of function ‘strtoull’ [-Werror=implicit-function-declaration]
This fix following build error:
CC obexd/src/obexd-service.o
obexd/src/service.c: In function ‘obex_service_driver_register’:
obexd/src/service.c💯10: error: unused variable ‘l’ [-Werror=unused-variable]
This can happend only if there is a bug in obexd code.
This fix following buld error:
CC obexd/src/obexd-manager.o
obexd/src/manager.c: In function ‘status2str’:
obexd/src/manager.c:292:1: error: control reaches end of non-void
function [-Werror=return-type]
This fix following build error:
obexd/src/manager.c: At top level:
obexd/src/manager.c:190:13: error:
‘dbus_message_iter_append_dict_entry’ defined but not used
[-Werror=unused-function]
This fix following build error:
CC obexd/client/obexd-mns.o
obexd/client/mns.c:344:38: error: ‘mas_drivers’ defined but not used
[-Werror=unused-variable]
cc1: all warnings being treated as errors
This fix following build error:
CC obexd/client/obexd-mns.o
obexd/client/mns.c: In function ‘parse_event_report_handle’:
obexd/client/mns.c:187:2: error: implicit declaration of function
‘strtoull’ [-Werror=implicit-function-declaration]
This fix following build error:
CC obexd/client/obexd-mns.o
obexd/client/mns.c: In function ‘mns_connect’:
obexd/client/mns.c:105:2: error: implicit declaration of function
‘manager_register_session’ [-Werror=implicit-function-declaration]
obexd/client/mns.c: In function ‘mns_disconnect’:
obexd/client/mns.c:128:2: error: implicit declaration of function
‘manager_unregister_session’ [-Werror=implicit-function-declaration]
This fix following build error:
CC obexd/plugins/obexd-bluetooth.o
obexd/plugins/bluetooth.c:242:6: error: no previous declaration for
‘dict_append_entry’ [-Werror=missing-declarations]
This ix following build errors:
CC obexd/plugins/obexd-bluetooth.o
obexd/plugins/bluetooth.c: In function ‘register_profile_reply’:
obexd/plugins/bluetooth.c:202:10: error: unused variable ‘err’
[-Werror=unused-variable]
obexd/plugins/bluetooth.c: In function ‘name_acquired’:
obexd/plugins/bluetooth.c:367:15: error: unused variable ‘uuid’
[-Werror=unused-variable]
obexd/plugins/bluetooth.c: In function ‘name_released’:
obexd/plugins/bluetooth.c:389:15: error: unused variable ‘uuid’
[-Werror=unused-variable]
obexd/plugins/bluetooth.c: In function ‘bluetooth_start’:
obexd/plugins/bluetooth.c:400:10: error: unused variable ‘ios’
[-Werror=unused-variable]
obexd/client/map.c: In function ‘map_msg_get’:
obexd/client/map.c:446:2: warning: format ‘%u’ expects argument of type
‘unsigned int’, but argument 4 has type ‘uint64_t’ [-Wformat]
obexd/client/map.c:446:2: warning: format ‘%u’ expects argument of type
‘unsigned int’, but argument 4 has type ‘uint64_t’ [-Wformat]
This is more efficient in terms of memory and hash lookups, it is also
not prone to string format bugs in remote stacks such as leading zeros
being treated as a different handle as can be experience with
Nokia N950 which sends events using a handle with leading zeros but
message listing don't have them.
session_process_queue can call a callback which can cause the session to
be freed:
Invalid write of size 4
at 0x4265C9: session_process (session.c:716)
by 0x3D46047E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048157: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048559: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x40D55C: main (main.c:319)
Address 0x4d658a8 is 104 bytes inside a block of size 120 free'd
at 0x4A074C4: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x3D4604D9AE: g_free (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x4265B1: session_process_queue (session.c:794)
by 0x4265C8: session_process (session.c:714)
by 0x3D46047E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048157: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3D46048559: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x40D55C: main (main.c:319)
In order to determine if the message Type property has changed,
the stored type needs to be compared with the parsed type and not with
the raw value received from the MSE.
This fixes the issue that the property changed signal for the Type
property is emitted for every message on every ListMessage call.
sdp_connect fails when Bluetooth adapter is off which leads to the
following leak:
37 bytes in 1 blocks are definitely lost in loss record 68 of 165
at 0x4A06409: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x3B03C4D89E: g_malloc (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3B03C64BAE: g_strdup (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x427D5D: bluetooth_connect (bluetooth.c:410)
by 0x426CC9: obc_session_create (session.c:454)
by 0x425693: create_session (manager.c:203)
by 0x43D8A3: process_message.isra.5 (object.c:259)
by 0x3B0701CE85: ??? (in /usr/lib64/libdbus-1.so.3.7.4)
by 0x3B0700FA30: dbus_connection_dispatch (in /usr/lib64/libdbus-1.so.3.7.4)
by 0x43A627: message_dispatch (mainloop.c:76)
by 0x3B03C48962: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3B03C47E05: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3600.3)
The method ListMessages allows to specify a relative subfolder.
This subfolder needs to be added to the current path when registering
a new message interface.
Message interfaces are not necessarily created for the current folder,
therefore the folder needs to be specified in a parameter.
For example, messages can be created for sub folders when using the folder
parameter in ListMessages.
When registering a new driver with obex_service_driver_register there
could exist another driver for the service which will cause the drivers
list to leak.
The leak can be detected by using G_SLICE=always-malloc which will
produce the following trace using valgrind:
112 bytes in 7 blocks are definitely lost in loss record 123 of 167
at 0x4A06409: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x3B03C4D89E: g_malloc (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3B03C6344D: g_slice_alloc (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3B03C647A5: g_slist_append (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x424DD3: obex_service_driver_list (service.c:76)
by 0x42517F: obex_server_init (server.c:64)
by 0x40D439: main (main.c:304)
g_io_channel_unix_new creates a reference which is then passed to
obex_session_start which creates its on reference via g_io_channel_ref
leading to the following leak:
at 0x4A06409: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x3B03C4D89E: g_malloc (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3B03C88224: g_io_channel_unix_new (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x418967: profile_new_connection (bluetooth.c:148)
by 0x43D763: process_message.isra.5 (object.c:259)
This adds a pending_request struct in order to store the D-Bus request
data.
The current version stores the received D-Bus message in the MAP session
struct. The stored message is overridden by intermediate D-Bus method
calls which can lead into a crash.
Trace:
arguments to dbus_message_unref() were incorrect,
assertion "!message->in_cache" failed in file dbus-message.c line 1618.
0 0x00007ffff6a6a1c9 in raise () from /usr/lib/libc.so.6
1 0x00007ffff6a6b5c8 in abort () from /usr/lib/libc.so.6
2 0x00007ffff7313de5 in ?? () from /usr/lib/libdbus-1.so.3
3 0x00007ffff730ab91 in ?? () from /usr/lib/libdbus-1.so.3
4 0x000000000043721c in message_listing_cb (session=0x6a7d30,
transfer=0x6a9450, err=0x0, user_data=0x6a9950) at obexd/client/map.c:1166
5 0x000000000042f7af in session_terminate_transfer (session=0x6a7d30,
transfer=0x6a9450, gerr=0x0) at obexd/client/session.c:830
6 0x000000000042f83d in session_notify_complete (session=0x6a7d30,
transfer=0x6a9450) at obexd/client/session.c:845
7 0x000000000042f8dc in transfer_complete (transfer=0x6a9450, err=0x0,
user_data=0x6a7d30) at obexd/client/session.c:865
8 0x0000000000439ee7 in xfer_complete (obex=0x677250, err=0x0,
user_data=0x6a9450) at obexd/client/transfer.c:577
9 0x000000000043a05f in get_xfer_progress_first (obex=0x677250, err=0x0,
rsp=0x678730, user_data=0x6a9450) at obexd/client/transfer.c:621
10 0x0000000000413f08 in handle_response (obex=0x677250, err=0x0,
rsp=0x678730) at gobex/gobex.c:949
11 0x00000000004147db in incoming_data (io=0x6a8a00, cond=G_IO_IN,
user_data=0x677250) at gobex/gobex.c:1192
12 0x00007ffff702dda6 in g_main_context_dispatch ()
from /usr/lib/libglib-2.0.so.0
13 0x00007ffff702e0f8 in ?? () from /usr/lib/libglib-2.0.so.0
14 0x00007ffff702e4fa in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
15 0x0000000000427ce8 in main (argc=1, argv=0x7fffffffdd48)
at obexd/src/main.c:319