2nd Underhanded C Contest Begins

X

Xcott Craver

The second Underhanded C contest just opened today, and will run until
July 4th. The Prize is a ThinkGeek gift certificate.

The object is to write deceptive C code, code that does something
malicious but looks innocent and simple enough to pass a cursory
examination of the source.

Last year's contest was to write an image processing routine that
covertly embedds fingerprints in the images it creates. This year's
challenge is to write C code that runs fine on one OS but mysteriously
slowly on a competing OS.
 
S

Sebastian Gottschalk

Xcott said:
This year's
challenge is to write C code that runs fine on one OS but mysteriously
slowly on a competing OS.

void setnormalcount(uint8 *count) {
count = 3;
}

const uint32 count = 0;
#ifdef NDEBUG
setnormalcount(&count);
#endif

while(count--) {
do_some_normal_task();
}
 
T

tomstdenis

Sebastian said:
void setnormalcount(uint8 *count) {
count = 3;
}

That should be *count = 3;
const uint32 count = 0;
#ifdef NDEBUG
setnormalcount(&count);

This will warning out.

It's probably valid to assume count=0 at this point and the compiler
may optimize out this loop.
while(count--) {
do_some_normal_task();
}

GCC 3.4.6 won't even compile this. It complains that decrementing
count is invalid.

And yes, GCC will allow you to overwrite 'count' but assumes it's zero.

For instance

void p(unsigned char *t) { *t = 3; }
const unsigned r = 0;
void q(void) { p(&r); if (r) printf("Whoa!\n"); }

produces [on my amd64]

p:
..LFB2:
movb $3, (%rdi)
ret
..LFE2:
.size p, .-p
.p2align 4,,15
..globl q
.type q, @function
q:
..LFB3:
movl $r, %edi
jmp p

So clearly the printf is totally ignored.

Tom
 
S

Sebastian Gottschalk

That should be *count = 3;

Jupp, sorry.
This will warning out.


It's probably valid to assume count=0 at this point and the compiler
may optimize out this loop.

It's probably valid to assume that the symbol NDEBUG (== no debug) is
defined and the this preprocessing statement justifies the use of th
setnormalcount() function (which would be inlined).
GCC 3.4.6 won't even compile this. It complains that decrementing
count is invalid.

Stupid me, if course the post-decrement means that count shouldn't be const.
So clearly the printf is totally ignored.

With the little correction done, it does the printf 2 times.
But well, compile it with a different endianess and you'll see why the
difference between uint8 and uint32 is an important detail. :)
 
D

Douglas A. Gwyn

GCC 3.4.6 won't even compile this. ...

No conforming C compiler will accept the code as is,
because the identifiers "uint8" and "uint32" aren't
defined.
 
W

Walter Roberson

Sebastian Gottschalk said:
With the little correction done, it does the printf 2 times.
But well, compile it with a different endianess and you'll see why the
difference between uint8 and uint32 is an important detail. :)

Hmmm, the result would depend on the endianness. Endianness is
a property of the processor + operating system combination, not
necessarily of the operating system by itself.

But either endianess, the program would still meet the criteria
of operating at different speeds in different environment.
 
J

Joe Estock

Xcott said:
The second Underhanded C contest just opened today, and will run until
July 4th. The Prize is a ThinkGeek gift certificate.

The object is to write deceptive C code, code that does something
malicious but looks innocent and simple enough to pass a cursory
examination of the source.

[snip]

Does this qualify? :)

Hint: this compiles cleanly and runs just fine - just one problem. Can
you find out what the problem is without compiling and running it?

#include <stdio.h>
#include <string.h>

int main(void)
{
char buffer[600000];
char piece[10];
long i;

strcpy(buffer, "");

for(i = 0; i <= 199999; i++)
{
sprintf(piece, "%ld", i);
strcat(buffer, piece);
}

printf("5=%d\n", strlen(buffer));

return(0);
}
 
C

CBFalconer

Joe said:
Xcott said:
The second Underhanded C contest just opened today, and will run
until July 4th. The Prize is a ThinkGeek gift certificate.

The object is to write deceptive C code, code that does something
malicious but looks innocent and simple enough to pass a cursory
examination of the source.

[snip]

Does this qualify? :)

Hint: this compiles cleanly and runs just fine - just one problem. Can
you find out what the problem is without compiling and running it?

#include <stdio.h>
#include <string.h>

int main(void)
{
char buffer[600000];
char piece[10];
long i;

strcpy(buffer, "");

for(i = 0; i <= 199999; i++)
{
sprintf(piece, "%ld", i);
strcat(buffer, piece);
}

printf("5=%d\n", strlen(buffer));

return(0);
}

Apart from exhibiting undefined behaviour? Even assuming that the
assignment of storage for buffer works, which is not guaranteed.

BTW, using strlcat could avert the undefined problem.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
R

Richard Bos

Hmmm, the result would depend on the endianness. Endianness is
a property of the processor + operating system combination, not
necessarily of the operating system by itself.

Nothing in C is _necessarily_ a property of the OS itself. One can
always run any program in a C interpreter which provides identical,
repeatable behaviour on any OS it runs on.
More simply, if a certain OS provides default C libraries, and some
function in those libraries is sub-optimal, there is nothing to forbid
the implementation (as opposed to the user-programmer!) from redefining
that function _for that implementation only_.

Richard
 
J

jaysome

Richard said:
Nothing in C is _necessarily_ a property of the OS itself. One can
always run any program in a C interpreter which provides identical,
repeatable behaviour on any OS it runs on.
More simply, if a certain OS provides default C libraries, and some
function in those libraries is sub-optimal, there is nothing to forbid
the implementation (as opposed to the user-programmer!) from redefining
that function _for that implementation only_.

That's hard to believe. Do you have a section number from the C standard
that supports your position?

I can see how an implementation could provide a sub-optimal
implementation, but I can't see how that implementation could sacrifice
functionality. Sure, it may be slower, but it should still work as expected.
 
S

Sebastian Gottschalk

jaysome said:
That's hard to believe. Do you have a section number from the C standard
that supports your position?

Hm... f.e. fgets() might be a macro. On GLIBC and many other
implementations it's actually a function and some stupid programs expect
t to be so, but on dietlibc it's really just a macro.
I can see how an implementation could provide a sub-optimal
implementation, but I can't see how that implementation could sacrifice
functionality. Sure, it may be slower, but it should still work as
expected.

Oh, you don't know about macros? Try to understand how
max(a,max(b,max(c,max(d,max(e,f))))) expands.
 
P

pete

Sebastian said:
Hm... f.e. fgets() might be a macro.
On GLIBC and many other
implementations it's actually
a function and some stupid programs expect
t to be so, but on dietlibc it's really just a macro.

On a conforming implementation,
if a standard library function is rendered as a macro
then there also has to be a function version.
If <stdio.h> has been #included,
then you can consider (&fgets) to be a valid expression.
 
P

pemo

Xcott said:
The second Underhanded C contest just opened today, and will run until
July 4th. The Prize is a ThinkGeek gift certificate.

The object is to write deceptive C code, code that does something
malicious but looks innocent and simple enough to pass a cursory
examination of the source.

Last year's contest was to write an image processing routine that
covertly embedds fingerprints in the images it creates. This year's
challenge is to write C code that runs fine on one OS but mysteriously
slowly on a competing OS.


Some interesting and funny stuff about this on slashdot today ...

http://it.slashdot.org/article.pl?sid=06/04/05/1255233
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top