Mercurial > dovecot > core-2.2
changeset 805:5ac361acb316 HEAD
Marked all non-trivial buffer modifications with @UNSAFE tag. Several
cleanups and a couple of minor bugfixes.
line wrap: on
line diff
--- a/configure.in Wed Dec 18 12:40:43 2002 +0200 +++ b/configure.in Wed Dec 18 17:15:41 2002 +0200 @@ -166,7 +166,7 @@ dnl * after -lsocket and -lnsl tests, inet_aton() may be in them AC_CHECK_FUNCS(fcntl flock inet_aton sigaction getpagesize madvise \ - strcasecmp stricmp vsnprintf memmove vsyslog writev setrlimit \ + strcasecmp stricmp vsnprintf vsyslog writev setrlimit \ setproctitle) dnl * poll/select?
--- a/src/auth/auth-digest-md5.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/auth/auth-digest-md5.c Wed Dec 18 17:15:41 2002 +0200 @@ -218,6 +218,7 @@ static int parse_next(char **data, char **key, char **value) { + /* @UNSAFE */ char *p, *dest; p = *data; @@ -271,6 +272,7 @@ /* remove leading and trailing whitespace */ static char *trim(char *str) { + /* @UNSAFE */ char *ret; while (IS_LWS(*str)) str++;
--- a/src/auth/userinfo-pam.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/auth/userinfo-pam.c Wed Dec 18 17:15:41 2002 +0200 @@ -60,6 +60,7 @@ static int pam_userpass_conv(int num_msg, linux_const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { + /* @UNSAFE */ pam_userpass_t *userpass = (pam_userpass_t *)appdata_ptr; #ifdef AUTH_PAM_USERPASS pamc_bp_t prompt;
--- a/src/auth/userinfo-passwd-file.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/auth/userinfo-passwd-file.c Wed Dec 18 17:15:41 2002 +0200 @@ -312,7 +312,7 @@ { IStream *input; char *const *args; - char *line; + const char *line; input = i_stream_create_file(pw->fd, default_pool, 2048, FALSE); for (;;) {
--- a/src/auth/userinfo-passwd.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/auth/userinfo-passwd.c Wed Dec 18 17:15:41 2002 +0200 @@ -31,7 +31,6 @@ AuthCookieReplyData *reply) { struct passwd *pw; - char *passdup; int result; pw = getpwnam(user); @@ -39,11 +38,9 @@ return FALSE; /* check if the password is valid */ - passdup = t_strdup_noconst(password); - result = strcmp(mycrypt(passdup, pw->pw_passwd), pw->pw_passwd) == 0; + result = strcmp(mycrypt(password, pw->pw_passwd), pw->pw_passwd) == 0; /* clear the passwords from memory */ - safe_memset(passdup, 0, strlen(passdup)); safe_memset(pw->pw_passwd, 0, strlen(pw->pw_passwd)); if (!result)
--- a/src/auth/userinfo-shadow.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/auth/userinfo-shadow.c Wed Dec 18 17:15:41 2002 +0200 @@ -20,7 +20,6 @@ { struct passwd *pw; struct spwd *spw; - char *passdup; int result; spw = getspnam(user); @@ -28,11 +27,9 @@ return FALSE; /* check if the password is valid */ - passdup = t_strdup_noconst(password); - result = strcmp(mycrypt(passdup, spw->sp_pwdp), spw->sp_pwdp) == 0; + result = strcmp(mycrypt(password, spw->sp_pwdp), spw->sp_pwdp) == 0; /* clear the passwords from memory */ - safe_memset(passdup, 0, strlen(passdup)); safe_memset(spw->sp_pwdp, 0, strlen(spw->sp_pwdp)); if (!result)
--- a/src/auth/userinfo-vpopmail.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/auth/userinfo-vpopmail.c Wed Dec 18 17:15:41 2002 +0200 @@ -26,7 +26,6 @@ { char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT]; struct vqpasswd *vpw; - char *passdup; int result; /* vpop_user must be zero-filled or parse_email() leaves an extra @@ -77,10 +76,7 @@ } /* verify password */ - passdup = t_strdup_noconst(password); - result = strcmp(crypt(passdup, vpw->pw_passwd), vpw->pw_passwd) == 0; - - safe_memset(passdup, 0, strlen(passdup)); + result = strcmp(crypt(password, vpw->pw_passwd), vpw->pw_passwd) == 0; safe_memset(vpw->pw_passwd, 0, strlen(vpw->pw_passwd)); if (!result) {
--- a/src/imap/client.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/imap/client.c Wed Dec 18 17:15:41 2002 +0200 @@ -63,10 +63,6 @@ client->output = o_stream_create_file(hout, default_pool, 4096, IO_PRIORITY_DEFAULT, FALSE); - /* always use nonblocking I/O */ - net_set_nonblock(hin, TRUE); - net_set_nonblock(hout, TRUE); - /* set timeout for reading expected data (eg. APPEND). This is different from the actual idle time. */ i_stream_set_blocking(client->input, CLIENT_CMDINPUT_TIMEOUT,
--- a/src/lib-imap/imap-envelope.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-imap/imap-envelope.c Wed Dec 18 17:15:41 2002 +0200 @@ -21,12 +21,7 @@ static Rfc822Address *parse_address(Pool pool, const char *value, size_t value_len) { - Rfc822Address *ret; - - t_push(); - ret = rfc822_address_parse(pool, t_strndup(value, value_len)); - t_pop(); - return ret; + return rfc822_address_parse(pool, t_strndup(value, value_len)); } void imap_envelope_parse_header(Pool pool, MessagePartEnvelopeData **data, @@ -38,6 +33,8 @@ (*data)->pool = pool; } + t_push(); + if (strcasecmp(name, "Date") == 0 && (*data)->date == NULL) (*data)->date = imap_quote_value(pool, value, value_len); else if (strcasecmp(name, "Subject") == 0 && (*data)->subject == NULL) @@ -60,6 +57,8 @@ else if (strcasecmp(name, "Message-Id") == 0 && (*data)->message_id == NULL) (*data)->message_id = imap_quote_value(pool, value, value_len); + + t_pop(); } static void imap_write_address(TempString *str, Rfc822Address *addr)
--- a/src/lib-imap/imap-match.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-imap/imap-match.c Wed Dec 18 17:15:41 2002 +0200 @@ -21,33 +21,34 @@ static const char inbox[] = "INBOX"; #define INBOXLEN (sizeof(inbox) - 1) -ImapMatchGlob *imap_match_init(const char *str, int inboxcase, char separator) +ImapMatchGlob *imap_match_init(const char *mask, int inboxcase, char separator) { ImapMatchGlob *glob; const char *p, *inboxp; char *dst; /* +1 from struct */ - glob = t_malloc(sizeof(ImapMatchGlob) + strlen(str)); + glob = t_malloc(sizeof(ImapMatchGlob) + strlen(mask)); glob->sep_char = separator; + /* @UNSAFE: compress the mask */ dst = glob->mask; - while (*str != '\0') { - if (*str == '*' || *str == '%') { + while (*mask != '\0') { + if (*mask == '*' || *mask == '%') { /* remove duplicate hierarchy wildcards */ - while (*str == '%') str++; + while (*mask == '%') mask++; /* "%*" -> "*" */ - if (*str == '*') { + if (*mask == '*') { /* remove duplicate wildcards */ - while (*str == '*' || *str == '%') - str++; + while (*mask == '*' || *mask == '%') + mask++; *dst++ = '*'; } else { *dst++ = '%'; } } else { - *dst++ = *str++; + *dst++ = *mask++; } } *dst++ = '\0';
--- a/src/lib-imap/imap-match.h Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-imap/imap-match.h Wed Dec 18 17:15:41 2002 +0200 @@ -5,7 +5,7 @@ /* If inboxcase is TRUE, the "INBOX" string at the beginning of line is compared case-insensitively */ -ImapMatchGlob *imap_match_init(const char *str, int inboxcase, char separator); +ImapMatchGlob *imap_match_init(const char *mask, int inboxcase, char separator); /* Returns 1 if matched, 0 if it didn't match, but could match with additional hierarchies, -1 if definitely didn't match */
--- a/src/lib-imap/imap-message-cache.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-imap/imap-message-cache.c Wed Dec 18 17:15:41 2002 +0200 @@ -228,7 +228,8 @@ do it only if the file isn't open already, since this takes more CPU than parsing message headers. */ value = cache->iface->get_cached_field( - IMAP_CACHE_BODYSTRUCTURE, cache->context); + IMAP_CACHE_BODYSTRUCTURE, + cache->context); if (value != NULL) { value = imap_body_parse_from_bodystructure( value);
--- a/src/lib-imap/imap-parser.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-imap/imap-parser.c Wed Dec 18 17:15:41 2002 +0200 @@ -136,6 +136,7 @@ i_assert(parser->cur_list != NULL); + /* @UNSAFE */ if (parser->cur_list->size == parser->cur_list->alloc) imap_args_realloc(parser, parser->cur_list->alloc * 2);
--- a/src/lib-imap/imap-util.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-imap/imap-util.c Wed Dec 18 17:15:41 2002 +0200 @@ -63,7 +63,7 @@ if (esc == 0) return str; - /* escape them */ + /* @UNSAFE: escape them */ p = ret = t_malloc(i + esc + 1); for (; *str != '\0'; str++) { if (IS_ESCAPED_CHAR(str[i]))
--- a/src/lib-index/mail-index-update.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-index/mail-index-update.c Wed Dec 18 17:15:41 2002 +0200 @@ -207,7 +207,7 @@ return TRUE; } -/* Replace the whole block - assumes there's enoguh space to do it */ +/* Replace the whole block - assumes there's enough space to do it */ static void update_by_replace_block(MailIndexUpdate *update, size_t extra_size) { MailIndexDataRecordHeader *data_hdr;
--- a/src/lib-index/mbox/mbox-index.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-index/mbox/mbox-index.c Wed Dec 18 17:15:41 2002 +0200 @@ -119,7 +119,8 @@ mbox_file_close_stream(index); if (index->mbox_fd != -1) { - close(index->mbox_fd); + if (close(index->mbox_fd) < 0) + i_error("close(mbox) failed: %m"); index->mbox_fd = -1; } }
--- a/src/lib-index/mbox/mbox-rewrite.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-index/mbox/mbox-rewrite.c Wed Dec 18 17:15:41 2002 +0200 @@ -199,7 +199,7 @@ static const char *strip_chars(const char *value, size_t value_len, const char *list) { - /* leave only unknown flags, very likely none */ + /* @UNSAFE: leave only unknown flags, very likely none */ char *ret, *p; size_t i;
--- a/src/lib-mail/message-body-search.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-mail/message-body-search.c Wed Dec 18 17:15:41 2002 +0200 @@ -32,9 +32,7 @@ CharsetTranslation *translation; Buffer *decode_buf; - - size_t *matches; - ssize_t match_count; + Buffer *match_buf; char *content_type; char *content_charset; @@ -156,30 +154,31 @@ static int message_search_decoded_block(PartSearchContext *ctx, Buffer *block) { const unsigned char *p, *end, *key; - size_t key_len, block_size; + size_t key_len, block_size, *matches, match_count, value; ssize_t i; key = (const unsigned char *) ctx->body_ctx->key; key_len = ctx->body_ctx->key_len; + matches = buffer_get_modifyable_data(ctx->match_buf, &match_count); + match_count /= sizeof(size_t); + p = buffer_get_data(block, &block_size); end = p + block_size; for (; p != end; p++) { - for (i = ctx->match_count-1; i >= 0; i--) { - if (key[ctx->matches[i]] == *p) { - if (++ctx->matches[i] == key_len) { + for (i = match_count-1; i >= 0; i--) { + if (key[matches[i]] == *p) { + if (++matches[i] == key_len) { /* full match */ p++; return TRUE; } } else { /* non-match */ - ctx->match_count--; - if (i != ctx->match_count) { - memmove(ctx->matches + i, - ctx->matches + i + 1, - ctx->match_count - i); - } + buffer_delete(ctx->match_buf, + i * sizeof(size_t), + sizeof(size_t)); + match_count--; } } @@ -190,8 +189,9 @@ return TRUE; } - i_assert((size_t)ctx->match_count < key_len); - ctx->matches[ctx->match_count++] = 1; + value = 1; + buffer_append(ctx->match_buf, &value, sizeof(value)); + match_count++; } } @@ -284,9 +284,9 @@ ctx->translation = charset_to_utf8_begin("ascii", NULL); ctx->decode_buf = buffer_create_static(data_stack_pool, 256); - - ctx->match_count = 0; - ctx->matches = t_malloc(sizeof(size_t) * ctx->body_ctx->key_len); + ctx->match_buf = buffer_create_static_hard(data_stack_pool, + sizeof(size_t) * + ctx->body_ctx->key_len); i_stream_skip(input, part->physical_pos + part->header_size.physical_size - input->v_offset);
--- a/src/lib-mail/message-header-search.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-mail/message-header-search.c Wed Dec 18 17:15:41 2002 +0200 @@ -18,8 +18,7 @@ size_t key_len; char *key_charset; - size_t *matches; /* size of strlen(key) */ - ssize_t match_count; + Buffer *match_buf; unsigned int found:1; unsigned int last_newline:1; @@ -48,7 +47,6 @@ if (key == NULL) { /* invalid key */ - t_pop(); return NULL; } @@ -66,7 +64,8 @@ } i_assert(ctx->key_len <= SSIZE_T_MAX/sizeof(size_t)); - ctx->matches = p_new(pool, size_t, ctx->key_len); + ctx->match_buf = buffer_create_static_hard(pool, sizeof(size_t) * + ctx->key_len); return ctx; } @@ -74,10 +73,11 @@ { Pool pool; + buffer_free(ctx->match_buf); + pool = ctx->pool; p_free(pool, ctx->key); p_free(pool, ctx->key_charset); - p_free(pool, ctx->matches); p_free(pool, ctx); } @@ -112,11 +112,14 @@ static void search_loop(const unsigned char *data, size_t size, HeaderSearchContext *ctx) { - size_t pos; + size_t pos, *matches, match_count, value; ssize_t i; unsigned char chr; int last_newline; + matches = buffer_get_modifyable_data(ctx->match_buf, &match_count); + match_count /= sizeof(size_t); + last_newline = ctx->last_newline; for (pos = 0; pos < size; pos++) { chr = data[pos]; @@ -137,7 +140,8 @@ if (last_newline && !ctx->submatch) { if (!IS_LWSP(chr)) { /* not a long header, reset matches */ - ctx->match_count = 0; + buffer_set_used_size(ctx->match_buf, 0); + match_count = 0; } chr = ' '; } @@ -146,21 +150,19 @@ if (chr == '\r' || chr == '\n') continue; - for (i = ctx->match_count-1; i >= 0; i--) { - if (ctx->key[ctx->matches[i]] == chr) { - if (++ctx->matches[i] == ctx->key_len) { + for (i = match_count-1; i >= 0; i--) { + if (ctx->key[matches[i]] == chr) { + if (++matches[i] == ctx->key_len) { /* full match */ ctx->found = TRUE; return; } } else { /* non-match */ - ctx->match_count--; - if (i != ctx->match_count) { - memmove(ctx->matches + i, - ctx->matches + i + 1, - ctx->match_count - i); - } + buffer_delete(ctx->match_buf, + i * sizeof(size_t), + sizeof(size_t)); + match_count--; } } @@ -170,8 +172,10 @@ ctx->found = TRUE; break; } - i_assert((size_t)ctx->match_count < ctx->key_len); - ctx->matches[ctx->match_count++] = 1; + + value = 1; + buffer_append(ctx->match_buf, &value, sizeof(value)); + match_count++; } } @@ -205,6 +209,6 @@ void message_header_search_reset(HeaderSearchContext *ctx) { - ctx->match_count = 0; + buffer_set_used_size(ctx->match_buf, 0); ctx->found = FALSE; }
--- a/src/lib-mail/message-size.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-mail/message-size.c Wed Dec 18 17:15:41 2002 +0200 @@ -161,7 +161,7 @@ } } -void message_size_add(MessageSize *dest, MessageSize *src) +void message_size_add(MessageSize *dest, const MessageSize *src) { dest->virtual_size += src->virtual_size; dest->physical_size += src->physical_size;
--- a/src/lib-mail/message-size.h Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-mail/message-size.h Wed Dec 18 17:15:41 2002 +0200 @@ -18,6 +18,6 @@ MessageSize *msg_size, int *cr_skipped); /* Sum contents of src into dest. */ -void message_size_add(MessageSize *dest, MessageSize *src); +void message_size_add(MessageSize *dest, const MessageSize *src); #endif
--- a/src/lib-mail/rfc822-tokenize.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-mail/rfc822-tokenize.c Wed Dec 18 17:15:41 2002 +0200 @@ -23,6 +23,7 @@ { Rfc822Token *token; + /* @UNSAFE */ if (*pos+1 >= INITIAL_COUNT) *tokens = t_buffer_reget_type(*tokens, Rfc822Token, *pos + 2); @@ -180,6 +181,7 @@ if (tokens_count != NULL) *tokens_count = pos; + /* @UNSAFE */ first_token[pos++].token = 0; t_buffer_alloc(sizeof(Rfc822Token) * pos); return first_token; @@ -187,6 +189,7 @@ const char *rfc822_tokens_get_value(const Rfc822Token *tokens, int count) { + /* @UNSAFE */ char *buf; size_t i, len, buf_size; int last_atom; @@ -249,6 +252,7 @@ const char *rfc822_tokens_get_value_quoted(const Rfc822Token *tokens, int count) { + /* @UNSAFE */ char *buf; size_t len, buf_size; int last_atom;
--- a/src/lib-storage/subscription-file/subscription-file.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib-storage/subscription-file/subscription-file.c Wed Dec 18 17:15:41 2002 +0200 @@ -74,6 +74,7 @@ if (lseek(fd, 0, SEEK_END) < 0) return subsfile_set_syscall_error(storage, "lseek()", path); + /* @UNSAFE */ buf = t_buffer_get(len+2); buf[0] = '\n'; memcpy(buf+1, name, len);
--- a/src/lib/buffer.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/buffer.c Wed Dec 18 17:15:41 2002 +0200 @@ -21,6 +21,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* @UNSAFE: whole file */ + #include "lib.h" #include "buffer.h" @@ -212,6 +214,58 @@ return data_size; } +size_t buffer_insert(Buffer *buf, size_t pos, + const void *data, size_t data_size) +{ + size_t move_size, size; + + move_size = buf->used - buf->start_pos; + i_assert(pos <= move_size); + move_size -= pos; + + if (data_size < (size_t)-1 - move_size) + size = data_size + move_size; + else + size = (size_t)-1; + + if (!buffer_check_write(buf, &pos, &size, TRUE)) + return 0; + + i_assert(size >= move_size); + size -= move_size; + + memmove(buf->w_buffer + pos + size, buf->w_buffer + pos, move_size); + memcpy(buf->w_buffer + pos, data, size); + return size; +} + +size_t buffer_delete(Buffer *buf, size_t pos, size_t size) +{ + size_t end_size; + + if (buf->readonly) + return 0; + + end_size = buf->used - buf->start_pos; + i_assert(pos <= end_size); + end_size -= pos; + + if (size < end_size) { + /* delete from between */ + memmove(buf->w_buffer + buf->start_pos + pos, + buf->w_buffer + buf->start_pos + pos + size, + end_size - size); + end_size = size; + } else { + /* delete the rest of the buffer */ + size = end_size; + end_size = 0; + } + + buffer_set_used_size(buf, pos + end_size); + return size; +} + size_t buffer_copy(Buffer *dest, size_t dest_pos, const Buffer *src, size_t src_pos, size_t copy_size) {
--- a/src/lib/buffer.h Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/buffer.h Wed Dec 18 17:15:41 2002 +0200 @@ -29,6 +29,12 @@ /* Append character to buffer, returns 1 if written, 0 if not. */ size_t buffer_append_c(Buffer *buf, char chr); +/* Insert data to buffer, returns number of bytes inserted. */ +size_t buffer_insert(Buffer *buf, size_t pos, + const void *data, size_t data_size); +/* Delete data from buffer, returns number of bytes deleted. */ +size_t buffer_delete(Buffer *buf, size_t pos, size_t size); + /* Copy data from buffer to another. The buffers may be same in which case it's internal copying, possibly with overlapping positions (ie. memmove() like functionality). copy_size may be set to (size_t)-1 to copy the rest of
--- a/src/lib/compat.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/compat.c Wed Dec 18 17:15:41 2002 +0200 @@ -34,34 +34,6 @@ # define INADDR_NONE INADDR_BROADCAST #endif -#ifndef HAVE_MEMMOVE -void *my_memmove(void *dest, const void *src, size_t size) -{ - char *destp = dest; - const char *srcp = src; - - if (destp < srcp) { - /* dest = 1234, src=234 */ - destp = dest; - srcp = src; - while (size > 0) { - *destp++ = *srcp++; - size--; - } - } else if (destp > srcp) { - /* dest = 234, src=123 */ - destp += size-1; - srcp += size-1; - while (size > 0) { - *destp-- = *srcp--; - size--; - } - } - - return dest; -} -#endif - #if !defined (HAVE_STRCASECMP) && !defined (HAVE_STRICMP) int my_strcasecmp(const char *s1, const char *s2) {
--- a/src/lib/compat.h Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/compat.h Wed Dec 18 17:15:41 2002 +0200 @@ -38,12 +38,6 @@ # error I do not know how to compare dev_t #endif -/* memmove() */ -#ifndef HAVE_MEMMOVE -# define memmove my_memmove -void *my_memmove(void *dest, const void *src, size_t n); -#endif - /* strcasecmp(), strncasecmp() */ #ifndef HAVE_STRCASECMP # ifdef HAVE_STRICMP
--- a/src/lib/data-stack.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/data-stack.c Wed Dec 18 17:15:41 2002 +0200 @@ -23,6 +23,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* @UNSAFE: whole file */ + #include "lib.h" #include "data-stack.h"
--- a/src/lib/hex-binary.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/hex-binary.c Wed Dec 18 17:15:41 2002 +0200 @@ -33,6 +33,8 @@ size_t i; int value; + /* @UNSAFE */ + buf = p = t_malloc(size * 2 + 1); for (i = 0; i < size; i++) { value = data[i] >> 4;
--- a/src/lib/ioloop-poll.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/ioloop-poll.c Wed Dec 18 17:15:41 2002 +0200 @@ -23,6 +23,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* @UNSAFE: whole file */ + #include "lib.h" #include "ioloop-internal.h"
--- a/src/lib/istream-file.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/istream-file.c Wed Dec 18 17:15:41 2002 +0200 @@ -23,6 +23,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* @UNSAFE: whole file */ + #include "lib.h" #include "alarm-hup.h" #include "istream-internal.h"
--- a/src/lib/istream.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/istream.c Wed Dec 18 17:15:41 2002 +0200 @@ -167,6 +167,7 @@ return NULL; } + /* @UNSAFE */ ret_buf = NULL; for (i = _stream->cr_lookup_pos; i < _stream->pos; i++) { if (_stream->buffer[i] == 10) {
--- a/src/lib/md5.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/md5.c Wed Dec 18 17:15:41 2002 +0200 @@ -186,6 +186,7 @@ void md5_update(MD5Context *ctx, const void *data, size_t size) { + /* @UNSAFE */ MD5_u32plus saved_lo; unsigned long used, free; @@ -220,6 +221,7 @@ void md5_final(MD5Context *ctx, unsigned char result[16]) { + /* @UNSAFE */ unsigned long used, free; used = ctx->lo & 0x3f;
--- a/src/lib/mempool-alloconly.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/mempool-alloconly.c Wed Dec 18 17:15:41 2002 +0200 @@ -24,6 +24,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* @UNSAFE: whole file */ + #include "lib.h" #include "mempool.h"
--- a/src/lib/mempool-datastack.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/mempool-datastack.c Wed Dec 18 17:15:41 2002 +0200 @@ -95,6 +95,7 @@ static void *pool_data_stack_realloc_min(Pool pool __attr_unused__, void *mem, size_t size) { + /* @UNSAFE */ PoolAlloc *alloc, *new_alloc; size_t old_size; unsigned char *rmem;
--- a/src/lib/mempool-system.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/mempool-system.c Wed Dec 18 17:15:41 2002 +0200 @@ -23,6 +23,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* @UNSAFE: whole file */ + #include "lib.h" #include "mempool.h"
--- a/src/lib/mmap-anon.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/mmap-anon.c Wed Dec 18 17:15:41 2002 +0200 @@ -21,6 +21,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* @UNSAFE: whole file */ + #include "lib.h" #include "mmap-util.h"
--- a/src/lib/network.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/network.c Wed Dec 18 17:15:41 2002 +0200 @@ -120,7 +120,7 @@ static inline void close_save_errno(int fd) { int old_errno = errno; - close(fd); + (void)close(fd); errno = old_errno; } @@ -420,6 +420,7 @@ to be free'd. Returns 0 = ok, others = error code for net_gethosterror() */ int net_gethostbyname(const char *addr, IPADDR **ips, int *ips_count) { + /* @UNSAFE */ #ifdef HAVE_IPV6 union sockaddr_union *so; struct addrinfo hints, *ai, *origai; @@ -508,25 +509,28 @@ return 0; } -int net_ip2host(const IPADDR *ip, char *host) +const char *net_ip2host(const IPADDR *ip) { #ifdef HAVE_IPV6 - if (!inet_ntop(ip->family, &ip->ip, host, MAX_IP_LEN)) - return -1; + char host[MAX_IP_LEN+1]; + + host[MAX_IP_LEN] = '\0'; + if (inet_ntop(ip->family, &ip->ip, host, MAX_IP_LEN) == NULL) + return NULL; + + return t_strdup(host); #else unsigned long ip4; - if (ip->family != AF_INET) { - strcpy(host, "0.0.0.0"); - return -1; - } + if (ip->family != AF_INET) + return NULL; ip4 = ntohl(ip->ip.s_addr); - i_snprintf(host, MAX_IP_LEN, "%lu.%lu.%lu.%lu", - (ip4 & 0xff000000UL) >> 24, - (ip4 & 0x00ff0000) >> 16, - (ip4 & 0x0000ff00) >> 8, - (ip4 & 0x000000ff)); + return t_strdup_printf("%lu.%lu.%lu.%lu", + (ip4 & 0xff000000UL) >> 24, + (ip4 & 0x00ff0000) >> 16, + (ip4 & 0x0000ff00) >> 8, + (ip4 & 0x000000ff)); #endif return 0; }
--- a/src/lib/network.h Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/network.h Wed Dec 18 17:15:41 2002 +0200 @@ -89,8 +89,8 @@ /* Get socket address/port */ int net_getsockname(int fd, IPADDR *addr, unsigned int *port); -/* IPADDR -> char* translation. `host' must be at least MAX_IP_LEN bytes */ -int net_ip2host(const IPADDR *ip, char *host); +/* Returns IPADDR as string, or NULL if ip is invalid. */ +const char *net_ip2host(const IPADDR *ip); /* char* -> IPADDR translation. */ int net_host2ip(const char *host, IPADDR *ip);
--- a/src/lib/ostream-file.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/ostream-file.c Wed Dec 18 17:15:41 2002 +0200 @@ -23,6 +23,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* @UNSAFE: whole file */ + #include "lib.h" #include "alarm-hup.h" #include "ioloop.h"
--- a/src/lib/randgen.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/randgen.c Wed Dec 18 17:15:41 2002 +0200 @@ -56,8 +56,8 @@ urandom_fd = open("/dev/urandom", O_RDONLY); if (urandom_fd == -1) { if (errno == ENOENT) { - i_fatal("/dev/urandom doesn't exist, currently we " - "require it"); + i_fatal("/dev/urandom doesn't exist, " + "currently we require it"); } else { i_fatal("Can't open /dev/urandom: %m"); }
--- a/src/lib/strfuncs.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/strfuncs.c Wed Dec 18 17:15:41 2002 +0200 @@ -24,6 +24,8 @@ Boston, MA 02111-1307, USA. */ +/* @UNSAFE: whole file */ + #include "lib.h" #include "strfuncs.h"
--- a/src/lib/temp-string.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/temp-string.c Wed Dec 18 17:15:41 2002 +0200 @@ -23,6 +23,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* @UNSAFE: whole file */ + #include "lib.h" #include "temp-string.h"
--- a/src/lib/unlink-directory.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/lib/unlink-directory.c Wed Dec 18 17:15:41 2002 +0200 @@ -51,15 +51,17 @@ i_snprintf(path, sizeof(path), "%s/%s", dir, d->d_name); - if (unlink(path) == -1) { + if (unlink(path) == -1 && errno != ENOENT) { + int old_errno = errno; + if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) { if (!unlink_directory(path)) return FALSE; } else { /* so it wasn't a directory, unlink() again to get correct errno */ - if (unlink(path) == -1) - return FALSE; + errno = old_errno; + return FALSE; } } }
--- a/src/login/auth-connection.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/login/auth-connection.c Wed Dec 18 17:15:41 2002 +0200 @@ -119,7 +119,8 @@ hash_foreach(conn->requests, request_hash_destroy, NULL); hash_destroy(conn->requests); - (void)close(conn->fd); + if (close(conn->fd) < 0) + i_error("close(imap-auth) failed: %m"); io_remove(conn->io); i_stream_unref(conn->input); o_stream_unref(conn->output);
--- a/src/login/client-authenticate.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/login/client-authenticate.c Wed Dec 18 17:15:41 2002 +0200 @@ -251,8 +251,6 @@ return; } - t_push(); - linelen = strlen(line); buf = buffer_create_static_hard(data_stack_pool, linelen); @@ -272,8 +270,6 @@ bufsize = buffer_get_used_size(buf); safe_memset(buffer_free_without_data(buf), 0, bufsize); - - t_pop(); } int cmd_authenticate(Client *client, const char *method_name)
--- a/src/login/client.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/login/client.c Wed Dec 18 17:15:41 2002 +0200 @@ -27,13 +27,14 @@ static void client_set_title(Client *client) { - char host[MAX_IP_LEN]; + const char *host; if (!verbose_proctitle || !process_per_connection) return; - if (net_ip2host(&client->ip, host) < 0) - strcpy(host, "??"); + host = net_ip2host(&client->ip); + if (host == NULL) + host = "??"; process_title_set(t_strdup_printf(client->tls ? "[%s TLS]" : "[%s]", host)); @@ -133,36 +134,39 @@ } } -static char *get_next_arg(char **line) +static char *get_next_arg(char **linep) { - char *start; + char *line, *start; int quoted; - while (**line == ' ') (*line)++; - - if (**line == '"') { - quoted = TRUE; - (*line)++; + line = *linep; + while (*line == ' ') line++; - start = *line; - while (**line != '\0' && **line != '"') { - if (**line == '\\' && (*line)[1] != '\0') - (*line)++; - (*line)++; + /* @UNSAFE: get next argument, unescape arg if it's quoted */ + if (*line == '"') { + quoted = TRUE; + line++; + + start = line; + while (*line != '\0' && *line != '"') { + if (*line == '\\' && line[1] != '\0') + line++; + line++; } - if (**line == '"') - *(*line)++ = '\0'; + if (*line == '"') + *line++ = '\0'; string_remove_escapes(start); } else { - start = *line; - while (**line != '\0' && **line != ' ') - (*line)++; + start = line; + while (*line != '\0' && *line != ' ') + line++; - if (**line == ' ') - *(*line)++ = '\0'; + if (*line == ' ') + *line++ = '\0'; } + *linep = line; return start; } @@ -237,16 +241,17 @@ void *context) { Client *client = key; - Client **destroy_clients = context; - int i; + Buffer *destroy_buf = context; + Client *const *destroy_clients; + size_t i, count; - for (i = 0; i < CLIENT_DESTROY_OLDEST_COUNT; i++) { - if (destroy_clients[i] == NULL || - destroy_clients[i]->created > client->created) { - memmove(destroy_clients+i+1, destroy_clients+i, - sizeof(Client *) * - (CLIENT_DESTROY_OLDEST_COUNT - i-1)); - destroy_clients[i] = client; + destroy_clients = buffer_get_data(destroy_buf, &count); + count /= sizeof(Client *); + + for (i = 0; i < count; i++) { + if (destroy_clients[i]->created > client->created) { + buffer_insert(destroy_buf, i * sizeof(Client *), + &client, sizeof(client)); break; } } @@ -254,13 +259,21 @@ static void client_destroy_oldest(void) { - Client *destroy_clients[CLIENT_DESTROY_OLDEST_COUNT]; - int i; + Buffer *destroy_buf; + Client *const *destroy_clients; + size_t i, count; - memset(destroy_clients, 0, sizeof(destroy_clients)); - hash_foreach(clients, client_hash_destroy_oldest, destroy_clients); + /* find the oldest clients and put them to destroy-buffer */ + destroy_buf = buffer_create_static_hard(data_stack_pool, + sizeof(Client *) * + CLIENT_DESTROY_OLDEST_COUNT); + hash_foreach(clients, client_hash_destroy_oldest, destroy_buf); - for (i = 0; i < CLIENT_DESTROY_OLDEST_COUNT; i++) { + /* then kill them */ + destroy_clients = buffer_get_data(destroy_buf, &count); + count /= sizeof(Client *); + + for (i = 0; i < count; i++) { client_destroy(destroy_clients[i], "Disconnected: Connection queue full"); } @@ -357,10 +370,11 @@ void client_syslog(Client *client, const char *text) { - char host[MAX_IP_LEN]; + const char *host; - if (net_ip2host(&client->ip, host) == -1) - host[0] = '\0'; + host = net_ip2host(&client->ip); + if (host == NULL) + host = "??"; syslog(LOG_INFO, "%s [%s]", text, host); }
--- a/src/login/master.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/login/master.c Wed Dec 18 17:15:41 2002 +0200 @@ -111,7 +111,8 @@ clients_destroy_all(); - (void)close(LOGIN_MASTER_SOCKET_FD); + if (close(LOGIN_MASTER_SOCKET_FD) < 0) + i_fatal("close(master) failed: %m"); io_remove(io_master); io_master = NULL;
--- a/src/login/ssl-proxy-gnutls.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/login/ssl-proxy-gnutls.c Wed Dec 18 17:15:41 2002 +0200 @@ -448,17 +448,11 @@ static void gcrypt_log_handler(void *context __attr_unused__, int level, const char *fmt, va_list args) { - char *buf; - - t_push(); - - buf = t_malloc(printf_string_upper_bound(fmt, args)); - vsprintf(buf, fmt, args); - - if (level == GCRY_LOG_FATAL) - i_error("gcrypt fatal: %s", buf); - - t_pop(); + if (level == GCRY_LOG_FATAL) { + t_push(); + i_error("gcrypt fatal: %s", t_strdup_vprintf(fmt, args)); + t_pop(); + } } void ssl_proxy_init(void)
--- a/src/login/ssl-proxy-openssl.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/login/ssl-proxy-openssl.c Wed Dec 18 17:15:41 2002 +0200 @@ -135,14 +135,15 @@ { unsigned long err; char *buf; + size_t err_size = 256; err = ERR_get_error(); if (err == 0) return strerror(errno); - buf = t_malloc(256); - buf[255] = '\0'; - ERR_error_string_n(err, buf, 255); + buf = t_malloc(err_size); + buf[err_size-1] = '\0'; + ERR_error_string_n(err, buf, err_size-1); return buf; }
--- a/src/master/auth-process.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/master/auth-process.c Wed Dec 18 17:15:41 2002 +0200 @@ -163,7 +163,8 @@ o_stream_unref(p->output); io_remove(p->io); - (void)close(p->fd); + if (close(p->fd) < 0) + i_error("close(auth) failed: %m"); i_free(p->name); i_free(p); } @@ -205,6 +206,7 @@ path = t_strconcat(set_login_dir, "/", config->name, NULL); (void)unlink(path); (void)umask(0177); /* we want 0600 mode for the socket */ + listen_fd = net_listen_unix(path); if (listen_fd < 0) i_fatal("Can't listen in UNIX socket %s: %m", path); @@ -212,11 +214,14 @@ i_assert(listen_fd > 2); /* set correct permissions */ - (void)chown(path, set_login_uid, set_login_gid); + if (chown(path, set_login_uid, set_login_gid) < 0) { + i_fatal("login: chown(%s, %d, %d) failed: %m", + path, (int)set_login_uid, (int)set_login_gid); + } /* move master communication handle to 0 */ if (dup2(fd[1], 0) < 0) - i_fatal("login: dup2() failed: %m"); + i_fatal("login: dup2(0) failed: %m"); (void)close(fd[0]); (void)close(fd[1]); @@ -224,9 +229,9 @@ /* set /dev/null handle into 1 and 2, so if something is printed into stdout/stderr it can't go anywhere where it could cause harm */ if (dup2(null_fd, 1) < 0) - i_fatal("login: dup2() failed: %m"); + i_fatal("login: dup2(1) failed: %m"); if (dup2(null_fd, 2) < 0) - i_fatal("login: dup2() failed: %m"); + i_fatal("login: dup2(2) failed: %m"); clean_child_process();
--- a/src/master/imap-process.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/master/imap-process.c Wed Dec 18 17:15:41 2002 +0200 @@ -109,9 +109,10 @@ const char *login_tag) { static char *argv[] = { NULL, NULL, NULL }; - char host[MAX_IP_LEN], title[1024]; + const char *host; + char title[1024]; pid_t pid; - int i, j, err; + int i, err; if (imap_process_count == set_max_imap_processes) { i_error("Maximum number of imap processes exceeded"); @@ -134,7 +135,8 @@ /* master */ imap_process_count++; PID_ADD_PROCESS_TYPE(pid, PROCESS_TYPE_IMAP); - (void)close(socket); + if (close(socket) < 0) + i_error("close(imap client) failed: %m"); return MASTER_RESULT_SUCCESS; } @@ -142,15 +144,12 @@ /* move the imap socket into stdin, stdout and stderr fds */ for (i = 0; i < 3; i++) { - if (dup2(socket, i) < 0) { - err = errno; - for (j = 0; j < i; j++) - (void)close(j); - (void)close(socket); - i_fatal("imap: dup2() failed: %m"); - } + if (dup2(socket, i) < 0) + i_fatal("imap: dup2(%d) failed: %m", i); } - (void)close(socket); + + if (close(socket) < 0) + i_error("imap: close(imap client) failed: %m"); /* setup environment - set the most important environment first (paranoia about filling up environment without noticing) */ @@ -197,7 +196,11 @@ env_put(t_strconcat("USER=", virtual_user, NULL)); env_put(t_strconcat("LOGIN_TAG=", login_tag, NULL)); - if (set_verbose_proctitle && net_ip2host(ip, host) == 0) { + if (set_verbose_proctitle) { + host = net_ip2host(ip); + if (host == NULL) + host = "??"; + i_snprintf(title, sizeof(title), "[%s %s]", virtual_user, host); argv[1] = title; }
--- a/src/master/login-process.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/master/login-process.c Wed Dec 18 17:15:41 2002 +0200 @@ -79,7 +79,8 @@ if (o_stream_send(process->output, &reply, sizeof(reply)) < 0) login_process_destroy(process); - (void)close(request->fd); + if (close(request->fd) < 0) + i_error("close(imap client) failed: %m"); login_process_unref(process); i_free(request); } @@ -212,7 +213,8 @@ o_stream_close(p->output); io_remove(p->io); - (void)close(p->fd); + if (close(p->fd) < 0) + i_error("close(login) failed: %m"); if (!p->listening) login_process_remove_from_lists(p); @@ -270,17 +272,17 @@ /* move communication handle */ if (dup2(fd[1], LOGIN_MASTER_SOCKET_FD) < 0) - i_fatal("login: dup2() failed: %m"); + i_fatal("login: dup2(master) failed: %m"); fd_close_on_exec(LOGIN_MASTER_SOCKET_FD, FALSE); /* move the listen handle */ if (dup2(imap_fd, LOGIN_IMAP_LISTEN_FD) < 0) - i_fatal("login: dup2() failed: %m"); + i_fatal("login: dup2(imap) failed: %m"); fd_close_on_exec(LOGIN_IMAP_LISTEN_FD, FALSE); /* move the SSL listen handle */ if (dup2(imaps_fd, LOGIN_IMAPS_LISTEN_FD) < 0) - i_fatal("login: dup2() failed: %m"); + i_fatal("login: dup2(imaps) failed: %m"); fd_close_on_exec(LOGIN_IMAPS_LISTEN_FD, FALSE); /* imap_fd and imaps_fd are closed by clean_child_process() */ @@ -297,10 +299,8 @@ if (!set_login_chroot) { /* no chrooting, but still change to the directory */ - if (chdir(set_login_dir) < 0) { - i_fatal("chdir(%s) failed: %m", - set_login_dir); - } + if (chdir(set_login_dir) < 0) + i_fatal("chdir(%s) failed: %m", set_login_dir); } if (!set_ssl_disable) {
--- a/src/master/main.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/master/main.c Wed Dec 18 17:15:41 2002 +0200 @@ -164,9 +164,12 @@ return ip; } + /* Return the first IP if there happens to be multiple. */ ret = net_gethostbyname(name, &ip, &ips_count); - if (ret != 0) - i_fatal("Can't resolve address: %s", name); + if (ret != 0) { + i_fatal("Can't resolve address %s: %s", + name, net_gethosterror(ret)); + } if (ips_count < 1) i_fatal("No IPs for address: %s", name); @@ -245,9 +248,12 @@ timeout_remove(to); - (void)close(null_fd); - (void)close(imap_fd); - (void)close(imaps_fd); + if (close(null_fd) < 0) + i_error("close(null_fd) failed: %m"); + if (close(imap_fd) < 0) + i_error("close(imap_fd) failed: %m"); + if (close(imaps_fd) < 0) + i_error("close(imaps_fd) failed: %m"); hash_destroy(pids); closelog();
--- a/src/master/settings.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/master/settings.c Wed Dec 18 17:15:41 2002 +0200 @@ -457,6 +457,8 @@ } linenum++; + /* @UNSAFE: line is modified */ + /* skip whitespace */ while (IS_WHITE(*line)) line++;
--- a/src/master/ssl-init.c Wed Dec 18 12:40:43 2002 +0200 +++ b/src/master/ssl-init.c Wed Dec 18 17:15:41 2002 +0200 @@ -32,7 +32,7 @@ _ssl_generate_parameters(fd, temp_fname); if (close(fd) < 0) - i_fatal("close() failed for %s: %m", temp_fname); + i_fatal("close(%s) failed: %m", temp_fname); if (rename(temp_fname, fname) < 0) i_fatal("rename(%s, %s) failed: %m", temp_fname, fname);