Project

Profile

Help

HostedRedmine.com has moved to the Planio platform. All logins and passwords remained the same. All users will be able to login and use Redmine just as before. Read more...

Bug #859034

closed

Global-buffer-overflow while trying to disband unit (3.0.92-dev)

Added by Chippo Elder about 4 years ago. Updated about 4 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Client
Sprint/Milestone:
Start date:
Due date:
% Done:

0%

Estimated time:

Description

I was trying to disband an explorer. I got the 'Disband this 1 unit', clicked Yes and the dump happened.

==749870==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000000a3badc at pc 0x000000524dd8 bp 0x7ffd744e4d90 sp 0x7ffd744e4d88
READ of size 4 at 0x000000a3badc thread T0
    #0 0x524dd7 in do_disband_alternative /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/control.c:1847:19
    #1 0x5d514c in update_unqueue /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/update_queue.c:319:5
    #2 0x6b0a5d in mr_idle::idling() /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/gui-qt/mapview.cpp:175:5
    #3 0x6bbac6 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (mr_idle::*)()>::call(void (mr_idle::*)(), mr_idle*, void**) /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:152:13
    #4 0x6bb9e8 in void QtPrivate::FunctionPointer<void (mr_idle::*)()>::call<QtPrivate::List<>, void>(void (mr_idle::*)(), mr_idle*, void**) /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:185:13
    #5 0x6bb907 in QtPrivate::QSlotObject<void (mr_idle::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:414:17
    #6 0x7f97b39455c7 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2b15c7)
    #7 0x7f97b395266a in QTimer::timeout(QTimer::QPrivateSignal) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2be66a)
    #8 0x7f97b3945e54 in QObject::event(QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2b1e54)
    #9 0x7f97b3165a85 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x16aa85)
    #10 0x7f97b316edff in QApplication::notify(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x173dff)
    #11 0x7f97b3919a99 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x285a99)
    #12 0x7f97b39709ff in QTimerInfoList::activateTimers() (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2dc9ff)
    #13 0x7f97b39712db  (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2dd2db)
    #14 0x7f97b0d5e84c in g_main_context_dispatch (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5184c)
    #15 0x7f97b0d5eacf  (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51acf)
    #16 0x7f97b0d5eb72 in g_main_context_iteration (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51b72)
    #17 0x7f97b39716a4 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2dd6a4)
    #18 0x7f97b391863a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x28463a)
    #19 0x7f97b39203a5 in QCoreApplication::exec() (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x28c3a5)
    #20 0x66a7c0 in fc_client::fc_main(QApplication*) /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/gui-qt/fc_client.cpp:257:3
    #21 0x50e135 in qtg_ui_main(int, char**) /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/gui-qt/gui_main.cpp:179:17
    #22 0x50d9b9 in ui_main /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/gui_interface.c:59:3
    #23 0x512627 in client_main /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/client_main.c:685:3
    #24 0x50deba in main /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/gui-qt/gui_main.cpp:100:10
    #25 0x7f97b2b031e2 in __libc_start_main /build/glibc-4WA41p/glibc-2.30/csu/../csu/libc-start.c:308:16
    #26 0x463a5d in _start (/usr/local/bin/freeciv-qt-dev+0x463a5d)

0x000000a3badc is located 4 bytes to the left of global variable 'disband_unit_alternatives' defined in 'control.c:69:12' (0xa3bae0) of size 12
0x000000a3badc is located 35 bytes to the right of global variable '<string literal>' defined in 'control.c:356:3' (0xa3ba80) of size 57
  '<string literal>' is ascii string 'Unit %d started action selection before unit %d was done'
SUMMARY: AddressSanitizer: global-buffer-overflow /home/chippo/Downloads/git_clones/freeciv/freeciv-dev/client/control.c:1847:19 in do_disband_alternative
Shadow bytes around the buggy address:
  0x00008013f700: f9 f9 f9 f9 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9
  0x00008013f710: 00 00 00 00 04 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
  0x00008013f720: 00 00 00 00 00 04 f9 f9 f9 f9 f9 f9 00 00 07 f9
  0x00008013f730: f9 f9 f9 f9 06 f9 f9 f9 f9 f9 f9 f9 00 00 00 04
  0x00008013f740: f9 f9 f9 f9 00 00 00 00 00 00 00 01 f9 f9 f9 f9
=>0x00008013f750: 00 00 00 00 00 00 00 01 f9 f9 f9[f9]00 04 f9 f9
  0x00008013f760: f9 f9 f9 f9 00 00 07 f9 f9 f9 f9 f9 00 00 00 02
  0x00008013f770: f9 f9 f9 f9 00 00 00 01 f9 f9 f9 f9 00 00 00 00
  0x00008013f780: 00 04 f9 f9 f9 f9 f9 f9 00 04 f9 f9 f9 f9 f9 f9
  0x00008013f790: 00 00 05 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
  0x00008013f7a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==749870==ABORTING
AddressSanitizer:DEADLYSIGNAL
Aborted (core dumped)
Core was generated by `freeciv-qt-dev'.
Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50    ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
[Current thread is 1 (Thread 0x7f97af493080 (LWP 749870))]
(gdb) bt full
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
        set = 
            {__val = {0, 281470681751461, 140726554738272, 140726554738272, 140726554738272, 5197072, 206158430216, 140726554738912, 140726554738720, 5108075, 140726554738336, 14204840, 140726554742160, 140726554742152, 140726554742064, 14803976}}
        pid = <optimized out>
        tid = <optimized out>
#1  0x00007f97b2b01899 in __GI_abort () at abort.c:79
        save_stage = 1
        act = 
          {__sigaction_handler = {sa_handler = 0x7f97b68ea900, sa_sigaction = 0x7f97b68ea900}, sa_mask = {__val = {2, 2, 8, 32, 4628179, 14127432, 0, 0, 10730204, 2, 0, 0, 0, 0, 0, 0}}, sa_flags = 0, sa_restorer = 0xd8bfa8 <__asan::error_message_buf_mutex>}
        sigs = {__val = {32, 0 <repeats 15 times>}}
#2  0x00000000004f9417 in  ()
#3  0x00000000004f7df1 in  ()
#4  0x00000000004df979 in  ()
#5  0x00000000004e10ef in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) ()
#6  0x00000000004e1908 in __asan_report_load4 ()
#7  0x0000000000524dd8 in do_disband_alternative (p=0x602000197e90) at control.c:1847
        data = 0x602000197e90
        punit = <optimized out>
        next = <optimized out>
        act = <optimized out>
        last_request_id_used = <optimized out>
        pcity = <optimized out>
        ptile = <optimized out>
#8  0x00000000005d514d in update_unqueue (data=<optimized out>) at update_queue.c:319
        callback = 0x524830 <do_disband_alternative>
        uq_data = 0x0
        __vla_expr0 = <optimized out>
        MY_mem_MY_iter = <optimized out>
        MY_it_MY_iter = 0x7ffd744e4e00
        MY_iter = 0x7ffd744e4e00
        hash = 0x607000686690
#9  0x00000000006b0a5e in mr_idle::idling() (this=<optimized out>) at mapview.cpp:175
--Type <RET> for more, q to quit, c to continue without paging--c
        cb = 0x6020003e4dd0
#10 0x00000000006bbac7 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (mr_idle::*)()>::call(void (mr_idle::*)(), mr_idle*, void**) (f=<optimized out>, o=<optimized out>, arg=<optimized out>) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:152
#11 0x00000000006bb9e9 in QtPrivate::FunctionPointer<void (mr_idle::*)()>::call<QtPrivate::List<>, void>(void (mr_idle::*)(), mr_idle*, void**) (f=(void (mr_idle::*)(class mr_idle * const)) 0x2, this adjustment 140726554738128, o=0x0, arg=0x7f97b2b223eb <__GI_raise+203>) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:185
#12 0x00000000006bb908 in QtPrivate::QSlotObject<void (mr_idle::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (which=<optimized out>, this_=0x603000005380, r=0x0, a=0x7f97b2b223eb <__GI_raise+203>, ret=0x0) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:414
#13 0x00007f97b39455c8 in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#14 0x00007f97b395266b in QTimer::timeout(QTimer::QPrivateSignal) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#15 0x00007f97b3945e55 in QObject::event(QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#16 0x00007f97b3165a86 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#17 0x00007f97b316ee00 in QApplication::notify(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#18 0x00007f97b3919a9a in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#19 0x00007f97b3970a00 in QTimerInfoList::activateTimers() () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#20 0x00007f97b39712dc in  () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#21 0x00007f97b0d5e84d in g_main_context_dispatch () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#22 0x00007f97b0d5ead0 in  () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#23 0x00007f97b0d5eb73 in g_main_context_iteration () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#24 0x00007f97b39716a5 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#25 0x00007f97b391863b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#26 0x00007f97b39203a6 in QCoreApplication::exec() () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#27 0x000000000066a7c1 in fc_client::fc_main(QApplication*) (this=<optimized out>, qapp=<optimized out>) at fc_client.cpp:257
#28 0x000000000050e136 in qtg_ui_main(int, char**) (argc=<optimized out>, argv=<optimized out>) at gui_main.cpp:179
        app_icon = <optimized out>
        qpm = <optimized out>
#29 0x000000000050d9ba in ui_main (argc=2, argv=0x7ffd744e3dd0) at gui_interface.c:59
#30 0x0000000000512628 in client_main (argc=1, argv=<optimized out>) at client_main.c:685
        loglevel = <optimized out>
        fatal_assertions = <optimized out>
        option = <optimized out>
        ui_separator = <optimized out>
        ui_options = 0
        i = <optimized out>
        aii = <optimized out>
#31 0x000000000050debb in main(int, char**) (argc=2, argv=0x7ffd744e3dd0) at gui_main.cpp:100

I can't reproduce it from the savegame (3.0.92-dev (modified 5fa96c064c)) but I've attached it anyway. I was trying to disband the Explorer from Chennai, in Chennai [l tgt="city" id=195 name="Chennai" /].

I was running the client and the server separately and only the client crashed. When I reconnected to the running server with both gtk and qt clients, the Explorer was disbanded and everything seemed fine.


Files

freeciv-T0112-Y00220-auto.sav.xz (138 KB) freeciv-T0112-Y00220-auto.sav.xz Chippo Elder, 2020-02-07 07:00 AM
m-859034-untested.patch (730 Bytes) m-859034-untested.patch master, experimental, untested Jacob Nevins, 2020-02-08 02:18 PM

Related issues

Has duplicate Freeciv - Bug #862483: global-buffer-overflow while disbanding unit (S3_0)Closed

Actions
Actions #1

Updated by Jacob Nevins about 4 years ago

  • Sprint/Milestone set to 3.0.0

Backtrace contains do_disband_alternative() => assume this affects 3.0 at the earliest.

Actions #2

Updated by Jacob Nevins about 4 years ago

Assuming my line numbers match up with the backtrace (haven't checked), I think the line number of the "buffer-overflow" is /* FAULT */:

static void do_disband_alternative(void *p)
{
  /* ... */
  const int act = disband_unit_alternatives[data->alt];   /* FAULT */
  /* ... */
  if (data->alt == -1) {
    /* All alternatives have been tried. */
    /* ... give up ... */
  }
  /* ... */
}

From inspection, I don't see any reason why this won't try to access disband_unit_alternatives[-1], which sounds like it could cause a "global-buffer-overflow".

I think this will occur whenever ACTION_HELP_WONDER and ACTION_RECYCLE_UNIT aren't valid ways to get rid of a unit but ACTION_DISBAND_UNIT is (which IIRC will usually be the case if you disband a unit outside a city). (Because we do this access before even checking if the previous action got rid of the unit.)

Untested patch for master attached.

Actions #3

Updated by Chippo Elder about 4 years ago

I applies cleanly, it compiles and the executable runs (fine, I think), but since I only saw the original problem once in my life...

Actions #4

Updated by Jacob Nevins about 4 years ago

  • Related to Bug #862483: global-buffer-overflow while disbanding unit (S3_0) added
Actions #5

Updated by Chippo Elder about 4 years ago

The patch fixes a repeatable example in S3_0 (see #862483), so should probably be committed to master.

Actions #6

Updated by Jacob Nevins about 4 years ago

  • Category set to Client
  • Status changed from New to Resolved
  • Assignee set to Jacob Nevins

Since Chippo Elder has confirmed the patch to be useful in #862483, and it still applies to master and S3_0, it's now a commit candidate.

Actions #7

Updated by Jacob Nevins about 4 years ago

  • Related to deleted (Bug #862483: global-buffer-overflow while disbanding unit (S3_0))
Actions #8

Updated by Jacob Nevins about 4 years ago

  • Has duplicate Bug #862483: global-buffer-overflow while disbanding unit (S3_0) added
Actions #9

Updated by Jacob Nevins about 4 years ago

  • Subject changed from Global-buffer-overflow while trying to disband unit (3.0.92-dev, qt) to Global-buffer-overflow while trying to disband unit (3.0.92-dev)
Actions #10

Updated by Jacob Nevins about 4 years ago

  • Status changed from Resolved to Closed

Also available in: Atom PDF