Security Problem ( Buffer Overflow) in newlib
Corinna Vinschen
vinschen@redhat.com
Mon Sep 17 09:01:00 GMT 2001
On Sun, Sep 16, 2001 at 01:32:31PM +0200, Bjoern Voigt wrote:
> 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:
That file is never used in Cygwin. Cygwin implements it's own
version of getpwent() which is in winsup/cygwin/passwd.cc.
It doesn't have the below static buffer problem.
Corinna
>
> 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@cs.tu-berlin.de>
> WWW: http://user.cs.tu-berlin.de/~bjoern/
>
>
--
Corinna Vinschen
Cygwin Developer
Red Hat, Inc.
mailto:vinschen@redhat.com
More information about the Newlib
mailing list