[16880] in bugtraq

home help back first fref pref prev next nref lref last post

Re: Format String Attacks

daemon@ATHENA.MIT.EDU (jsl2@JEDITECH.COM)
Fri Sep 22 14:03:17 2000

Mime-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Message-Id:  <Pine.GSO.4.10.10009211300490.15239-100000@stargazer.jeditech.com>
Date:         Thu, 21 Sep 2000 14:22:28 -0700
Reply-To: jsl2@JEDITECH.COM
From: jsl2@JEDITECH.COM
X-To:         Ajax <ajax@firest0rm.org>
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <Pine.BSO.4.10.10009192335180.18014-100000@firest0rm.org>

On Wed, 20 Sep 2000, Ajax wrote:

> When the compiler constructs the va_list that ap will point to, it simply
> makes the last element NULL, which can (ought) never be a valid pointer to
> anything.  ap then looks like:

	methinks this is more suitable for comp.lang.c, but what the heck...
we'll let Elias moderate this. :=)

	You cannot assume anything about va_list based on its definition or
prototypes. va_list and va_*() macros are to be treated as black-boxes. Use
them, but do not assume anything about how they are implemented or how it
works.

For example, on the x86, all args are passed on the stack. If you're calling
printf("help %i %s %f\n", 123, "abc", 2.35432):

			<=== remainder of the stack
---------------
|  2.3542     |		<=== 3rd vararg, a float
---------------
| char "abc\0"|		<=== 2nd vararg, a ptr to a character string
---------------
|   123       |		<=== first varable arg, in this case an integer
---------------
| const char* |		<=== first arg of printf(), a ptr to the fmt string
---------------
| ret address |     <=== return address, duh
---------------
|   .....     |     <=== SP upon entry to printf()


As you can see, there are no pointers to the integer or float vararg. varargs
is similar to an array of Visual Basic-like variant types, but since one
can't have an array of voids in C, the closest thing is an array of void
pointers.

In this example, when you call va_start(), "ap" is set to point at the first
vararg, which is the integer 123. When you fetch that int using va_arg()
macro, it increments "ap" by the size of the integer.

I suggest compiling a call to printf, and study disassembly of the
caller and printf() itself.

And yes, the compiler could have the caller include the # of varargs in the
parameter list, but that discussion has been had before (see Bugtraq
archives)

-James

home help back first fref pref prev next nref lref last post