xorl %eax, %eax

CVE-2009-0757: GNU MPFR Off-by-One Overflows

leave a comment »

First of all I have to apologize for not posting anything and even right now I’m posting something extremely simple and definitely not interesting. The reason for this is that I don’t have internet connection at home (nor did my neighbors had any wifi last time I checked – yesterday). I spend some time at work moderating comments, reading emails and stuff. But I don’t have enough time to write new posts. Sorry for that. I just hope I’ll get back by connection soon.

Now, regarding this bug. MPFR is a C library for multiple-precision floating-point calculations. It is installed on various Linux distributions and it is available as a precompiled package for most the popular ones. CVE-2009-0757 includes two buffer overflow vulnerabilities. This was finally patched on 25 February 2009. The following code is taken from MPFR 2.4.0 release.

151  mpfr_snprintf (char *buf, size_t size, const char *fmt, ...)
152  {
153    char *str;
154    int ret;
155    size_t min_size;
156
157    /* C99 allows SIZE to be null */
158    if (size == 0)
159      return 0;
160
161    MPFR_ASSERTD (buf != NULL);
162
163    GET_STR (ret, str, fmt);
164    min_size = (size_t)ret < size ? (size_t)ret : size - 1;
165    strncpy (buf, str, min_size);
166    buf[min_size + 1] = '\0';
167
168    mpfr_free_str (str);
169    return ret;
170  }

This function can be found under printf.c. This source code file contains printf family functions implementations used internally on the MPFR project. The mistake of the above code is that strncpy() at line 165 NULL terminates buf by adding a NULL byte when min_size leaves enough space. To avoid the information leakage of the other cases where min_size is the exact size of buf, the author added the following code at line 166. Unfortunately, this introduces an off-by-one since min_size is the exact buffer size and adding a NULL byte after min_size passes the boundaries of buf. The fix was simple:

-    buf[min_size + 1] = '\0';
+    buf[min_size] = '';

The exact same vulnerability was also at another function:

172  int
173  mpfr_vsnprintf (char *buf, size_t size, const char *fmt, va_list ap)
174  {
         ...
187    strncpy (buf, str, min_size);
188    buf[min_size + 1] = '\0';
         ...
190    return ret;
191  }
192

I know this isn’t something fancy, but for a 5 minute post I think it’s fine. Once again, I’m sorry for not posting anything cool lately :P

Written by xorl

March 9, 2009 at 16:09

Posted in bugs

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s