Commit Graph

39 Commits

Author SHA1 Message Date
Martin Hundebøll d5bfc2ab41 gatmux: disable destroy notification on read watcher
With the reference in place in received_data(), the address sanitizer
now encounters a use-after-free when the destroy notification is
dispatched for the read watcher (see below).

Fix this by remove the destroy notification callback, as it isn't really
used except in the shutdown function.

==5797==ERROR: AddressSanitizer: heap-use-after-free on address 0x621000ac5904 at pc 0x55c1243b1f14 bp 0x7ffdef001340 sp 0x7ffdef001330
WRITE of size 4 at 0x621000ac5904 thread T0
    #0 0x55c1243b1f13 in read_watcher_destroy_notify ../git/gatchat/gatmux.c:660
    #1 0x7f08a8676742  (/usr/lib/libglib-2.0.so.0+0x62742)
    #2 0x7f08a867e2e4 in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x6a2e4)
    #3 0x7f08a8680210  (/usr/lib/libglib-2.0.so.0+0x6c210)
    #4 0x7f08a8681122 in g_main_loop_run (/usr/lib/libglib-2.0.so.0+0x6d122)
    #5 0x55c1243d6703 in main ../git/src/main.c:286
    #6 0x7f08a8423152 in __libc_start_main (/usr/lib/libc.so.6+0x27152)
    #7 0x55c1241fe1ad in _start (/home/martin/projects/ofono/x86/src/ofonod+0xfd1ad)

0x621000ac5904 is located 4 bytes inside of 4672-byte region [0x621000ac5900,0x621000ac6b40)
freed by thread T0 here:
    #0 0x7f08a88cc6b0 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:122
    #1 0x55c1243b1ebf in g_at_mux_unref ../git/gatchat/gatmux.c:652
    #2 0x55c1243b062c in received_data ../git/gatchat/gatmux.c:276
    #3 0x7f08a867e2ce in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x6a2ce)

previously allocated by thread T0 here:
    #0 0x7f08a88cccd8 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:153
    #1 0x55c1243b1bf1 in g_at_mux_new ../git/gatchat/gatmux.c:613
    #2 0x55c1243b4b53 in g_at_mux_new_gsm0710_basic ../git/gatchat/gatmux.c:1172
    #3 0x55c124386abd in cmux_gatmux ../git/plugins/quectel.c:871
    #4 0x55c12438779f in cmux_cb ../git/plugins/quectel.c:1023
    #5 0x55c1243a368e in at_chat_finish_command ../git/gatchat/gatchat.c:459
    #6 0x55c1243a3bc8 in at_chat_handle_command_response ../git/gatchat/gatchat.c:521
    #7 0x55c1243a4408 in have_line ../git/gatchat/gatchat.c:600
    #8 0x55c1243a539e in new_bytes ../git/gatchat/gatchat.c:759
    #9 0x55c1243ae2f9 in received_data ../git/gatchat/gatio.c:122
    #10 0x7f08a867e2ce in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x6a2ce)

SUMMARY: AddressSanitizer: heap-use-after-free ../git/gatchat/gatmux.c:660 in read_watcher_destroy_notify
Shadow bytes around the buggy address:
  0x0c4280150ad0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4280150ae0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4280150af0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4280150b00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4280150b10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c4280150b20:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4280150b30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4280150b40: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4280150b50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4280150b60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4280150b70: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==5797==ABORTING
2019-10-08 14:49:22 -05:00
Martin Hundebøll 1b4ee8dbb8 gatmux: take reference to mux object while processing incoming data
When closing down a cmux object, the address sanitizer detects a
use-after-free in gatmux.c (see below).

Avoid this by taking a reference to the mux object during the processing
in received_data().

ofonod[3640549]: ../git/plugins/quectel.c:cfun_disable() 0x610000000b40
ofonod[3640549]: ../git/plugins/quectel.c:close_serial() 0x610000000b40
ofonod[3640549]: ../git/plugins/quectel.c:close_mux() 0x610000000b40
ofonod[3640549]: ../git/examples/emulator.c:powered_watch() Removing modem 0x610000000b40 from the list
ofonod[3640549]: ../git/examples/emulator.c:powered_watch() Removing server watch: 106
ofonod[3640549]: ../git/src/modem.c:modem_change_state() old state: 0, new state: 0

=================================================================
==3640549==ERROR: AddressSanitizer: heap-use-after-free on address 0x62100073dd28 at pc 0x5566b6402a21 bp 0x7ffe7a2db0e0 sp 0x7ffe7a2db0d0
READ of size 8 at 0x62100073dd28 thread T0
    #0 0x5566b6402a20 in debug ../git/gatchat/gatmux.c:109
    #1 0x5566b6404bd7 in channel_close ../git/gatchat/gatmux.c:525
    #2 0x7fa0516e44a6 in g_io_channel_shutdown (/usr/lib/libglib-2.0.so.0+0x774a6)
    #3 0x7fa0516e4644 in g_io_channel_unref (/usr/lib/libglib-2.0.so.0+0x77644)
    #4 0x5566b64048a4 in watch_finalize ../git/gatchat/gatmux.c:474
    #5 0x7fa0516d6f6f  (/usr/lib/libglib-2.0.so.0+0x69f6f)
    #6 0x7fa0516ac6a7 in g_slist_foreach (/usr/lib/libglib-2.0.so.0+0x3f6a7)
    #7 0x7fa0516b277b in g_slist_free_full (/usr/lib/libglib-2.0.so.0+0x4577b)
    #8 0x5566b6403413 in dispatch_sources ../git/gatchat/gatmux.c:224
    #9 0x5566b64039ea in received_data ../git/gatchat/gatmux.c:268
    #10 0x7fa0516d727e in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x6a27e)
    #11 0x7fa0516d91c0  (/usr/lib/libglib-2.0.so.0+0x6c1c0)
    #12 0x7fa0516da0d2 in g_main_loop_run (/usr/lib/libglib-2.0.so.0+0x6d0d2)
    #13 0x5566b6429b1b in main ../git/src/main.c:286
    #14 0x7fa05147fee2 in __libc_start_main (/usr/lib/libc.so.6+0x26ee2)
    #15 0x5566b62531ad in _start (/home/martin/projects/ofono/x86/src/ofonod+0xfc1ad)

0x62100073dd28 is located 40 bytes inside of 4672-byte region [0x62100073dd00,0x62100073ef40)
freed by thread T0 here:
    #0 0x7fa0519256c0 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:122
    #1 0x5566b64052d7 in g_at_mux_unref ../git/gatchat/gatmux.c:645
    #2 0x5566b63d6d19 in close_mux ../git/plugins/quectel.c:199
    #3 0x5566b63d7047 in close_serial ../git/plugins/quectel.c:223
    #4 0x5566b63db62a in cfun_disable ../git/plugins/quectel.c:1056
    #5 0x5566b63f6ae1 in at_chat_finish_command ../git/gatchat/gatchat.c:459
    #6 0x5566b63f701b in at_chat_handle_command_response ../git/gatchat/gatchat.c:521
    #7 0x5566b63f785b in have_line ../git/gatchat/gatchat.c:600
    #8 0x5566b63f87f1 in new_bytes ../git/gatchat/gatchat.c:759
    #9 0x5566b640174c in received_data ../git/gatchat/gatio.c:122
    #10 0x5566b64047b4 in watch_dispatch ../git/gatchat/gatmux.c:464
    #11 0x5566b640313b in dispatch_sources ../git/gatchat/gatmux.c:183
    #12 0x5566b64039ea in received_data ../git/gatchat/gatmux.c:268
    #13 0x7fa0516d727e in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x6a27e)

previously allocated by thread T0 here:
    #0 0x7fa051925ce8 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:153
    #1 0x5566b6405009 in g_at_mux_new ../git/gatchat/gatmux.c:606
    #2 0x5566b6407f6b in g_at_mux_new_gsm0710_basic ../git/gatchat/gatmux.c:1165
    #3 0x5566b63da9ba in cmux_cb ../git/plugins/quectel.c:882
    #4 0x5566b63f6ae1 in at_chat_finish_command ../git/gatchat/gatchat.c:459
    #5 0x5566b63f701b in at_chat_handle_command_response ../git/gatchat/gatchat.c:521
    #6 0x5566b63f785b in have_line ../git/gatchat/gatchat.c:600
    #7 0x5566b63f87f1 in new_bytes ../git/gatchat/gatchat.c:759
    #8 0x5566b640174c in received_data ../git/gatchat/gatio.c:122
    #9 0x7fa0516d727e in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x6a27e)

SUMMARY: AddressSanitizer: heap-use-after-free ../git/gatchat/gatmux.c:109 in debug
Shadow bytes around the buggy address:
  0x0c42800dfb50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c42800dfb60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c42800dfb70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c42800dfb80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c42800dfb90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c42800dfba0: fd fd fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd
  0x0c42800dfbb0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c42800dfbc0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c42800dfbd0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c42800dfbe0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c42800dfbf0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==3640549==ABORTING
2019-10-08 14:45:42 -05:00
Denis Kenzior 713655a1ae gatchat: Remove unneeded if 2019-04-29 14:29:21 -05:00
Marcel Holtmann 4cd1608320 gatchat: Use pragma to mask unknown pragma diagnostic options
gatchat/gatmux.c:33:32: error: unknown option after ‘#pragma GCC diagnostic’ kind [-Werror=pragmas]
 #pragma GCC diagnostic ignored "-Wcast-function-type"
                                ^~~~~~~~~~~~~~~~~~~~~~
2018-06-14 21:47:41 +02:00
Marcel Holtmann 07fc4a8506 gatchat: Use pragma to mask GFunc casting warning
gatchat/gatmux.c: In function ‘watch_dispatch’:
gatchat/gatmux.c:454:17: error: cast between incompatible function types from ‘GSourceFunc’ {aka ‘int (*)(void *)’} to ‘gboolean (*)(GIOChannel *, GIOCondition,  void *)’ {aka ‘int (*)(struct _GIOChannel *, enum <anonymous>,  void *)’} [-Werror=cast-function-type]
  GIOFunc func = (GIOFunc) callback;
                 ^
2018-06-14 15:19:16 +02:00
Slava Monich bf5f4242a2 gatmux: Remove write watch source at shutdown
Otherwise write_watcher_destroy_notify can be invoked after
GAtMux has been deallocated which results in write after free:

==3952== Invalid write of size 4
==3952==    at 0xABF54: write_watcher_destroy_notify (gatmux.c:285)
==3952==    by 0x4AF21E7: g_source_callback_unref (gmain.c:1561)
==3952==    by 0x4AF2E53: g_source_destroy_internal.constprop.8 (gmain.c:1207)
==3952==    by 0x4AF61CF: g_main_dispatch (gmain.c:3177)
==3952==    by 0x4AF61CF: g_main_context_dispatch (gmain.c:3769)
==3952==    by 0x4AF658F: g_main_loop_run (gmain.c:4034)
==3952==    by 0xBDDBB: main (main.c:261)
==3952==  Address 0x50c6cb0 is 8 bytes inside a block of size 4,396 free'd
==3952==    at 0x4840B28: free (vg_replace_malloc.c:530)
==3952==    by 0xACB53: g_at_mux_unref (gatmux.c:642)
==3952==  Block was alloc'd at
==3952==    at 0x4841BF0: calloc (vg_replace_malloc.c:711)
==3952==    by 0xAC9DF: g_at_mux_new (gatmux.c:603)
==3952==    by 0xADF2F: g_at_mux_new_gsm0710_basic (gatmux.c:1160)
2017-10-23 17:22:56 -05:00
Slava Monich bb637a12c5 gatmux: Remove finalized watches from the list
Leaving them there may result in invalid reads like this:

==2312== Invalid read of size 4
==2312==    at 0xAB8C0: dispatch_sources (gatmux.c:134)
==2312==    by 0xAC5D3: channel_close (gatmux.c:479)
==2312==    by 0x4AE8885: g_io_channel_shutdown (giochannel.c:523)
==2312==    by 0x4AE8A1D: g_io_channel_unref (giochannel.c:240)
==2312==    by 0xAC423: watch_finalize (gatmux.c:426)
==2312==    by 0x4AF2CC9: g_source_unref_internal (gmain.c:2048)
==2312==    by 0x4AF44E1: g_source_destroy_internal (gmain.c:1230)
==2312==    by 0x4AF44E1: g_source_destroy (gmain.c:1256)
==2312==    by 0x4AF5257: g_source_remove (gmain.c:2282)
==2312==    by 0xAB5CB: io_shutdown (gatio.c:325)
==2312==    by 0xAB667: g_at_io_unref (gatio.c:345)
==2312==    by 0xA72C7: at_chat_unref (gatchat.c:972)
==2312==    by 0xA829B: g_at_chat_unref (gatchat.c:1446)
==2312==  Address 0x51420f0 is 56 bytes inside a block of size 60 free'd
==2312==    at 0x4840B28: free (vg_replace_malloc.c:530)
==2312==    by 0x4AF2D33: g_source_unref_internal (gmain.c:2075)
==2312==    by 0x4AF44E1: g_source_destroy_internal (gmain.c:1230)
==2312==    by 0x4AF44E1: g_source_destroy (gmain.c:1256)
==2312==    by 0x4AF5257: g_source_remove (gmain.c:2282)
==2312==    by 0xAB46B: g_at_io_set_write_handler (gatio.c:283)
==2312==    by 0xA713F: at_chat_suspend (gatchat.c:938)
==2312==    by 0xA72B7: at_chat_unref (gatchat.c:971)
==2312==    by 0xA829B: g_at_chat_unref (gatchat.c:1446)
==2312==  Block was alloc'd at
==2312==    at 0x4841BF0: calloc (vg_replace_malloc.c:711)
==2312==    by 0x4AFB117: g_malloc0 (gmem.c:124)
==2312==    by 0x4AF401F: g_source_new (gmain.c:892)
==2312==    by 0xAC6A7: channel_create_watch (gatmux.c:506)
==2312==    by 0x4AE7C4F: g_io_add_watch_full (giochannel.c:649)
==2312==    by 0xAB4EB: g_at_io_set_write_handler (gatio.c:297)
==2312==    by 0xA7103: chat_wakeup_writer (gatchat.c:931)
==2312==    by 0xA753F: at_chat_send_common (gatchat.c:1045)
==2312==    by 0xA850F: g_at_chat_send (gatchat.c:1502)

It's also necessary to add additional references to the sources
for the duration of the dispatch_sources loop because any source
can be removed when any callback is invoked (and not necessarily
the one being dispatched).
2017-10-23 15:25:20 -05:00
Denis Kenzior a8d4e7960f gatchat: Fix style 2016-10-05 13:02:52 -05:00
Antoine Aubert da47398525 gatmux: fix read channel remove on error
In case of invalid IO, read_watch is not reset. This fix crash on
destroy gatmux.
2016-10-05 13:02:41 -05:00
Marcel Holtmann 17828ce9c9 gatchat: Avoid shadowing variables 2012-07-15 20:14:12 -03:00
Marcel Holtmann 21f9da9916 gatchat: Update copyright information 2011-10-10 13:39:25 -07:00
Denis Kenzior 2b9a14dd0c gatmux: Remove unused error variable 2011-02-08 16:48:52 -06:00
Marcel Holtmann 2126700c3e gatchat: Fix setup of GIOChannel from multiplexer DLC 2011-01-19 12:10:10 +01:00
Lucas De Marchi 521071a785 gatchat: explicitly compare pointers to NULL
This patch was generated by the following semantic patch
(http://coccinelle.lip6.fr/)

// <smpl>
@fix disable is_null,isnt_null1@
expression *E;
@@

- !E
+ E == NULL
// </smpl>
2010-11-29 12:05:29 -06:00
Marcel Holtmann 0caafef6c9 gatchat: Add support for skipping AT+CMUX speed parameter 2010-10-19 18:50:52 +02:00
Marcel Holtmann 3dbfa4a7b4 gatchat: Hook up g_at_mux_set_debug to print debug messages for real 2010-09-26 17:25:27 +09:00
Denis Kenzior 8645b05c4f gatmux: Unref the chat instead of using shutdown 2010-04-28 17:27:34 -05:00
Denis Kenzior 15d93ad0b9 Fix: GAtMux channels should return EAGAIN
GAtChat uses non-blocking semantics, so the GAtMux channels should
return the EAGAIN status to make GAtChat work properly.
2010-04-14 10:39:47 -05:00
Marcel Holtmann a977ecf260 Remove various GDestroyNotify function casting 2010-04-12 17:48:20 -07:00
Marcel Holtmann 2dab6bc3a6 The user data pointer variable should be called user_data 2010-04-11 17:42:40 +02:00
Marcel Holtmann 764501482e Fix some cases where g_try_new should be used 2010-04-02 19:20:53 -07:00
Denis Kenzior 8d8f5d90a0 Fix: Dead Assignment 2010-02-04 00:00:00 -06:00
Marcel Holtmann 144080e749 Update copyright information 2010-01-01 17:00:10 -08:00
Denis Kenzior 43e5152934 Fix: Do not leak chat references in case of error 2009-10-15 16:15:17 -05:00
Denis Kenzior 20dc22a6c4 Fix: Cleanup debug formats 2009-10-15 16:15:17 -05:00
Denis Kenzior d4d1617684 Fix: Do not send shutdown more than once 2009-10-15 16:15:17 -05:00
Denis Kenzior a8af38d209 Fix: Be more paranoid in checking DLC validity 2009-10-15 16:15:17 -05:00
Denis Kenzior 112d07e14e Refactor: Add driver model to GAtMux
GAtMux can now be made to work with multiple multiplexing protocols.
Currently on the 27.010 (07.10) Advanced and Basic modes are supported.
However, further protocol support can be added by providing the
necessary driver functions for GAtMux
2009-10-15 16:15:17 -05:00
Denis Kenzior 6bfd76123b Forgot to add driverdata functions 2009-10-15 16:15:17 -05:00
Denis Kenzior a4a54f6625 Refactor: Enable multiplexer drivers for GAtMux 2009-10-15 16:15:17 -05:00
Denis Kenzior 1575f2dcd1 Fix: Notify sources upon shutdown 2009-10-15 16:15:16 -05:00
Denis Kenzior 5826fc9c15 Add ability to open/close multiple DLCs 2009-10-15 16:15:16 -05:00
Denis Kenzior 4734ebcb46 Refactor: Add convenience method to start 0710 MUX
Use an existing GAtChat that has been setup appropriately to conver the
channel into a MUX
2009-10-15 16:15:16 -05:00
Denis Kenzior 556186eb35 Remove more unused code 2009-10-15 16:15:16 -05:00
Denis Kenzior f9db94cd73 Cleanup: Remove more dead code 2009-10-08 12:53:25 -05:00
Denis Kenzior 273c8b06a0 Get rid of from_tty variant, use gattty instead 2009-10-08 12:53:25 -05:00
Marcel Holtmann 47b1d09b6e Hook up GAtMux with GSM 07.10 implementation 2009-09-08 09:04:11 +02:00
Marcel Holtmann 094fdd4e71 Add functions for disconnect and debug handling 2009-09-06 00:31:26 +02:00
Marcel Holtmann c9ba0e7df5 Integrate the multiplexer into the AT chat library 2009-09-06 00:25:16 +02:00