Le vendredi 1 mars 2013 14:00:07, Julien Cristau a écrit :
> Actually...
> 

> 
> Seems like ATX->recipient now points somewhere on the stack, and thus in
> la-la-land at the end of the loop in process_users.  Is there any
> guarantee it's not reused after that?  The scoping is kind of
> non-obvious...

Indeed, it's not obvious. So ATX->recipient points to one of 3 buffers:

* args[1024] in deliver_message()
* recipient[256] in the main while loop of process_users()
* mailbox[256] in process_users()

I've checked all the place where recipient is used (grep -ERIn recipient | 
grep ^src) and it's used only in 5 functions:

client_connect(), deliver_socket(), process_message(), deliver_message() and 
process_users().

deliver_socket(), process_message and deliver_message() are called directly or 
indirectly by process_users().

client_connect() can be called by deliver_socket() (and thus indirectly by 
process_users()) but also by the main() of dspam.c or the main() of dspamc.c 
in which case recipient is not set and should be NULL.

So when recipient points to recipient[256] or mailbox[256] there is no problem 
as the buffer is still in the scope.

For args[1024], I'm not 100% sure because that would require to follow all the 
use of ATX but looking at the code of deliver_message it's used to do some 
temporary transformation on the text which is used later in the function.

Hence ATX->recipient always points to a valid buffer (not overwritten on the 
stack by returing and then calling another function). Attached are my notes in 
case you want to take a look.

> 
> Cheers,
> Julien

Best regards,

Thomas
client_connect()   src/client.c:318:    if (ATX->recipient && 
ATX->recipient[0]) {
client_connect()   src/client.c:319:      char *domain = strchr(ATX->recipient, 
'@');
client_connect()   src/client.c:322:        char 
lcdomain[strlen(ATX->recipient)];
deliver_socket()   src/client.c:844:  snprintf(buf, sizeof(buf), "RCPT 
TO:<%s>", (ATX->recipient) ? ATX->recipient : "");
process_message()  src/dspam.c:503:        strlcpy(ATX->recipient, 
CTX->username, 256);
deliver_message()  src/dspam.c:925:    strlcpy(args, ATX->recipient, 
sizeof(args));
deliver_message()  src/dspam.c:937:    arg=index(ATX->recipient, '@');
deliver_message()  src/dspam.c:940:    ATX->recipient=args;
deliver_message()  src/dspam.c:998:      if (ATX->recipient)
deliver_message()  src/dspam.c:999:        strlcpy(a, ATX->recipient, 
sizeof(a));
process_users()    src/dspam.c:1625:    char recipient[256];
process_users()    src/dspam.c:1664:      strlcpy(recipient, node_rcpt->ptr, 
sizeof(recipient));
process_users()    src/dspam.c:1672:      strlcpy(recipient, node_nt->ptr, 
sizeof(recipient));
process_users()    src/dspam.c:1674:    ATX->recipient = recipient;
process_users()    src/dspam.c:1684:      ATX->recipient = mailbox;


*** in src/daemon.c ***

process_connection() calls:
  process_users()


*** in src/dspamc.c ***

main() calls:
  client_process()


*** in src/client.c ***

client_process() calls:
  client_connect()

deliver_socket() calls:
  client_connect()


*** in src/dspam.c ***

main() calls (in src/dspam.c):
  process_users()
  client_process()

process_users() calls:
  process_message() 4 times
  deliver_message() 5 times

send_notice() calls:
  deliver_message()

deliver_message() calls:
  deliver_socket()

src/dspam.c:503 in process_users
src/dspam.c:940 in deliver_message
src/dspam.c:1674 in process_users
src/dspam.c:1684 in process_users

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to