From: Timo Sirainen Date: Sun, 21 Sep 2003 16:21:36 +0000 (+0300) Subject: data_stack_pool split into two: unsafe_data_stack_pool which works like X-Git-Tag: 1.1.alpha1~4324 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cd466fe7b84b0223735a6469c7f7bc225f65996d;p=thirdparty%2Fdovecot%2Fcore.git data_stack_pool split into two: unsafe_data_stack_pool which works like before, and a new one which verifies that stack frame stays the same whenever the pool is accessed. --HG-- branch : HEAD --- diff --git a/src/auth/auth-master-connection.c b/src/auth/auth-master-connection.c index f5f99862f6..93359cc9fa 100644 --- a/src/auth/auth-master-connection.c +++ b/src/auth/auth-master-connection.c @@ -42,7 +42,7 @@ fill_reply(const struct user_data *user, size_t *reply_size) buffer_t *buf; char *p; - buf = buffer_create_dynamic(data_stack_pool, + buf = buffer_create_dynamic(pool_datastack_create(), sizeof(reply) + 256, (size_t)-1); memset(&reply, 0, sizeof(reply)); buffer_append(buf, &reply, sizeof(reply)); diff --git a/src/auth/mech-digest-md5.c b/src/auth/mech-digest-md5.c index f48b01e7ee..002356fb9c 100644 --- a/src/auth/mech-digest-md5.c +++ b/src/auth/mech-digest-md5.c @@ -76,7 +76,7 @@ static string_t *get_digest_challenge(struct digest_auth_request *auth) random_fill(nonce, sizeof(nonce)); t_push(); - buf = buffer_create_static(data_stack_pool, + buf = buffer_create_static(pool_datastack_create(), MAX_BASE64_ENCODED_SIZE(sizeof(nonce))+1); base64_encode(nonce, sizeof(nonce), buf); @@ -123,7 +123,7 @@ static int verify_credentials(struct digest_auth_request *auth, if (credentials == NULL || strlen(credentials) != sizeof(digest)*2) return FALSE; - digest_buf = buffer_create_data(data_stack_pool, + digest_buf = buffer_create_data(pool_datastack_create(), digest, sizeof(digest)); if (hex_to_binary(credentials, digest_buf) <= 0) return FALSE; diff --git a/src/auth/mech-plain.c b/src/auth/mech-plain.c index 1daf49fe25..cc38e54da2 100644 --- a/src/auth/mech-plain.c +++ b/src/auth/mech-plain.c @@ -35,7 +35,8 @@ mech_plain_auth_continue(struct auth_request *auth_request, else { i++; len = request->data_size - i; - pass = p_strndup(data_stack_pool, data+i, len); + pass = p_strndup(unsafe_data_stack_pool, + data+i, len); break; } } diff --git a/src/auth/mech.c b/src/auth/mech.c index 9b3d35c5af..5a8a485a9f 100644 --- a/src/auth/mech.c +++ b/src/auth/mech.c @@ -147,7 +147,7 @@ void *mech_auth_success(struct auth_client_request_reply *reply, { buffer_t *buf; - buf = buffer_create_dynamic(data_stack_pool, 256, (size_t)-1); + buf = buffer_create_dynamic(pool_datastack_create(), 256, (size_t)-1); reply->username_idx = 0; buffer_append(buf, auth_request->user, strlen(auth_request->user)+1); diff --git a/src/auth/passdb-pam.c b/src/auth/passdb-pam.c index 01d008b3f1..67991df072 100644 --- a/src/auth/passdb-pam.c +++ b/src/auth/passdb-pam.c @@ -243,7 +243,8 @@ pam_verify_plain_child(const char *service, const char *user, } } - buf = buffer_create_data(data_stack_pool, buf_data, sizeof(buf_data)); + buf = buffer_create_data(pool_datastack_create(), + buf_data, sizeof(buf_data)); buffer_append(buf, &result, sizeof(result)); if (str != NULL) { diff --git a/src/imap-login/client-authenticate.c b/src/imap-login/client-authenticate.c index 73838736c6..f285ac9acf 100644 --- a/src/imap-login/client-authenticate.c +++ b/src/imap-login/client-authenticate.c @@ -108,7 +108,8 @@ static void client_send_auth_data(struct imap_client *client, t_push(); - buf = buffer_create_dynamic(data_stack_pool, size*2, (size_t)-1); + buf = buffer_create_dynamic(pool_datastack_create(), + size*2, (size_t)-1); buffer_append(buf, "+ ", 2); base64_encode(data, size, buf); buffer_append(buf, "\r\n", 2); @@ -261,7 +262,7 @@ static void client_auth_input(void *context) } linelen = strlen(line); - buf = buffer_create_static_hard(data_stack_pool, linelen); + buf = buffer_create_static_hard(pool_datastack_create(), linelen); if (base64_decode((const unsigned char *) line, linelen, NULL, buf) <= 0) { diff --git a/src/imap-login/client.c b/src/imap-login/client.c index 838d30a91c..dc2052cb44 100644 --- a/src/imap-login/client.c +++ b/src/imap-login/client.c @@ -322,7 +322,7 @@ static void client_destroy_oldest(void) size_t i, count; /* find the oldest clients and put them to destroy-buffer */ - destroy_buf = buffer_create_static_hard(data_stack_pool, + destroy_buf = buffer_create_static_hard(pool_datastack_create(), sizeof(struct imap_client *) * CLIENT_DESTROY_OLDEST_COUNT); hash_foreach(clients, client_hash_destroy_oldest, destroy_buf); diff --git a/src/imap/cmd-append.c b/src/imap/cmd-append.c index 83990b38f6..8670bfdc8b 100644 --- a/src/imap/cmd-append.c +++ b/src/imap/cmd-append.c @@ -84,7 +84,7 @@ int cmd_append(struct client *client) return TRUE; } memset(&old_flags, 0, sizeof(old_flags)); - old_flags.pool = data_stack_pool; + old_flags.pool = pool_datastack_create(); client_save_custom_flags(&old_flags, status.custom_flags, status.custom_flags_count); diff --git a/src/imap/cmd-sort.c b/src/imap/cmd-sort.c index 937e6378b0..67c9f6e6cf 100644 --- a/src/imap/cmd-sort.c +++ b/src/imap/cmd-sort.c @@ -37,7 +37,7 @@ get_sort_program(struct client *client, struct imap_arg *args) return NULL; } - buf = buffer_create_dynamic(data_stack_pool, + buf = buffer_create_dynamic(pool_datastack_create(), 32 * sizeof(enum mail_sort_type), (size_t)-1); diff --git a/src/imap/imap-fetch-body-section.c b/src/imap/imap-fetch-body-section.c index 4a4e0ce464..dc01c544ae 100644 --- a/src/imap/imap-fetch-body-section.c +++ b/src/imap/imap-fetch-body-section.c @@ -339,7 +339,7 @@ static int fetch_header_from(struct imap_fetch_context *ctx, i_assert(hdr_ctx.dest_size <= size->virtual_size); } else { hdr_ctx.dest = - buffer_create_dynamic(data_stack_pool, + buffer_create_dynamic(pool_datastack_create(), I_MIN(size->virtual_size, 8192), (size_t)-1); if (!fetch_header_fields(input, header_section, &hdr_ctx)) diff --git a/src/imap/imap-fetch.c b/src/imap/imap-fetch.c index 4f80acb738..5d2655c305 100644 --- a/src/imap/imap-fetch.c +++ b/src/imap/imap-fetch.c @@ -365,7 +365,7 @@ int imap_fetch(struct client *client, separately rather than parsing the full header so mail storage can try to cache them. */ ctx.body_fetch_from_cache = TRUE; - buffer = buffer_create_dynamic(data_stack_pool, 64, (size_t)-1); + buffer = buffer_create_dynamic(pool_datastack_create(), 64, (size_t)-1); for (body = bodies; body != NULL; body = body->next) { if (strncmp(body->section, "HEADER.FIELDS ", 14) != 0) { ctx.body_fetch_from_cache = FALSE; diff --git a/src/imap/imap-sort.c b/src/imap/imap-sort.c index 98ffa51fbb..9f04ba54a7 100644 --- a/src/imap/imap-sort.c +++ b/src/imap/imap-sort.c @@ -203,7 +203,8 @@ int imap_sort(struct client *client, const char *charset, ctx = t_new(struct sort_context, 1); /* normalize sorting program */ - buf = buffer_create_data(data_stack_pool, norm_prog, sizeof(norm_prog)); + buf = buffer_create_data(pool_datastack_create(), + norm_prog, sizeof(norm_prog)); mail_sort_normalize(sort_program, buf); memcpy(ctx->sort_program, norm_prog, sizeof(ctx->sort_program)); @@ -284,7 +285,7 @@ static const char *get_first_mailbox(struct mail *mail, const char *field) if (str == NULL) return NULL; - addr = message_address_parse(data_stack_pool, + addr = message_address_parse(pool_datastack_create(), (const unsigned char *) str, (size_t)-1, 1); return addr != NULL ? addr->mailbox : NULL; diff --git a/src/imap/imap-thread.c b/src/imap/imap-thread.c index 8bda116024..57b8a7f51f 100644 --- a/src/imap/imap-thread.c +++ b/src/imap/imap-thread.c @@ -298,7 +298,8 @@ static const char *get_msgid(const char **msgid_p) if (found_at) { char *s; - s = p_strdup_until(data_stack_pool, msgid, p); + s = p_strdup_until(unsafe_data_stack_pool, + msgid, p); strip_lwsp(s); return s; } @@ -623,7 +624,7 @@ static void add_base_subject(struct thread_context *ctx, if (subject == NULL) return; - subject = imap_get_base_subject_cased(data_stack_pool, subject, + subject = imap_get_base_subject_cased(pool_datastack_create(), subject, &is_reply_or_forward); if (*subject == '\0') return; diff --git a/src/lib-charset/charset-utf8.c b/src/lib-charset/charset-utf8.c index 99fdb16f48..702bcd4789 100644 --- a/src/lib-charset/charset-utf8.c +++ b/src/lib-charset/charset-utf8.c @@ -22,7 +22,7 @@ const char *_charset_utf8_ucase_strdup(const unsigned char *data, size_t size, { buffer_t *dest; - dest = buffer_create_dynamic(data_stack_pool, size, (size_t)-1); + dest = buffer_create_dynamic(pool_datastack_create(), size, (size_t)-1); _charset_utf8_ucase(data, size, dest, 0); if (utf8_size_r != NULL) *utf8_size_r = buffer_get_used_size(dest); diff --git a/src/lib-imap/imap-bodystructure.c b/src/lib-imap/imap-bodystructure.c index 55a00ace2e..257f90092a 100644 --- a/src/lib-imap/imap-bodystructure.c +++ b/src/lib-imap/imap-bodystructure.c @@ -658,7 +658,8 @@ const char *imap_body_parse_from_bodystructure(const char *bodystructure) len = strlen(bodystructure); str = t_str_new(len); - input = i_stream_create_from_data(data_stack_pool, bodystructure, len); + input = i_stream_create_from_data(pool_datastack_create(), + bodystructure, len); (void)i_stream_read(input); parser = imap_parser_create(input, NULL, (size_t)-1); diff --git a/src/lib-imap/imap-envelope.c b/src/lib-imap/imap-envelope.c index fa7c2e9cf3..80bf2d9637 100644 --- a/src/lib-imap/imap-envelope.c +++ b/src/lib-imap/imap-envelope.c @@ -380,7 +380,7 @@ int imap_envelope_parse(const char *envelope, enum imap_envelope_field field, i_assert(field < IMAP_ENVELOPE_FIELDS); - input = i_stream_create_from_data(data_stack_pool, envelope, + input = i_stream_create_from_data(pool_datastack_create(), envelope, strlen(envelope)); parser = imap_parser_create(input, NULL, (size_t)-1); diff --git a/src/lib-imap/imap-quote.c b/src/lib-imap/imap-quote.c index 35a168e612..b5626b9e56 100644 --- a/src/lib-imap/imap-quote.c +++ b/src/lib-imap/imap-quote.c @@ -91,8 +91,6 @@ char *imap_quote(pool_t pool, const unsigned char *value, size_t value_len) string_t *str; char *ret; - i_assert(pool != data_stack_pool); - if (value == NULL) return "NIL"; diff --git a/src/lib-index/mail-cache.c b/src/lib-index/mail-cache.c index 41add6c328..00c85d92e0 100644 --- a/src/lib-index/mail-cache.c +++ b/src/lib-index/mail-cache.c @@ -540,7 +540,8 @@ mail_cache_compress_record(struct mail_cache *cache, int i; memset(&cache_rec, 0, sizeof(cache_rec)); - buffer = buffer_create_dynamic(data_stack_pool, 4096, (size_t)-1); + buffer = buffer_create_dynamic(pool_datastack_create(), + 4096, (size_t)-1); orig_cached_fields = mail_cache_get_fields(cache, rec); cached_fields = orig_cached_fields & ~MAIL_CACHE_HEADERS_MASK; @@ -1283,7 +1284,8 @@ int mail_cache_set_header_fields(struct mail_cache_transaction_ctx *ctx, t_push(); - buffer = buffer_create_dynamic(data_stack_pool, 512, (size_t)-1); + buffer = buffer_create_dynamic(pool_datastack_create(), + 512, (size_t)-1); while (*headers != NULL) { if (buffer_get_used_size(buffer) != 0) buffer_append(buffer, "\n", 1); diff --git a/src/lib-index/mail-modifylog.c b/src/lib-index/mail-modifylog.c index dec93093a7..57af13a44d 100644 --- a/src/lib-index/mail-modifylog.c +++ b/src/lib-index/mail-modifylog.c @@ -1109,7 +1109,8 @@ mail_modifylog_seq_get_expunges(struct mail_modify_log *log, i_assert((max_records+1) < SSIZE_T_MAX / sizeof(struct modify_log_expunge)); - buf = buffer_create_static_hard(data_stack_pool, (max_records+1) * + buf = buffer_create_static_hard(pool_datastack_create(), + (max_records+1) * sizeof(struct modify_log_expunge)); before = 0; @@ -1215,7 +1216,8 @@ mail_modifylog_uid_get_expunges(struct mail_modify_log *log, i_assert((max_records+1) < SSIZE_T_MAX / sizeof(struct modify_log_expunge)); - buf = buffer_create_static_hard(data_stack_pool, (max_records+1) * + buf = buffer_create_static_hard(pool_datastack_create(), + (max_records+1) * sizeof(struct modify_log_expunge)); before = 0; diff --git a/src/lib-index/mbox/mbox-index.c b/src/lib-index/mbox/mbox-index.c index 397f2280a2..0169020437 100644 --- a/src/lib-index/mbox/mbox-index.c +++ b/src/lib-index/mbox/mbox-index.c @@ -219,7 +219,7 @@ static void mbox_parse_imapbase(const unsigned char *value, size_t len, } /* we're at the 3rd field now, which begins the list of custom flags */ - buf = buffer_create_dynamic(data_stack_pool, + buf = buffer_create_dynamic(pool_datastack_create(), MAIL_CUSTOM_FLAGS_COUNT * sizeof(const char *), MAX_CUSTOM_FLAGS * sizeof(const char *)); diff --git a/src/lib-index/mbox/mbox-rewrite.c b/src/lib-index/mbox/mbox-rewrite.c index fc3c405dd4..23ec89d498 100644 --- a/src/lib-index/mbox/mbox-rewrite.c +++ b/src/lib-index/mbox/mbox-rewrite.c @@ -506,11 +506,12 @@ static int fd_copy(struct mail_index *index, int in_fd, int out_fd, t_push(); - input = i_stream_create_mmap(in_fd, data_stack_pool, + input = i_stream_create_mmap(in_fd, pool_datastack_create(), 1024*256, 0, 0, FALSE); i_stream_set_read_limit(input, size); - output = o_stream_create_file(out_fd, data_stack_pool, 1024, FALSE); + output = o_stream_create_file(out_fd, pool_datastack_create(), + 1024, FALSE); o_stream_set_blocking(output, 60000, NULL, NULL); ret = o_stream_send_istream(output, input); diff --git a/src/lib-mail/message-address.c b/src/lib-mail/message-address.c index 6c37e29595..4d9527c341 100644 --- a/src/lib-mail/message-address.c +++ b/src/lib-mail/message-address.c @@ -66,7 +66,7 @@ message_address_parse(pool_t pool, const unsigned char *data, size_t size, message_tokenize_skip_comments(tok, FALSE); message_tokenize_dot_token(tok, FALSE); - if (pool != data_stack_pool) + if (!pool->datastack_pool) t_push(); mailbox = t_str_new(128); domain = t_str_new(256); @@ -213,7 +213,7 @@ message_address_parse(pool_t pool, const unsigned char *data, size_t size, if (ingroup) (void)new_address(pool, &next_addr); - if (pool != data_stack_pool) + if (!pool->datastack_pool) t_pop(); message_tokenize_deinit(tok); diff --git a/src/lib-mail/message-body-search.c b/src/lib-mail/message-body-search.c index 7c6f40bd6e..1e8294e0eb 100644 --- a/src/lib-mail/message-body-search.c +++ b/src/lib-mail/message-body-search.c @@ -107,7 +107,7 @@ static int message_search_header(struct part_search_context *ctx, struct message_header_line *hdr; int found = FALSE; - hdr_search_ctx = message_header_search_init(data_stack_pool, + hdr_search_ctx = message_header_search_init(pool_datastack_create(), ctx->body_ctx->key, ctx->body_ctx->charset, NULL); @@ -214,7 +214,8 @@ static int message_search_body_block(struct part_search_context *ctx, enum charset_result result; size_t block_pos, inbuf_size, inbuf_left, ret; - outbuf = buffer_create_static(data_stack_pool, DECODE_BLOCK_SIZE); + outbuf = buffer_create_static(pool_datastack_create(), + DECODE_BLOCK_SIZE); for (block_pos = 0; block_pos < buffer_get_used_size(block); ) { if (buffer_get_used_size(ctx->decode_buf) == 0) { /* we can use the buffer directly without copying */ @@ -272,6 +273,7 @@ static int message_search_body(struct part_search_context *ctx, { const unsigned char *data; buffer_t *decodebuf; + pool_t pool; size_t data_size, pos; uoff_t old_limit; ssize_t ret; @@ -292,8 +294,8 @@ static int message_search_body(struct part_search_context *ctx, if (ctx->translation == NULL) ctx->translation = charset_to_utf8_begin("ascii", NULL); - ctx->decode_buf = buffer_create_static(data_stack_pool, 256); - ctx->match_buf = buffer_create_static_hard(data_stack_pool, + ctx->decode_buf = buffer_create_static(pool_datastack_create(), 256); + ctx->match_buf = buffer_create_static_hard(pool_datastack_create(), sizeof(size_t) * ctx->body_ctx->key_len); @@ -312,15 +314,14 @@ static int message_search_body(struct part_search_context *ctx, pos = data_size; t_push(); + pool = pool_datastack_create(); if (ctx->content_qp) { - decodebuf = buffer_create_static_hard(data_stack_pool, - data_size); + decodebuf = buffer_create_static_hard(pool, data_size); quoted_printable_decode(data, data_size, &data_size, decodebuf); } else if (ctx->content_base64) { size_t size = MAX_BASE64_DECODED_SIZE(data_size); - decodebuf = buffer_create_static_hard(data_stack_pool, - size); + decodebuf = buffer_create_static_hard(pool, size); if (base64_decode(data, data_size, &data_size, decodebuf) < 0) { @@ -330,8 +331,8 @@ static int message_search_body(struct part_search_context *ctx, break; } } else { - decodebuf = buffer_create_const_data(data_stack_pool, - data, data_size); + decodebuf = buffer_create_const_data(pool, data, + data_size); } ret = message_search_body_block(ctx, decodebuf); diff --git a/src/lib-mail/message-header-decode.c b/src/lib-mail/message-header-decode.c index c7ab1a051c..32fb6777a6 100644 --- a/src/lib-mail/message-header-decode.c +++ b/src/lib-mail/message-header-decode.c @@ -64,7 +64,8 @@ message_header_decode_encoded(const unsigned char *data, size_t *size, return TRUE; } - decodebuf = buffer_create_static_hard(data_stack_pool, text_size); + decodebuf = buffer_create_static_hard(pool_datastack_create(), + text_size); if (*encoding == 'Q') quoted_printable_decode(text, text_size, NULL, decodebuf); diff --git a/src/lib-storage/index/index-mail-headers.c b/src/lib-storage/index/index-mail-headers.c index 27f7f3bd9b..8f104e42de 100644 --- a/src/lib-storage/index/index-mail-headers.c +++ b/src/lib-storage/index/index-mail-headers.c @@ -120,7 +120,8 @@ static const char *const *sort_array(const char *const *arr) int i, already_sorted; /* copy the wanted_headers array */ - buffer = buffer_create_dynamic(data_stack_pool, 256, (size_t)-1); + buffer = buffer_create_dynamic(pool_datastack_create(), + 256, (size_t)-1); already_sorted = TRUE; for (i = 0; arr[i] != NULL; i++) { if (i > 0 && already_sorted && @@ -203,7 +204,8 @@ static const char *const *cached_header_get_names(struct index_mail *mail) data = buffer_get_modifyable_data(mail->data.headers, &size); size /= sizeof(struct cached_header *); - buffer = buffer_create_dynamic(data_stack_pool, 128, (size_t)-1); + buffer = buffer_create_dynamic(pool_datastack_create(), + 128, (size_t)-1); for (i = 0; i < size; i++) buffer_append(buffer, &data[i]->name, sizeof(const char *)); buffer_append(buffer, &null, sizeof(const char *)); @@ -423,7 +425,7 @@ static int parse_cached_headers(struct index_mail *mail, int idx) t_push(); if (idx < data->header_data_cached) { /* it's already in header_data. */ - istream = i_stream_create_from_data(data_stack_pool, + istream = i_stream_create_from_data(pool_datastack_create(), str_data(data->header_data), str_len(data->header_data)); /* we might be parsing a bit more.. */ @@ -440,7 +442,7 @@ static int parse_cached_headers(struct index_mail *mail, int idx) } data->header_data_cached_partial = TRUE; - istream = i_stream_create_from_data(data_stack_pool, + istream = i_stream_create_from_data(pool_datastack_create(), str, strlen(str)); } diff --git a/src/lib-storage/index/index-mail.c b/src/lib-storage/index/index-mail.c index 38f51e1968..682a5f116e 100644 --- a/src/lib-storage/index/index-mail.c +++ b/src/lib-storage/index/index-mail.c @@ -407,7 +407,7 @@ static int index_mail_parse_body(struct index_mail *mail) if (index_mail_cache_can_add(mail, MAIL_CACHE_MESSAGEPART)) { t_push(); - buffer = buffer_create_dynamic(data_stack_pool, + buffer = buffer_create_dynamic(pool_datastack_create(), 1024, (size_t)-1); message_part_serialize(mail->data.parts, buffer); diff --git a/src/lib-storage/index/index-search.c b/src/lib-storage/index/index-search.c index d33752b6ef..a9a012e4fa 100644 --- a/src/lib-storage/index/index-search.c +++ b/src/lib-storage/index/index-search.c @@ -423,7 +423,7 @@ static void search_header_arg(struct mail_search_arg *arg, void *context) struct message_address *addr; string_t *str; - addr = message_address_parse(data_stack_pool, + addr = message_address_parse(pool_datastack_create(), ctx->hdr->full_value, ctx->hdr->full_value_len, 0); diff --git a/src/lib-storage/index/maildir/maildir-save.c b/src/lib-storage/index/maildir/maildir-save.c index 921b3548ed..852fe718b0 100644 --- a/src/lib-storage/index/maildir/maildir-save.c +++ b/src/lib-storage/index/maildir/maildir-save.c @@ -46,7 +46,7 @@ maildir_read_into_tmp(struct index_mailbox *ibox, const char *dir, fname++; t_push(); - output = o_stream_create_file(fd, data_stack_pool, 4096, FALSE); + output = o_stream_create_file(fd, pool_datastack_create(), 4096, FALSE); o_stream_set_blocking(output, 60000, NULL, NULL); if (!mail_storage_save(ibox->box.storage, path, input, output, diff --git a/src/lib-storage/mail-search.c b/src/lib-storage/mail-search.c index b10e190458..86d56d413f 100644 --- a/src/lib-storage/mail-search.c +++ b/src/lib-storage/mail-search.c @@ -151,7 +151,8 @@ mail_search_args_analyze(struct mail_search_arg *args, *have_headers = *have_body = have_text = FALSE; - headers = buffer_create_dynamic(data_stack_pool, 128, (size_t)-1); + headers = buffer_create_dynamic(pool_datastack_create(), + 128, (size_t)-1); for (; args != NULL; args = args->next) { search_arg_analyze(args, headers, have_headers, have_body, &have_text); diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index f6307ad9a1..8313053963 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -35,6 +35,7 @@ liblib_a_SOURCES = \ mempool-alloconly.c \ mempool-datastack.c \ mempool-system.c \ + mempool-unsafe-datastack.c \ mkdir-parents.c \ mmap-anon.c \ mmap-util.c \ diff --git a/src/lib/mempool-alloconly.c b/src/lib/mempool-alloconly.c index 855eb31652..1505a3b6bb 100644 --- a/src/lib/mempool-alloconly.c +++ b/src/lib/mempool-alloconly.c @@ -57,7 +57,8 @@ static struct pool static_alloconly_pool = { pool_alloconly_clear, - TRUE + TRUE, + FALSE }; pool_t pool_alloconly_create(const char *name, size_t size) diff --git a/src/lib/mempool-datastack.c b/src/lib/mempool-datastack.c index b0ca301aaa..54b1e3fd41 100644 --- a/src/lib/mempool-datastack.c +++ b/src/lib/mempool-datastack.c @@ -27,46 +27,88 @@ static struct pool static_data_stack_pool = { pool_data_stack_clear, + TRUE, TRUE }; -pool_t data_stack_pool = &static_data_stack_pool; +struct datastack_pool { + struct pool pool; + int refcount; + + unsigned int data_stack_frame; +}; + +pool_t pool_datastack_create(void) +{ + struct datastack_pool *dpool; + + dpool = t_new(struct datastack_pool, 1); + dpool->pool = static_data_stack_pool; + dpool->refcount = 1; + dpool->data_stack_frame = data_stack_frame; + return &dpool->pool; +} static const char *pool_data_stack_get_name(pool_t pool __attr_unused__) { return "data stack"; } -static void pool_data_stack_ref(pool_t pool __attr_unused__) +static void pool_data_stack_ref(pool_t pool) { + struct datastack_pool *dpool = (struct datastack_pool *) pool; + + if (dpool->data_stack_frame != data_stack_frame) + i_panic("pool_data_stack_ref(): stack frame changed"); + + dpool->refcount++; } -static void pool_data_stack_unref(pool_t pool __attr_unused__) +static void pool_data_stack_unref(pool_t pool) { + struct datastack_pool *dpool = (struct datastack_pool *) pool; + + if (dpool->data_stack_frame != data_stack_frame) + i_panic("pool_data_stack_unref(): stack frame changed"); + + dpool->refcount--; + i_assert(dpool->refcount >= 0); } static void *pool_data_stack_malloc(pool_t pool __attr_unused__, size_t size) { + struct datastack_pool *dpool = (struct datastack_pool *) pool; + if (size == 0 || size > SSIZE_T_MAX) i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size); + if (dpool->data_stack_frame != data_stack_frame) + i_panic("pool_data_stack_malloc(): stack frame changed"); + return t_malloc0(size); } -static void pool_data_stack_free(pool_t pool __attr_unused__, - void *mem __attr_unused__) +static void pool_data_stack_free(pool_t pool, void *mem __attr_unused__) { + struct datastack_pool *dpool = (struct datastack_pool *) pool; + + if (dpool->data_stack_frame != data_stack_frame) + i_panic("pool_data_stack_free(): stack frame changed"); } -static void *pool_data_stack_realloc(pool_t pool __attr_unused__, void *mem, +static void *pool_data_stack_realloc(pool_t pool, void *mem, size_t old_size, size_t new_size) { + struct datastack_pool *dpool = (struct datastack_pool *) pool; void *new_mem; /* @UNSAFE */ if (new_size == 0 || new_size > SSIZE_T_MAX) i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size); + if (dpool->data_stack_frame != data_stack_frame) + i_panic("pool_data_stack_realloc(): stack frame changed"); + if (mem == NULL) return pool_data_stack_malloc(pool, new_size); diff --git a/src/lib/mempool-system.c b/src/lib/mempool-system.c index e528453314..3566c0a07f 100644 --- a/src/lib/mempool-system.c +++ b/src/lib/mempool-system.c @@ -29,7 +29,8 @@ static struct pool static_system_pool = { pool_system_clear, - FALSE + FALSE, + FALSE }; pool_t system_pool = &static_system_pool; diff --git a/src/lib/mempool-unsafe-datastack.c b/src/lib/mempool-unsafe-datastack.c new file mode 100644 index 0000000000..035bc6b5ca --- /dev/null +++ b/src/lib/mempool-unsafe-datastack.c @@ -0,0 +1,91 @@ +/* Copyright (c) 2002-2003 Timo Sirainen */ + +#include "lib.h" +#include "mempool.h" + +#include + +static const char *pool_unsafe_data_stack_get_name(pool_t pool); +static void pool_unsafe_data_stack_ref(pool_t pool); +static void pool_unsafe_data_stack_unref(pool_t pool); +static void *pool_unsafe_data_stack_malloc(pool_t pool, size_t size); +static void pool_unsafe_data_stack_free(pool_t pool, void *mem); +static void *pool_unsafe_data_stack_realloc(pool_t pool, void *mem, + size_t old_size, size_t new_size); +static void pool_unsafe_data_stack_clear(pool_t pool); + +static struct pool static_unsafe_data_stack_pool = { + pool_unsafe_data_stack_get_name, + + pool_unsafe_data_stack_ref, + pool_unsafe_data_stack_unref, + + pool_unsafe_data_stack_malloc, + pool_unsafe_data_stack_free, + + pool_unsafe_data_stack_realloc, + + pool_unsafe_data_stack_clear, + + TRUE, + TRUE +}; + +pool_t unsafe_data_stack_pool = &static_unsafe_data_stack_pool; + +static const char *pool_unsafe_data_stack_get_name(pool_t pool __attr_unused__) +{ + return "unsafe data stack"; +} + +static void pool_unsafe_data_stack_ref(pool_t pool __attr_unused__) +{ +} + +static void pool_unsafe_data_stack_unref(pool_t pool __attr_unused__) +{ +} + +static void *pool_unsafe_data_stack_malloc(pool_t pool __attr_unused__, + size_t size) +{ + if (size == 0 || size > SSIZE_T_MAX) + i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size); + + return t_malloc0(size); +} + +static void pool_unsafe_data_stack_free(pool_t pool __attr_unused__, + void *mem __attr_unused__) +{ +} + +static void *pool_unsafe_data_stack_realloc(pool_t pool __attr_unused__, + void *mem, + size_t old_size, size_t new_size) +{ + void *new_mem; + + /* @UNSAFE */ + if (new_size == 0 || new_size > SSIZE_T_MAX) + i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size); + + if (mem == NULL) + return pool_unsafe_data_stack_malloc(pool, new_size); + + if (old_size >= new_size) + return mem; + + if (!t_try_realloc(mem, new_size)) { + new_mem = t_malloc(new_size); + memcpy(new_mem, mem, old_size); + mem = new_mem; + } + + memset((char *) mem + old_size, 0, new_size - old_size); + return mem; +} + +static void pool_unsafe_data_stack_clear(pool_t pool __attr_unused__) +{ +} diff --git a/src/lib/mempool.h b/src/lib/mempool.h index 53c84bc339..03f0856ae8 100644 --- a/src/lib/mempool.h +++ b/src/lib/mempool.h @@ -29,18 +29,25 @@ struct pool { void (*clear)(pool_t pool); unsigned int alloconly_pool:1; + unsigned int datastack_pool:1; }; /* system_pool uses calloc() + realloc() + free() */ extern pool_t system_pool; -/* memory allocated from data_stack is valid only until next t_pop() call. */ -extern pool_t data_stack_pool; +/* memory allocated from data_stack is valid only until next t_pop() call. + No checks are performed. */ +extern pool_t unsafe_data_stack_pool; /* Create a new alloc-only pool. Note that `size' specifies the initial malloc()ed block size, part of it is used internally. */ pool_t pool_alloconly_create(const char *name, size_t size); +/* When allocating memory from returned pool, the data stack frame must be + the same as it was when calling this function. pool_unref() also checks + that the stack frame is the same. This should make it quite safe to use. */ +pool_t pool_datastack_create(void); + /* Pools should be used through these macros: */ #define pool_get_name(pool) (pool)->get_name(pool) #define pool_ref(pool) (pool)->ref(pool) diff --git a/src/lib/str.c b/src/lib/str.c index a5e16ce51f..b5d6e9fb24 100644 --- a/src/lib/str.c +++ b/src/lib/str.c @@ -14,7 +14,7 @@ string_t *str_new(pool_t pool, size_t initial_size) string_t *t_str_new(size_t initial_size) { - return str_new(data_stack_pool, initial_size); + return str_new(pool_datastack_create(), initial_size); } void str_free(string_t *str) diff --git a/src/lib/strfuncs.c b/src/lib/strfuncs.c index 357f93e01e..5d4140156f 100644 --- a/src/lib/strfuncs.c +++ b/src/lib/strfuncs.c @@ -197,7 +197,7 @@ char *p_strdup_vprintf(pool_t pool, const char *format, va_list args) i_assert(format != NULL); - if (pool != data_stack_pool) + if (!pool->datastack_pool) t_push(); VA_COPY(args2, args); @@ -210,7 +210,7 @@ char *p_strdup_vprintf(pool_t pool, const char *format, va_list args) #else vsprintf(ret, format, args2); #endif - if (pool != data_stack_pool) + if (!pool->datastack_pool) t_pop(); return ret; } @@ -277,27 +277,27 @@ char *p_strconcat(pool_t pool, const char *str1, ...) const char *t_strdup(const char *str) { - return p_strdup(data_stack_pool, str); + return p_strdup(unsafe_data_stack_pool, str); } char *t_strdup_noconst(const char *str) { - return p_strdup(data_stack_pool, str); + return p_strdup(unsafe_data_stack_pool, str); } const char *t_strdup_empty(const char *str) { - return p_strdup_empty(data_stack_pool, str); + return p_strdup_empty(unsafe_data_stack_pool, str); } const char *t_strdup_until(const void *start, const void *end) { - return p_strdup_until(data_stack_pool, start, end); + return p_strdup_until(unsafe_data_stack_pool, start, end); } const char *t_strndup(const void *str, size_t max_chars) { - return p_strndup(data_stack_pool, str, max_chars); + return p_strndup(unsafe_data_stack_pool, str, max_chars); } const char *t_strdup_printf(const char *format, ...) @@ -306,7 +306,7 @@ const char *t_strdup_printf(const char *format, ...) const char *ret; va_start(args, format); - ret = p_strdup_vprintf(data_stack_pool, format, args); + ret = p_strdup_vprintf(unsafe_data_stack_pool, format, args); va_end(args); return ret; @@ -314,7 +314,7 @@ const char *t_strdup_printf(const char *format, ...) const char *t_strdup_vprintf(const char *format, va_list args) { - return p_strdup_vprintf(data_stack_pool, format, args); + return p_strdup_vprintf(unsafe_data_stack_pool, format, args); } const char *t_strconcat(const char *str1, ...) diff --git a/src/pop3-login/client-authenticate.c b/src/pop3-login/client-authenticate.c index dadebd158c..ca7f849a2e 100644 --- a/src/pop3-login/client-authenticate.c +++ b/src/pop3-login/client-authenticate.c @@ -111,7 +111,8 @@ static void client_send_auth_data(struct pop3_client *client, t_push(); - buf = buffer_create_dynamic(data_stack_pool, size*2, (size_t)-1); + buf = buffer_create_dynamic(pool_datastack_create(), + size*2, (size_t)-1); buffer_append(buf, "+ ", 2); base64_encode(data, size, buf); buffer_append(buf, "\r\n", 2); @@ -250,7 +251,7 @@ static void client_auth_input(void *context) } linelen = strlen(line); - buf = buffer_create_static_hard(data_stack_pool, linelen); + buf = buffer_create_static_hard(pool_datastack_create(), linelen); if (base64_decode((const unsigned char *) line, linelen, NULL, buf) <= 0) { diff --git a/src/pop3-login/client.c b/src/pop3-login/client.c index 5e7a8d8650..568babe199 100644 --- a/src/pop3-login/client.c +++ b/src/pop3-login/client.c @@ -217,7 +217,7 @@ static void client_destroy_oldest(void) size_t i, count; /* find the oldest clients and put them to destroy-buffer */ - destroy_buf = buffer_create_static_hard(data_stack_pool, + destroy_buf = buffer_create_static_hard(pool_datastack_create(), sizeof(struct pop3_client *) * CLIENT_DESTROY_OLDEST_COUNT); hash_foreach(clients, client_hash_destroy_oldest, destroy_buf);