possible overflow?
Joel Sherrill
joel.sherrill at OARcorp.com
Mon Oct 22 12:01:26 UTC 2001
This was reportd on the newlib list. We do not use
this getpwent.c, but I thought this would be worth
double checking.
Not that RTEMS has high security for users, but I thought
this would be worth checking against the RTEMS version
for safety's sake.
--joel
-------- Original Message --------
From: Bjoern Voigt <bjoern at cs.tu-berlin.de>
Subject: Security Problem ( Buffer Overflow) in newlib
To: <newlib at sources.redhat.com>
Hello Cygwin-Friends,
I made some C/C++ experiments with Cygwin and found an Buffer Overflow
problem in the newlib library. I have a CVS snapshot
"cygwin-src-20010907.tar.bz2" of Cygwin/Newlib, but the problem isn't
new.
Let us take a look at newlib/libc/unix/getpwent.c:
Line 13-19:
-------------------------------------------------------------------
static char logname[8];
static char password[1024];
static char gecos[1024];
static char dir[1024];
static char shell[1024];
-------------------------------------------------------------------
Line 33-37:
-------------------------------------------------------------------
sscanf (buf, "%[^:]:%[^:]:%d:%d:%[^:]:%[^:]:%s\n",
logname, password, &pw_passwd.pw_uid,
&pw_passwd.pw_gid, gecos,
dir, shell);
-------------------------------------------------------------------
We see, that there is no length checking.
One example for a buffer overflow:
1) Cygwin is installed as "administrator", so /etc/passwd contains:
administator:x:1111:2222:Administrator:/home/administrator:/bin/bash
2) The word "Administrator" has 13 characters, but logname[8] has only
7 characters plus '\0'.
I suggest to dynamically resize logname, password, dir and shell. As
an (not so nice) alternative we can check the length and cut for
instance logname after xy characters.
For testing I uses the following entry in /etc/passwd:
-------------------------------------------------------------------
administator:x:3333:100:Administrator:/home/administrator:/bin/bash
-------------------------------------------------------------------
and the following C program (runs on Cygwin and Linux):
-------------------------------------------------------------------
#include <pwd.h>
int main(int argc, char *argv[])
{
struct passwd *pw;
if(argc!=2) {
printf("usage: %s loginname\n",argv[0]);
return 1;
}
pw=getpwnam(argv[1]);
if(pw) {
printf("char *pw_name: %s\n",pw->pw_name);
printf("char *pw_passwd: %s\n",pw->pw_passwd);
printf("int pw_uid: %d\n",pw->pw_uid);
printf("int pw_gid: %d\n",pw->pw_gid);
/* on Linux there is no pw_comment */
/*printf("char *pw_comment: %s\n",pw->pw_comment);*/
printf("char *pw_gecos: %s\n",pw->pw_gecos);
printf("char *pw_dir: %s\n",pw->pw_dir);
printf("char *pw_shell: %s\n",pw->pw_shell);
}
else {
printf("Could not find %s !\n",argv[1]);
return 2;
}
return 0;
}
-------------------------------------------------------------------
Bye, Björn
--
Björn Voigt <bjoern at cs.tu-berlin.de>
WWW: http://user.cs.tu-berlin.de/~bjoern/
More information about the users
mailing list