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_usersAttachment:
signature.asc
Description: This is a digitally signed message part.