Bug 804792 - sha512-crypt.c usage of alloca() unbounded
Summary: sha512-crypt.c usage of alloca() unbounded
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: glibc
Version: 16
Hardware: x86_64
OS: Linux
unspecified
high
Target Milestone: ---
Assignee: Jeff Law
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2012-03-19 19:32 UTC by Russell Bryant
Modified: 2016-11-24 15:39 UTC (History)
6 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2012-03-29 18:50:36 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Russell Bryant 2012-03-19 19:32:43 UTC
Description of problem:

We received a report of a remotely exploitable crash vulnerability in OpenStack (http://www.openstack.org).  The root cause turned out to be in glibc, when a password of excessive length made it down to sha512 crypt and resulted in an unbounded alloca() that exhausted the stack.

Here is an abbreviated demonstration of the bug in Python as it occurred in OpenStack (with python-passlib installed):

    import passlib.hash

    pw_utf8 = ('a' * 9999999).encode('utf-8')
    pw_hash = passlib.hash.sha512_crypt.encrypt(pw_utf8)
    passlib.hash.sha512_crypt.verify(pw_utf8, pw_hash)

It can also be reproduced using the crypt Python module directly:

    import crypt

    pw_utf8 = ('a' * 9999999).encode('utf-8')
    crypt.crypt(pw_utf8, '$6$' + '.'*16)

Both of these examples will result in a seg fault that resembles the following:

Program received signal SIGSEGV, Segmentation fault.
__sha512_crypt_r (key=0x7fffeb1db034 'a' <repeats 200 times>...,
salt=0x7f9bec "dWs9ZDUtzP4oF/03$",
   buffer=0x7a8a40
"$6$rounds=1000$test$2M/Lx6MtobqjLjobw0Wmo4Q5OFx5nVLJvmgseatA6oMnyWeBdRDx4DU.1H3eGmse6pgsOgDisWBGI5c7TZauS0")
at sha512-crypt.c:153
153           key = copied_key =

(gdb) list
148       key_len = strlen (key);
149
150       if ((key - (char *) 0) % __alignof__ (uint64_t) != 0)
151         {
152           char *tmp = (char *) alloca (key_len + __alignof__ (uint64_t));
153           key = copied_key =
154             memcpy (tmp + __alignof__ (uint64_t)
155                     - (tmp - (char *) 0) % __alignof__ (uint64_t),
156                     key, key_len);
157           assert ((key - (char *) 0) % __alignof__ (uint64_t) == 0);


Version-Release number of selected component (if applicable):

glibc-2.14.90-24.fc16.6.x86_64

Comment 2 Russell Bryant 2012-03-19 20:25:44 UTC
Thanks for the archive link.  I meant to post that ... pbrady pointed that out to me before I posted this.  It wasn't clear if the issue was ever reported anywhere and the code appears to still be the same, so I figure it should be reported.

Also, the original reporter of this issue to OpenStack was Dan Prince (dprince).

Comment 3 Jan Lieskovsky 2012-03-20 13:23:43 UTC
Though we understand the potential negative implications, this deficiency might have on packages / code using glibc's sha512-crypt module's routines, we would not classify this bug to be a security issue in glibc.

Explanation:
The currently seen behaviour is expected in the sense of the way how alloca() system call is intended to be used (to allocate space in the stack frame of the caller and automatically free the allocated space when the function from which alloca() was called returned). When the size of memory to be allocated in this temporary space would not fit into the stack frame of the caller (IOW by attempt to write at memory location past the stack frame of the caller), it is expected the application to be terminated. The only consequence of this behaviour (when very long password strings are used) is the termination (crash) of the application.

Comment 4 Jeff Law 2012-03-23 20:53:28 UTC
But isn't blowing out the stack subject to the kind of attacks seen in CVE-2012-0864 where passing a "clever" value to alloca causes the stack pointer to point into the heap and the potentially opening up all kinds of interesting attack vectors.

Comment 5 Jeff Law 2012-03-29 18:50:36 UTC
Fixed in rawhide, f17 & rhel 7 trees.  Not currently planning to backport to f15, f16, rhel5 or rhel6.

Comment 6 Tomas Hoger 2012-03-30 10:19:39 UTC
OpenStack Keystone was changed to limit the length of the passwords it processes - see bug #805551.

glibc upstream list on the Jeff's patch to make crypt implementation use malloc instead of alloca for long inputs:

http://sourceware.org/ml/libc-alpha/2012-03/msg01138.html
http://sourceware.org/ml/libc-alpha/2012-03/msg01158.html


Note You need to log in before you can comment on or make changes to this bug.