-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi,
Some days ago I send you this bug report.
Have you seen something about it ?
[...]
Hi,
I'm using Qpopper 4.0.2 and I have found a bug in the module 'popper.c',
function 'getline()'.
The bug is in the line:
425: if ( pPOP->pcInEnd != pPOP->pcInStart && *p == '\n' ) {
The solution is modify the line this way:
OLD 425: if ( pPOP->pcInEnd != pPOP->pcInStart && *p == '\n' ) {
NEW 425: if ( p != pPOP->pcInEnd && *p == '\n' ) {
I'm going to explain the bug.
Its something hard to explain, but I'll do my best :-)
The problem appears when I try to test one of my pop users accounts using the
telnet client from Windows.
This telnet client sends one TCP packet for every keystroke.
The function getline stores one line from the client TCP connection in one
buffer. If this BUFFER IS NOT INITIALIZED it will contain RANDOM BYTES.
Imagin that the buffer has this random bytes:
--------------------
| a | | g | 1 | | F | k |\n | X | ....
--------------------
and that I type the line 'pass pass00' in my Windows telnet client.
When Qpopper calls the function getline() the status of the buffer and the
pointers will be:
--------------------
| a | | g | 1 | | F | k |\n | X | ....
--------------------
^------pPOP->pcInStart
^------pPOP->pcInEnd
^------p
After the first read system call over the connected socket:
526: nRead = read ( pPOP->input_fd, pPOP->pcInEnd, nRoom );
the status of the buffer and the pointers will be:
--------------------
| p | | g | 1 | | F | k |\n | X | ....
--------------------
^--------pPOP->pcInStart
^------pPOP->pcInEnd
^--------p
Here the Qpopper process has readed the first letter of the pass keyword from
the connected socket. Due that my telnet client sends one TCP packet for
every keystroke, when Qpopper issues the read system call over the socket, it
will read only one byte.
Next the program flow goes to the begining of the main while loop of the
getline() function and this is the code executed:
418: /*
419: * Look for line in our buffer
420: */
421: p = pPOP->pcInStart;
422: for ( ; p < pPOP->pcInEnd; p++ )
423: if ( *p == '\n' )
424: break;
After this loop the status will be:
--------------------
| p | | g | 1 | | F | k |\n | X | ....
--------------------
^--------pPOP->pcInStart
^------pPOP->pcInEnd
^------p
And then the code line in which the bug is will be executed:
OLD 425: if ( pPOP->pcInEnd != pPOP->pcInStart && *p == '\n' ) {
At this point we we can see the bug.
If you see the status of the p pointer, its POINTING A BYTE WITH RANDOM DATA
and we are using it as part of the if conditions of the code line with the
bug !!!!!!
If we follow the program, we will reach the status:
--------------------
| p | a | s | s | | p | a |\n | X | ....
--------------------
^--- -----------------pPOP->pcInStart
^------pPOP->pcInEnd
^------p
In this status the conditios for the if stament in the line 425:
OLD 425: if ( pPOP->pcInEnd != pPOP->pcInStart && *p == '\n' ) {
become both true, making that the getline() function finish returning the
line 'pass pa', instead of the line I typed 'pass pass00', and my Qpopper
finish giving the error '-ERR [AUTH] Password supplied for "user" is
incorrect.'.
How I have said, the solution to the bug is very simple, modify the line 425
this way:
OLD 425: if ( pPOP->pcInEnd != pPOP->pcInStart && *p == '\n' ) {
NEW 425: if ( p != pPOP->pcInEnd && *p == '\n' ) {
With this modification, if the p pointer points to the same random byte that
pPOP->pcInEnd, the first condition of the if stament is not true and the
function getline() continues until a '\n' caracter is read from the socket.
I have observed that the bug only appears with users with the length of its
password string greater than the length of its user name. I believe that this
is because the same buffer is used to store the POP request 'user username',
and the next 'pass password', but the buffer is not cleaned before the
receive of the pass POP request.
This problem is difficult to see because the email clients like Netscape,
Outlook, ... sends all the request in one TCP packet and when Qpopper calls
the read system call in the getline() function, it obtains all the bytes from
the request, including the '\n' byte. This way the bug never appears because
the getline function reads the '\n' byte in the request and, then, the p
pointer will never point to random data.
UFffff, I hope that my explanation will be clear enougth :-)
Well, this is my second bug report for the Qpopper development team :-)
Do you have any award or prize for acumulation of bug reporting ????? ;-)
[...]
Greetings.
- ---
Carles Xavier Munyoz Bald� / [EMAIL PROTECTED]
VAS - Experto en Sistemas IP
Wanadoo Espa�a - http://www.wanadoo.es/
Tel: +34 96 5040046 - Fax: +34 96 5040047
- ---
-----BEGIN PGP SIGNATURE-----
Version: PGP 6.5.8
iQA/AwUBOxIgsBAGkoZz8//aEQITCgCdGFM6Tw2YXxtn2KjeNKnTYVTK+kQAn22D
a6JzUziAwuzuw+e18WkHA21y
=A806
-----END PGP SIGNATURE-----
BUG REPORT: module popper.c, function getline()
Carles Xavier Munyoz Bald� Mon, 28 May 2001 02:40:04 -0700
- BUG REPORT: module popper.c, function getline() Carles Xavier Munyoz Bald�
- Re: BUG REPORT: module popper.c, function ... Carles Xavier Munyoz Bald�
- Re: BUG REPORT: module popper.c, function ... Gregory Hicks
- Re: BUG REPORT: module popper.c, funct... Homer Wilson Smith
- Re: BUG REPORT: module popper.c, function ... Carles Xavier Munyoz Bald�
- Re: BUG REPORT: module popper.c, funct... Derek Balling
- Re: BUG REPORT: module popper.c, funct... Carles Xavier Munyoz Bald�
- Re: BUG REPORT: module popper.c, funct... Chuck Yerkes
