Bug 79639 - security problem with gets
Summary: security problem with gets
Status: CLOSED WONTFIX
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: imap
Version: 8.0
Hardware: All
OS: Linux
medium
low
Target Milestone: ---
Assignee: Mike A. Harris
QA Contact: David Lawrence
URL:
Whiteboard:
Keywords:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2002-12-14 10:39 UTC by d.binderman
Modified: 2007-04-18 16:49 UTC (History)
0 users

(edit)
Clone Of:
(edit)
Last Closed: 2002-12-18 20:56:41 UTC


Attachments (Terms of Use)

Description d.binderman 2002-12-14 10:39:42 UTC
Description of problem:

Hello there,

I just tried to compile package imap-2001a-15 from Redhat 8.0.

Here are some of the compiler messages.

/usr/src/redhat/BUILD/imap-2001a/mtest/mtest.c:517: the `gets' function is dangerous and should not be used.

The man page for gets suggests that fgets is a suitable replacement.

I make the following untested patch

*** ./src/mtest/mtest.c.old	2001-06-05 19:53:44.000000000 +0100
--- ./src/mtest/mtest.c	2002-11-29 08:44:55.000000000 +0000
***************
*** 77,83 ****
  void header (MAILSTREAM *stream,long msgno);
  void display_body (BODY *body,char *pfx,long i);
  void status (MAILSTREAM *stream);
! void prompt (char *msg,char *txt);
  void smtptest (long debug);
  

  /* Main program - initialization */
--- 77,83 ----
  void header (MAILSTREAM *stream,long msgno);
  void display_body (BODY *body,char *pfx,long i);
  void status (MAILSTREAM *stream);
! static void prompt (char *msg,char *txt, int txtSize);
  void smtptest (long debug);
  

  /* Main program - initialization */
***************
*** 115,127 ****
  #endif
    curhst = cpystr (mylocalhost ());
    puts ("MTest -- C client test program");
!   if (!*personalname) prompt ("Personal name: ",personalname);
  				/* user wants protocol telemetry? */
!   prompt ("Debug protocol (y/n)?",tmp);
    ucase (tmp);
    debug = (tmp[0] == 'Y') ? T : NIL;
    do {
!     prompt ("Mailbox ('?' for help): ",tmp);
      if (!strcmp (tmp,"?")) {
        puts ("Enter INBOX, mailbox name, or IMAP mailbox as {host}mailbox");
        puts ("Known local mailboxes:");
--- 115,128 ----
  #endif
    curhst = cpystr (mylocalhost ());
    puts ("MTest -- C client test program");
!   if (!*personalname) 
! 	prompt ("Personal name: ",personalname, sizeof( personalname));
  				/* user wants protocol telemetry? */
!   prompt ("Debug protocol (y/n)?",tmp, sizeof tmp);
    ucase (tmp);
    debug = (tmp[0] == 'Y') ? T : NIL;
    do {
!     prompt ("Mailbox ('?' for help): ",tmp, sizeof tmp);
      if (!strcmp (tmp,"?")) {
        puts ("Enter INBOX, mailbox name, or IMAP mailbox as {host}mailbox");
        puts ("Known local mailboxes:");
***************
*** 157,163 ****
    BODY *body;
    status (stream);		/* first report message status */
    while (stream) {
!     prompt ("MTest>",cmd);	/* prompt user, get command */
  				/* get argument */
      if (arg = strchr (cmd,' ')) *arg++ = '\0';
      switch (*ucase (cmd)) {	/* dispatch based on command */
--- 158,164 ----
    BODY *body;
    status (stream);		/* first report message status */
    while (stream) {
!     prompt ("MTest>",cmd, sizeof( cmd));	/* prompt user, get command */
  				/* get argument */
      if (arg = strchr (cmd,' ')) *arg++ = '\0';
      switch (*ucase (cmd)) {	/* dispatch based on command */
***************
*** 252,258 ****
        }
  				/* get the new mailbox */
        while (!(stream = mail_open (stream,arg,debug))) {
! 	prompt ("Mailbox: ",arg);
  	if (!arg[0]) break;
        }
        last = 0;
--- 253,259 ----
        }
  				/* get the new mailbox */
        while (!(stream = mail_open (stream,arg,debug))) {
! 	prompt ("Mailbox: ",arg, sizeof( arg));
  	if (!arg[0]) break;
        }
        last = 0;
***************
*** 511,520 ****
   *          pointer to input buffer
   */
  
! void prompt (char *msg,char *txt)
  {
    printf ("%s",msg);
!   gets (txt);
  }
  

  /* Interfaces to C-client */
--- 512,522 ----
   *          pointer to input buffer
   */
  
! static void 
! prompt (char *msg,char *txt, int txtSize)
  {
    printf ("%s",msg);
!   fgets (txt, txtSize, stdin);
  }
  

  /* Interfaces to C-client */
***************
*** 624,630 ****
    }
    else {
      sprintf (tmp,"{%s/%s} username: ",mb->host,mb->service);
!     prompt (tmp,user);
      strcpy (tmp,"Password: ");
    }
    if (curusr) fs_give ((void **) &curusr);
--- 626,632 ----
    }
    else {
      sprintf (tmp,"{%s/%s} username: ",mb->host,mb->service);
!     prompt (tmp,user, sizeof( user));
      strcpy (tmp,"Password: ");
    }
    if (curusr) fs_give ((void **) &curusr);
***************
*** 632,638 ****
  #if UNIXLIKE
    strcpy (pwd,getpass (tmp));
  #else
!   prompt (tmp,pwd);
  #endif
  }
  
--- 634,640 ----
  #if UNIXLIKE
    strcpy (pwd,getpass (tmp));
  #else
!   prompt (tmp,pwd, sizeof( pwd));
  #endif
  }
  
***************
*** 679,692 ****
    msg->return_path = mail_newaddr ();
    msg->return_path->mailbox = cpystr (curusr);
    msg->return_path->host = cpystr (curhst);
!   prompt ("To: ",line);
    rfc822_parse_adrlist (&msg->to,line,curhst);
    if (msg->to) {
!     prompt ("cc: ",line);
      rfc822_parse_adrlist (&msg->cc,line,curhst);
    }
    else {
!     prompt ("Newsgroups: ",line);
      if (*line) msg->newsgroups = cpystr (line);
      else {
        mail_free_body (&body);
--- 681,694 ----
    msg->return_path = mail_newaddr ();
    msg->return_path->mailbox = cpystr (curusr);
    msg->return_path->host = cpystr (curhst);
!   prompt ("To: ",line, sizeof( line));
    rfc822_parse_adrlist (&msg->to,line,curhst);
    if (msg->to) {
!     prompt ("cc: ",line, sizeof( line));
      rfc822_parse_adrlist (&msg->cc,line,curhst);
    }
    else {
!     prompt ("Newsgroups: ",line, sizeof( line));
      if (*line) msg->newsgroups = cpystr (line);
      else {
        mail_free_body (&body);
***************
*** 694,705 ****
        fs_give ((void **) &text);
      }
    }
!   prompt ("Subject: ",line);
    msg->subject = cpystr (line);
    puts (" Msg (end with a line with only a '.'):");
    body->type = TYPETEXT;
    *text = '\0';
!   while (gets (line)) {
      if (line[0] == '.') {
        if (line[1] == '\0') break;
        else strcat (text,".");
--- 696,707 ----
        fs_give ((void **) &text);
      }
    }
!   prompt ("Subject: ",line, sizeof( line));
    msg->subject = cpystr (line);
    puts (" Msg (end with a line with only a '.'):");
    body->type = TYPETEXT;
    *text = '\0';
!   while (fgets (line, sizeof( line), stdin)) {
      if (line[0] == '.') {
        if (line[1] == '\0') break;
        else strcat (text,".");


Version-Release number of selected component (if applicable):


How reproducible:


Steps to Reproduce:
1.
2.
3.
    
Actual results:


Expected results:


Additional info:

Comment 1 Alan Cox 2002-12-18 18:51:21 UTC
This is a test tool not something we install


Comment 2 Mike A. Harris 2002-12-18 20:56:41 UTC
As Alan says, this is a test tool, and is not even shipped with Red Hat Linux.
Also, the imap FAQ states that they are aware of gets() and consider it
a non issue due to the nature of the software.

Personally, I would fix it if I was the upstream maintainer, just to have
more robust software regardless of how trivial it is, and to also not
propagate poor programming techniques.  However upstream maintainers are
unlikely to be convinced in any case.

Closing WONTFIX


Note You need to log in before you can comment on or make changes to this bug.