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