Bug 804792 - sha512-crypt.c usage of alloca() unbounded
sha512-crypt.c usage of alloca() unbounded
Status: CLOSED RAWHIDE
Product: Fedora
Classification: Fedora
Component: glibc (Show other bugs)
16
x86_64 Linux
unspecified Severity high
: ---
: ---
Assigned To: Jeff Law
Fedora Extras Quality Assurance
: Security
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2012-03-19 15:32 EDT by Russell Bryant
Modified: 2016-11-24 10:39 EST (History)
6 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2012-03-29 14:50:36 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Russell Bryant 2012-03-19 15:32:43 EDT
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 16:25:44 EDT
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@redhat.com).
Comment 3 Jan Lieskovsky 2012-03-20 09:23:43 EDT
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 16:53:28 EDT
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 14:50:36 EDT
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 06:19:39 EDT
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.