_Initial_ security audit result: ORBit




Hi,

Firstly note that this initial result corresponds to a quick glance at the
code. Investigation, as they say, is continuing.

To put this in context for the security-audit readers.

Why audit ORBit?
================

ORBit is the component that handles the network messages to GNOME applets.
And GNOME applets listen on TCP network sockets. Inclusion of GNOME into
mainstream distributions is expected _soon_, in some cases as the default
desktop. Insecurities in ORBit could lead to remote compromise - Bad News
(tm).
NOTE: The argument to disable listening on TCP sockets has been discussed.
The option is there but by default TCP sockets will be enabled,
apparently. Hopefully vendors will do the sensible thing and use the
option to disable (by default) but let's not awaken the debate agin.

I would like some more people to volunteer help look through the ORBit
code. Post here if interested.


Initial result
==============

I have identified a potentially very serious flaw in ORBit. Look at
src/IIOP/giop-message-buffer.c, function giop_recv_message_buffer_use().

The problem is a "classic" assignment of unsigned value to signed value.
The RPC code in glibc (and most other RPC implementations) suffered from
this.

Faulty line:

message_size = GIOP_MESSAGE_BUFFER(retval)->message_header.message_size;
^^^^^^
This is a signed int. The message_header variable is an unsigned int.
Hence we can end up with a -ve value which will pass the sanity check

        if(!connection->is_auth
           && message_size > 131072) {

Next we save the value, as long as a -ve size to g_malloc won't abort the
running process [untested]

retval->message_body = g_malloc(message_size);
retval->left_to_read = message_size;

into a variable which is also unsigned. We use this variable later thus:

      bptr += GIOP_MESSAGE_BUFFER(retval)->message_header.message_size;
      bptr -= retval->left_to_read;

[...]

    sysret = read(GIOP_CONNECTION_GET_FD(connection), bptr,
                  retval->left_to_read);

Oh dear! We just trashed memory off the end of bptr with arbitrary data
supplied over the network.

<speculation>

Interestingly, with signed/unsigned conversion issues we can write
anywhere between 1 byte and 2GB off the end of the buffer. On i386, linux,
the heap tends to be at 0x80000000, so add 2GB of virtual memory to that
and you get to play with the stack.


Final disclaimer: all of the above is theory _only_ so I could be wrong
and embarassing myself. Hopefully not!

Cheers
Chris



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]