Subject: Typo bugs, unfortunately in C too!

From: "Nadav Har'El" <[email-masked]>
Date: Fri, 12 Jan 2001 19:40:27 +0200

A while ago I wrote here about how annoying Fortran 77 is, and said that
one of its problems was that typo bugs (a bug caused by a mistake in typing)
was very common, and I showed several examples.

Today was the first time that it was brought to my attention that C was also
suseptible to typo bugs! It is caused by ANSI C's string-constant
concatination syntax, where you can simply write two adjacent string
constants, and they are concatenated into one. This concatenation syntax is
extremely useful in cases like

	printf("this is a very long message that doesn't fit very well "
               "on one line. Also, x=%g.", x);

But causes a bug when you do something like:

	char *string_list[] = {
		"first string",
		"another string",
		"hello"
		"yet another",
		"the end"
	}

See the missing comma after "hello"? A typo bug! Instead of having the
two strings "hello" and "yet another" on the list, we have only one,
"helloyet another".

Interestingly, the latest version of glibc (which is found, for example, in
the latest version of Redhat) has a typo bug exactly like that, with very
dire consequences: a non-priviliged user on a vulnerable system (such as
Redhat 7) can read *any* file on the system, readable or not (e.g.,
/etc/shadow...).

I enclose below excerpts from two postings on bugtraq (the vulnerability
mailing list for [other-definition-of-]hackers and people who try to defend
systems from them):

--------------------------------------
Date:         Wed, 10 Jan 2001 00:06:48 -0700
From: Charles Stevenson <[email-masked]>
To: [email-masked]
Subject:      Glibc Local Root Exploit

Hi all,
  This has been bouncing around on vuln-dev and the debian-devel lists. It
effects glibc >= 2.1.9x and it would seem many if not all OSes using these
versions of glibc. Ben Collins writes, "This wasn't supposed to happen, and
the actual fix was a missing comma in the list of secure env vars that were
supposed to be cleared when a program starts up suid/sgid (including
RESOLV_HOST_CONF)." The exploit varies from system to system but in our
devel version of Yellow Dog Linux I was able to print the /etc/shadow file
as a normal user in the following manner:

export RESOLV_HOST_CONF=/etc/shadow
ssh whatever.host.com

  Other programs have the same effect depending on the defaults for the
system. I have tested this on Red Hat 7.0, Yellow Dog Linux 2.0
(prerelease), and Debian Woody. Others have reported similar results on
slackware and even "home brew[ed]" GNU/Linux.
--------------------------------------
Date:         Thu, 11 Jan 2001 02:04:07 +0000
From: Simon Cozens <[email-masked]>
To: [email-masked]
Subject:      Re: Glibc Local Root Exploit

And a patch. Yeah, it's pretty obvious, but nobody's produced it yet.
Of course, it'll take you forever to *compile* the thing. :)

--- sysdeps/generic/unsecvars.h~    Wed Jan 10 23:37:09 2001
+++ sysdeps/generic/unsecvars.h Wed Jan 10 23:37:20 2001
@@ -5,7 +5,7 @@
   "LOCPATH",                                     \
   "MALLOC_TRACE",                                \
   "NLSPATH",                                     \
-  "RESOLV_HOST_CONF"                                 \
+  "RESOLV_HOST_CONF",                                \
   "RES_OPTIONS",                                 \
   "TMPDIR",                                      \
   "TZDIR"

-- 
Nadav Har'El                        |       Friday, Jan 12 2001, 18 Tevet 5761
[email-masked]             |-----------------------------------------
Phone: +972-53-245868, ICQ 13349191 |If I am not for myself, who will be for
http://nadav.harel.org.il           |me? If I am only for myself, who am I?

---

From: Shlomi Fish <[email-masked]>
Date: Fri, 12 Jan 2001 20:17:39 +0200 (IST)

Well, that just shows to always specify the number of elements in your
array when using C. That way you get a warning that there is an incorrect
number of elements.

In any case, I too think that such implicit string concatentation is a bad
idea. But still, C is much less vulnerable to typos than Fortran seemed
like from your post. (I don't know Fortran)

Regards,

	Shlomi Fish

----------------------------------------------------------------------
Shlomi Fish        [email-masked] 
Home Page:         http://t2.technion.ac.il/~shlomif/
Home E-mail:       [email-masked]

The prefix "God Said" has the extraordinary logical property of 
converting any statement that follows it into a true one.

---

From: Oleg Goldshmidt <[email-masked]>
Date: 14 Jan 2001 10:08:47 +0200

"Nadav Har'El" <[email-masked]> writes:

> suseptible to typo bugs! 

C is very much susceptible to typos. If you didn't know about

   if (status = UNDER_NUCLEAR_ATTACK) {
        fill_retaliatory_strike();
   }

it's time you learn... ;-)

That said, the glibc example is scary. There are patches in RH errata.

-- 
Oleg Goldshmidt | Comgates Ltd. | [email-masked] 
"... We work by wit, and not by witchcraft;
 And wit depends on dilatory time." [Shakespeare]

---

From: Shlomi Fish <[email-masked]>
Date: Sun, 14 Jan 2001 10:24:15 +0200 (IST)

> it's time you learn... ;-)

Usually, the compiler gives you a warning for this kind of thing.
However, in perl it does not.

Regards,

	Shlomi Fish
 
> To unsubscribe from this group, send an email to:
> [email-masked]
> 
> 
> 
>

---

From: mulix <[email-masked]>
Date: Sun, 14 Jan 2001 12:20:45 +0200

why not help the compiler help you... 

    if (UNDER_NUCLEAR_ATTACK == status) {
         fill_retaliatory_strike();
    }

-- 
mulix

linux/reboot.h: #define LINUX_REBOOT_MAGIC1 0xfee1dead

---

From: Oleg Goldshmidt <[email-masked]>
Date: 14 Jan 2001 14:57:50 +0200

>          fill_retaliatory_strike();

There are many ways to avoid such typos, that's not the point.

> > Usually, the compiler gives you a warning for this kind of thing.

Usually it won't. Sometimes, it might.

The way I wrote it, gcc might suggest putting an extra couple of
parentheses arround it, but I am not aware of, say, any gcc option
that will give me a warning for

    if ((status = UNDER_NUCLEAR_ATTACK) && 
        (alert_level == WEAPONS_READY)) {
        full_retaliatory_strike();
    }

The particular example is not the point. You can get weird kinds of
bugs by putting an extra ; or using , or in 1001 other ways in C.
Fortran does not have a monopoly on this kind of thing.

---

From: "Nadav Har'El" <[email-masked]>
Date: Sun, 14 Jan 2001 16:09:23 +0200

On Sun, Jan 14, 2001, Oleg Goldshmidt wrote about "Re: [hackers-il] Typo bugs, unfortunately in C too!":
>...

Yes, Fortran doesn't have a monopoly on typo bugs. But it does control
most of that market :)

-- 
Nadav Har'El                        |       Sunday, Jan 14 2001, 19 Tevet 5761
[email-masked]             |-----------------------------------------
Phone: +972-53-245868, ICQ 13349191 |Computers are like air conditioners.
http://nadav.harel.org.il           |Both stop working if you open windows.