26th Sep 2002 [SBWID-5316]
COMMAND
	Qpopper buffer overflow condition
SYSTEMS AFFECTED
	Qpopper 4.0.3 and 4.0.4. default install.
PROBLEM
	In Marcel Fodor [http://mantra.freeweb.hu] security bug report :
	In :
	
	pop_bull.c
	-----------
	int
	CopyOneBull ( POP *p, long bnum, char *name )
	{
	    FILE              *bull;
	    char                buffer [ MAXMSGLINELEN ];
	    BOOL            in_header            = TRUE;
	    BOOL            first_line              = TRUE;
	    int                    nchar; 
	    int                    msg_num;
	    int                    msg_vis_num          = 0;
	    int                    msg_ends_in_nl       = 0;
	    char                bullName [ 256 ];
	    MsgInfoList    *mp;               /* Pointer to message info list */
	.
	.
	.
	    sprintf ( bullName, "%s/%s", p->bulldir, name );
	------------
	
	The bullNmae buffer is 256 bytes long, but in the  user's  configuration
	file you can define it up to MAXLINELEN-1-sizeof("set  bulldir=")  ~1010
	bytes.
	
	~/.qpopper-options
	--------------
	set bulldir=AAAAAAAAAAA.....AAAAAAAAAAAAAAA // ( bulldir must exist)
	--------------
	
	Since we have only 1010+256 bytes(p->bulldir+name) it is NOT  enough  to
	overflow the funcion`s stack and overwrite EIP.
	As you see the following registers can be overwritten:
	
	    BOOL         in_header            = TRUE; 
	    BOOL         first_line              = TRUE; 
	    int                nchar; 
	    int                msg_num;
	    int                msg_vis_num       = 0;
	    int                msg_ends_in_nl   = 0;
	    char             bullName [ 256 ];
	---------------------
	    MsgInfoList   *mp;               /* Pointer to message info list */
	
	There are two valuable registers:
	
	    1. msg_num
	    2. msg_vis_num
	
	As the code runs on, server  wants  to  find  memory  location  for  the
	actual message. Here it is:
	
	   mp = p->mlp + msg_num - 1;
	
	As we have control over msg_num, we  can  walk  forward  in  memory,  by
	steps of 0x40 bytes (sizeof(*mp)). On my  system  giving  the  value  of
	0x2dfe423 to msg_num, mp will point to 0xbfffbe6c Now code runs on,  and
	fill up properties.
	 
	    ++mp;
	    mp->number          = msg_num;
	    mp->visible_num    = ++msg_vis_num;               <---- we have this
	    mp->lines               = 0;
	    mp->body_lines     = 0;
	    mp->offset             = ftell(p->drop);
	    mp->del_flag         = FALSE;
	    mp->hide_flag       = FALSE;
	    mp->retr_flag        = FALSE;
	
	So, the main thing is the 0x40 bytes steps. For this, the  risk  of  the
	bug is low.
SOLUTION
	 Workaround  :
	 ==========
	Servers, not processing user's configuration  file  (~/.qpopper-options)
	are insensible to this bug. ( qpopper -u)
	 Patch :
	 =====
	None yet ?