URL:
  <http://gna.org/bugs/?19241>

                 Summary: Server crash when game ends with >100 players
                 Project: Freeciv
            Submitted by: None
            Submitted on: Tue 03 Jan 2012 08:58:28 PM UTC
                Category: general
                Severity: 3 - Normal
                Priority: 5 - Normal
                  Status: None
             Assigned to: None
        Originator Email: j...@freeciv.mail.kapsi.fi
             Open/Closed: Open
                 Release: 2.3.1
         Discussion Lock: Any
        Operating System: GNU/Linux
         Planned Release: 

    _______________________________________________________

Details:

The endgame packet in our 126 player game (http://game.freeciv.fi/) exceeds
the maximum packet size.

>From server log:

3: in send_packet_endgame_report_100() [packets_gen.c::2764]:
packet_endgame_report_100: sending info about ()
3: in send_packet_data() [packets.c::190]: sending packet
type=PACKET_ENDGAME_REPORT(12) len=5654 to doctor

compare with the source code:

connection.h:#define MAX_LEN_PACKET   4096
packets.h:  unsigned char buffer[MAX_LEN_PACKET];

This causes the server to crash with stacktrace:

*** stack smashing detected ***: freeciv-server terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x37)[0x7fe68bfe31d7]
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x0)[0x7fe68bfe31a0]
freeciv-server[0x4ef39a]
======= Memory map: ========
...

The address in question points to the GCC stack check at the end of function
send_packet_endgame_report_100().

My interpretation is that the endgame packet grows too large when there are
many players. The send_packet_endgame_report_100() then somehow manages to
overwrite the buffer and result in a length that is larger than
MAX_LEN_PACKET.

The dataio.c has buffer length checks that should prevent the crash and
simply result in truncated packet. However, there is another bug on line 116:

if (ADD_TO_POINTER(dout->current, size) >= ADD_TO_POINTER(dout->dest,
dout->dest_size))

The buffer length check is comparing the number of bytes in buffer
(dout->current is size_t) to the pointer to the end of the buffer (dout->dest
is void*), which is always larger.




    _______________________________________________________

Reply to this item at:

  <http://gna.org/bugs/?19241>

_______________________________________________
  Message sent via/by Gna!
  http://gna.org/


_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to