From d4ead7075692a4abdc487fcb422cb9fd5b41a596 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Tue, 22 Apr 2014 15:22:38 +0300 Subject: [PATCH] Static analyzer bug fixes Bunch of small bugs fixed here and there found during static analysis. --- .cvsignore => .gitignore | 18 ++ apps/irssi/src/silc/core/client_ops.c | 2 +- apps/irssi/src/silc/core/silc-channels.c | 2 + apps/irssi/src/silc/core/silc-queries.c | 6 +- apps/irssi/src/silc/core/silc-servers.c | 11 +- apps/silcd/command.c | 56 +++-- apps/silcd/command_reply.c | 12 +- apps/silcd/idlist.c | 12 ++ apps/silcd/packet_receive.c | 19 +- apps/silcd/packet_send.c | 9 + apps/silcd/server.c | 32 ++- apps/silcd/server.h | 2 +- apps/silcd/server_backup.c | 33 ++- apps/silcd/server_query.c | 6 + apps/silcd/serverid.c | 4 + lib/contrib/nfkc.c | 3 + lib/silcasn1/silcasn1.c | 2 +- lib/silcasn1/silcasn1_decode.c | 2 +- lib/silcasn1/silcasn1_encode.c | 2 +- lib/silcclient/client.c | 8 +- lib/silcclient/client_entry.c | 9 +- lib/silcclient/client_notify.c | 2 +- lib/silcclient/client_prvmsg.c | 3 +- lib/silcclient/client_register.c | 2 +- lib/silcclient/command_reply.c | 2 +- lib/silccore/silcargument.c | 2 - lib/silccore/silcattrs.c | 9 +- lib/silccore/silcpacket.c | 2 +- lib/silccrypt/aes.c | 18 +- lib/silccrypt/silccipher.c | 3 +- lib/silccrypt/silchash.c | 3 +- lib/silccrypt/silchmac.c | 3 +- lib/silccrypt/silcpkcs.c | 3 +- lib/silccrypt/silcpkcs1.c | 20 +- lib/silccrypt/silcrng.c | 18 +- lib/silccrypt/twofish.c | 2 +- lib/silchttp/silchttpserver.c | 3 + lib/silcmath/mp_gmp.c | 3 +- lib/silcmath/mp_tfm.c | 3 +- lib/silcmath/mp_tma.c | 3 +- lib/silcmath/silcmp.h | 2 +- lib/silcmath/tma.c | 5 + lib/silcsftp/sftp_fs_memory.c | 2 + lib/silcske/groups.c | 3 +- lib/silcske/silcske.c | 257 ++++++++++++++++++----- lib/silcutil/silcmime.c | 3 + lib/silcutil/silcnet.c | 54 +++-- lib/silcutil/silcschedule.c | 9 +- 48 files changed, 529 insertions(+), 160 deletions(-) rename .cvsignore => .gitignore (70%) diff --git a/.cvsignore b/.gitignore similarity index 70% rename from .cvsignore rename to .gitignore index b79d574a..681191bc 100644 --- a/.cvsignore +++ b/.gitignore @@ -24,3 +24,21 @@ ltconfig ltmain.sh stamp-h stamp-h.in +silcdefs.h +silcdefs.h.in +*.o +*.a +*.la +*.Plo +*.Po +.exists +*.so +*.pm +*.lo +*.lai +*.bs +*.pc +apps/irssi/docs/help +*draft*.txt +configure.ac +stamp-h1 diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index a4d53b76..d73c7bee 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -946,7 +946,7 @@ void silc_notify(SilcClient client, SilcClientConnection conn, tmp = cp; } - chanrec->topic = *tmp == '\0' ? NULL : g_strdup(tmp); + chanrec->topic = (tmp && *tmp == '\0' ? NULL : g_strdup(tmp)); signal_emit("channel topic changed", 1, chanrec); silc_free(dm); diff --git a/apps/irssi/src/silc/core/silc-channels.c b/apps/irssi/src/silc/core/silc-channels.c index 055c6d72..b70968f7 100644 --- a/apps/irssi/src/silc/core/silc-channels.c +++ b/apps/irssi/src/silc/core/silc-channels.c @@ -170,6 +170,8 @@ static void sig_silc_channel_joined(SILC_CHANNEL_REC *channel) return; if (channel->server && channel->server->disconnected) return; + if (!channel->server) + return; if (channel->session_rejoin) return; diff --git a/apps/irssi/src/silc/core/silc-queries.c b/apps/irssi/src/silc/core/silc-queries.c index ec29a2f3..18ddf04d 100644 --- a/apps/irssi/src/silc/core/silc-queries.c +++ b/apps/irssi/src/silc/core/silc-queries.c @@ -366,7 +366,8 @@ void silc_query_attributes_default(SilcClient client, mask |= SILC_ATTRIBUTE_MOOD_ANXIOUS; } silc_client_attribute_add(silc_client, conn, - SILC_ATTRIBUTE_STATUS_MOOD, (void *)mask, + SILC_ATTRIBUTE_STATUS_MOOD, + SILC_32_TO_PTR(mask), sizeof(SilcUInt32)); g_strfreev(list); } @@ -437,7 +438,8 @@ void silc_query_attributes_default(SilcClient client, mask |= SILC_ATTRIBUTE_CONTACT_VIDEO; } silc_client_attribute_add(silc_client, conn, - SILC_ATTRIBUTE_PREFERRED_CONTACT, (void *)mask, + SILC_ATTRIBUTE_PREFERRED_CONTACT, + SILC_32_TO_PTR(mask), sizeof(SilcUInt32)); g_strfreev(list); } diff --git a/apps/irssi/src/silc/core/silc-servers.c b/apps/irssi/src/silc/core/silc-servers.c index 9dd1c8e2..4b18e371 100644 --- a/apps/irssi/src/silc/core/silc-servers.c +++ b/apps/irssi/src/silc/core/silc-servers.c @@ -645,7 +645,7 @@ static void command_smsg(const char *data, SILC_SERVER_REC *server, { GHashTable *optlist; char *target, *origtarget, *msg; - void *free_arg; + void *free_arg = NULL; int free_ret, target_type; g_return_if_fail(data != NULL); @@ -714,8 +714,10 @@ static void command_smsg(const char *data, SILC_SERVER_REC *server, "message signed_own_public" : "message signed_own_private", 4, server, msg, target, origtarget); out: - if (free_ret && target != NULL) g_free(target); - cmd_params_free(free_arg); + if (free_ret && target != NULL) + g_free(target); + if (free_arg) + cmd_params_free(free_arg); } /* FILE command */ @@ -749,7 +751,8 @@ static void silc_client_file_monitor(SilcClient client, if (status == SILC_CLIENT_FILE_MONITOR_CLOSED) return; - snprintf(fsize, sizeof(fsize) - 1, "%llu", ((filesize + 1023) / 1024)); + snprintf(fsize, sizeof(fsize) - 1, "%llu", + (unsigned long long)((filesize + 1023) / 1024)); silc_dlist_start(server->ftp_sessions); while ((ftp = silc_dlist_get(server->ftp_sessions)) != SILC_LIST_END) { diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 9439f488..213e8fee 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2009 Pekka Riikonen + Copyright (C) 1997 - 2014 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -209,6 +209,8 @@ void silc_server_command_process(SilcServer server, /* Allocate command context. This must be free'd by the command routine receiving it. */ ctx = silc_server_command_alloc(); + if (!ctx) + return; ctx->server = server; ctx->sock = sock; ctx->packet = packet; /* Save original packet */ @@ -252,6 +254,15 @@ void silc_server_command_process(SilcServer server, int fast; timeout = silc_calloc(1, sizeof(*timeout)); + if (!timeout) { + silc_server_command_send_status_reply( + ctx, command, + SILC_STATUS_ERR_OPERATION_ALLOWED, 0); + silc_packet_free(packet); + silc_packet_stream_unref(ctx->sock); + silc_free(ctx); + return; + } timeout->ctx = ctx; timeout->cmd = cmd; @@ -300,7 +311,8 @@ void silc_server_command_process(SilcServer server, SilcServerCommandContext silc_server_command_alloc() { SilcServerCommandContext ctx = silc_calloc(1, sizeof(*ctx)); - ctx->users++; + if (ctx) + ctx->users++; return ctx; } @@ -349,6 +361,8 @@ SILC_TASK_CALLBACK(silc_server_command_pending_timeout) /* Allocate temporary and bogus command reply context */ cmdr = silc_calloc(1, sizeof(*cmdr)); + if (!cmdr) + return; cmdr->server = server; cmdr->ident = reply->ident; @@ -356,6 +370,10 @@ SILC_TASK_CALLBACK(silc_server_command_pending_timeout) cmdr->callbacks = silc_server_command_pending_check(server, reply->reply_cmd, reply->ident, &cmdr->callbacks_count); + if (!cmdr->callbacks) { + silc_free(cmdr); + return; + } /* Create bogus command reply with an error inside */ tmpreply = @@ -399,11 +417,11 @@ SilcBool silc_server_command_pending(SilcServer server, commands. If the `timeout' is zero default timeout is used. */ SilcBool silc_server_command_pending_timed(SilcServer server, - SilcCommand reply_cmd, - SilcUInt16 ident, - SilcCommandCb callback, - void *context, - SilcUInt16 timeout) + SilcCommand reply_cmd, + SilcUInt16 ident, + SilcCommandCb callback, + void *context, + SilcUInt16 timeout) { SilcServerCommandPending *reply; @@ -418,6 +436,8 @@ SilcBool silc_server_command_pending_timed(SilcServer server, } reply = silc_calloc(1, sizeof(*reply)); + if (!reply) + return FALSE; reply->reply_cmd = reply_cmd; reply->ident = ident; reply->context = context; @@ -453,7 +473,8 @@ void silc_server_command_pending_del(SilcServer server, } /* Checks for pending commands and marks callbacks to be called from - the command reply function. Returns TRUE if there were pending command. */ + the command reply function. Returns the pending callbacks if there were + any or NULL if there weren't. */ SilcServerCommandPendingCallbacks silc_server_command_pending_check(SilcServer server, @@ -470,6 +491,8 @@ silc_server_command_pending_check(SilcServer server, if ((r->reply_cmd == command || r->reply_cmd == SILC_COMMAND_NONE) && r->ident == ident) { callbacks = silc_realloc(callbacks, sizeof(*callbacks) * (i + 1)); + if (!callbacks) + return NULL; callbacks[i].context = r->context; callbacks[i].callback = r->callback; r->reply_check = TRUE; @@ -1365,6 +1388,8 @@ SILC_SERVER_CMD_FUNC(quit) tmp = NULL; q = silc_calloc(1, sizeof(*q)); + if (!q) + goto out; q->sock = sock; q->signoff = tmp ? strdup(tmp) : NULL; silc_packet_stream_ref(q->sock); @@ -2112,6 +2137,8 @@ static void silc_server_command_join_channel(SilcServer server, Add also the channel to client entry's channels list for fast cross- referencing. */ chl = silc_calloc(1, sizeof(*chl)); + if (!chl) + goto out; chl->mode = umode; chl->client = client; chl->channel = channel; @@ -2439,7 +2466,6 @@ SILC_SERVER_CMD_FUNC(join) 0); goto out; } - tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len); /* Get cipher, hmac name and auth payload */ cipher = silc_argument_get_arg_type(cmd->args, 4, NULL); @@ -3239,7 +3265,8 @@ SILC_SERVER_CMD_FUNC(cmode) silc_server_command_send_status_data( cmd, SILC_COMMAND_CMODE, SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0, - 2, hmac, strlen(hmac)); + 2, hmac ? hmac : SILC_DEFAULT_HMAC, + strlen(hmac ? hmac : SILC_DEFAULT_HMAC)); goto out; } @@ -4073,7 +4100,7 @@ SILC_TASK_CALLBACK(silc_server_command_detach_cb) QuitInternal q = (QuitInternal)context; SilcPacketStream sock = q->sock; SilcClientEntry client = silc_packet_get_context(sock); - SilcIDListData idata = (SilcIDListData)client; + SilcIDListData idata; if (!client) { silc_packet_stream_unref(sock); @@ -4178,6 +4205,8 @@ SILC_SERVER_CMD_FUNC(detach) SILC_NOTIFY_TYPE_UMODE_CHANGE); q = silc_calloc(1, sizeof(*q)); + if (!q) + goto out; q->sock = cmd->sock; silc_packet_stream_ref(q->sock); silc_schedule_task_add_timeout(server->schedule, @@ -4186,6 +4215,8 @@ SILC_SERVER_CMD_FUNC(detach) if (server->config->detach_timeout) { q = silc_calloc(1, sizeof(*q)); + if (!q) + goto out; q->sock = (void *)silc_id_dup(client->id, SILC_ID_CLIENT); silc_schedule_task_add_timeout(server->schedule, silc_server_command_detach_timeout, @@ -5214,7 +5245,6 @@ SILC_SERVER_CMD_FUNC(service) SilcServer server = cmd->server; SilcUInt32 tmp_len, auth_len; unsigned char *service_name, *auth; - SilcBool send_list = FALSE; SilcUInt16 ident = silc_command_get_ident(cmd->payload); SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SERVICE, cmd, 0, 256); @@ -5239,8 +5269,6 @@ SILC_SERVER_CMD_FUNC(service) } - send_list = TRUE; - /* Send our service list back */ silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_SERVICE, SILC_STATUS_OK, 0, ident, 0); diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index bb32bb2b..41bec7f0 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -386,9 +386,12 @@ silc_server_command_reply_whois_save_client(SilcServerCommandReplyContext cmd) SilcUInt32 len; SilcClientEntry client = silc_packet_get_context(cmd->sock); + if (!client) + return FALSE; + /* Take Requested Attributes if set. */ tmp = silc_argument_get_arg_type(cmd->args, 11, &len); - if (tmp && client) { + if (tmp) { silc_free(client->attrs); client->attrs = silc_memdup(tmp, len); client->attrs_len = len; @@ -619,6 +622,8 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) if (!idp) return FALSE; + memset(nick, 0, sizeof(nick)); + name = silc_argument_get_arg_type(cmd->args, 3, &len); info = silc_argument_get_arg_type(cmd->args, 4, &len); @@ -1443,7 +1448,6 @@ SILC_SERVER_CMD_REPLY_FUNC(list) SilcIDCacheEntry cache; unsigned char *tmp, *name, *namec = NULL, *topic; SilcUInt32 usercount = 0; - SilcBool global_list = FALSE; COMMAND_CHECK_STATUS; @@ -1464,11 +1468,9 @@ SILC_SERVER_CMD_REPLY_FUNC(list) /* Add the channel entry if we do not have it already */ channel = silc_idlist_find_channel_by_name(server->local_list, namec, &cache); - if (!channel) { + if (!channel) channel = silc_idlist_find_channel_by_name(server->global_list, namec, &cache); - global_list = TRUE; - } if (!channel) { /* If router did not find such channel in its lists then this must be bogus channel or some router in the net is buggy. */ diff --git a/apps/silcd/idlist.c b/apps/silcd/idlist.c index 13093c09..5eb063e5 100644 --- a/apps/silcd/idlist.c +++ b/apps/silcd/idlist.c @@ -94,6 +94,10 @@ silc_idlist_add_server(SilcIDList id_list, } server = silc_calloc(1, sizeof(*server)); + if (!server) { + silc_free(server_namec); + return NULL; + } server->server_name = server_name; server->server_type = server_type; server->id = id; @@ -615,6 +619,10 @@ silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode, } channel = silc_calloc(1, sizeof(*channel)); + if (!channel) { + silc_free(channel_namec); + return NULL; + } channel->channel_name = channel_name; channel->mode = mode; channel->id = id; @@ -840,6 +848,8 @@ silc_idlist_get_channels(SilcIDList id_list, SilcChannelID *channel_id, return NULL; channels = silc_calloc(silc_list_count(list), sizeof(*channels)); + if (!channels) + return NULL; i = 0; silc_list_start(list); @@ -851,6 +861,8 @@ silc_idlist_get_channels(SilcIDList id_list, SilcChannelID *channel_id, i = 1; channels = silc_calloc(1, sizeof(*channels)); + if (!channels) + return NULL; channels[0] = (SilcChannelEntry)id_cache->context; } diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index f2a82212..56435eb6 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -1677,7 +1677,7 @@ static void silc_server_notify_process(SilcServer server, SilcStatus error; tmp = silc_argument_get_arg_type(args, 1, &tmp_len); - if (!tmp && tmp_len != 1) + if (!tmp || tmp_len != 1) goto out; error = (SilcStatus)tmp[0]; @@ -2263,6 +2263,16 @@ SilcClientEntry silc_server_new_client(SilcServer server, char *newusername; newusername = silc_calloc(strlen(username) + strlen(hostname) + 2, sizeof(*newusername)); + if (!newusername) { + silc_free(username); + silc_free(realname); + silc_free(nickname); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_OPERATION_ALLOWED, NULL); + silc_server_free_sock_user_data(server, sock, NULL); + silc_packet_free(packet); + return NULL; + } strncat(newusername, username, strlen(username)); strncat(newusername, "@", 1); strncat(newusername, hostname, strlen(hostname)); @@ -2276,6 +2286,9 @@ SilcClientEntry silc_server_new_client(SilcServer server, if (!silc_id_create_client_id(server, server->id, server->rng, server->md5hash, nicknamec, strlen(nicknamec), &client_id)) { + silc_free(username); + silc_free(realname); + silc_free(nickname); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_BAD_NICKNAME, NULL); silc_server_free_sock_user_data(server, sock, NULL); @@ -2915,7 +2928,7 @@ static void silc_server_new_channel_process(SilcServer server, SilcChannelID channel_id; char *channel_name, *channel_namec = NULL; SilcUInt32 name_len; - unsigned char *id, cid[32]; + unsigned char cid[32]; SilcUInt32 id_len, cipher_len; SilcServerEntry server_entry; SilcChannelEntry channel; @@ -2949,8 +2962,6 @@ static void silc_server_new_channel_process(SilcServer server, if (!channel_namec) return; - id = silc_channel_get_id(payload, &id_len); - server_entry = (SilcServerEntry)idata; if (idata->conn_type == SILC_CONN_ROUTER) { diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 9e6fa133..2caacd2b 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -319,6 +319,8 @@ void silc_server_packet_send_to_channel(SilcServer server, routed = silc_calloc(silc_hash_table_count(channel->user_list), sizeof(*routed)); + if (!routed) + goto out; /* Send the message to clients on the channel's client list. */ silc_hash_table_list(channel->user_list, &htl); @@ -528,8 +530,15 @@ void silc_server_packet_relay_to_channel(SilcServer server, } } + if (!silc_hash_table_count(channel->user_list)) { + SILC_LOG_DEBUG(("Channel %s is empty", channel->channel_name)); + return; + } + routed = silc_calloc(silc_hash_table_count(channel->user_list), sizeof(*routed)); + if (!routed) + return; /* Assure we won't route the message back to the sender's way. */ if (sender_entry->router) diff --git a/apps/silcd/server.c b/apps/silcd/server.c index a1c9fa13..4712bb2d 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -53,7 +53,7 @@ silc_server_verify_key(SilcSKE ske, SILC_LOG_DEBUG(("Verifying public key")); - if (silc_pkcs_get_type(public_key) != SILC_SKE_PK_TYPE_SILC) { + if (silc_pkcs_get_type(public_key) != SILC_PKCS_SILC) { SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d", entry->hostname, entry->ip, entry->port, silc_pkcs_get_type(public_key))); @@ -2403,8 +2403,6 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, SilcBool initiator = FALSE; SilcBool backup_local = FALSE; SilcBool backup_router = FALSE; - char *backup_replace_ip = NULL; - SilcUInt16 backup_replace_port = 0; SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr; SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr; @@ -2461,8 +2459,6 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, initiator = rconn->initiator; backup_local = rconn->backup_local; backup_router = rconn->backup_router; - backup_replace_ip = rconn->backup_replace_ip; - backup_replace_port = rconn->backup_replace_port; } } @@ -4016,6 +4012,14 @@ SilcBool silc_server_create_channel_key(SilcServer server, if (server->server_type == SILC_ROUTER) { if (!channel->rekey) channel->rekey = silc_calloc(1, sizeof(*channel->rekey)); + if (!channel->rekey) { + memset(channel->key, 0, channel->key_len / 8); + silc_free(channel->key); + silc_cipher_free(channel->send_key); + silc_cipher_free(channel->receive_key); + channel->send_key = channel->receive_key = NULL; + return FALSE; + } channel->rekey->channel = channel; channel->rekey->key_len = key_len; if (channel->rekey->task) @@ -4129,7 +4133,7 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, silc_cipher_free(channel->send_key); silc_cipher_free(channel->receive_key); channel->send_key = channel->receive_key = NULL; - return FALSE; + return NULL; } silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash); silc_hmac_set_key(channel->hmac, hash, @@ -4141,6 +4145,14 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, if (server->server_type == SILC_ROUTER) { if (!channel->rekey) channel->rekey = silc_calloc(1, sizeof(*channel->rekey)); + if (!channel->rekey) { + memset(channel->key, 0, channel->key_len / 8); + silc_free(channel->key); + silc_cipher_free(channel->send_key); + silc_cipher_free(channel->receive_key); + channel->send_key = channel->receive_key = NULL; + return NULL; + } channel->rekey->channel = channel; if (channel->rekey->task) silc_schedule_task_del(server->schedule, channel->rekey->task); @@ -5095,6 +5107,8 @@ void silc_server_save_users_on_channel(SilcServer server, if (!silc_server_client_on_channel(client, channel, &chl)) { /* Client was not on the channel, add it. */ chl = silc_calloc(1, sizeof(*chl)); + if (!chl) + continue; chl->client = client; chl->mode = mode; chl->channel = channel; @@ -5173,6 +5187,8 @@ void silc_server_save_user_channels(SilcServer server, /* Add the client on the channel */ if (!silc_server_client_on_channel(client, channel, &chl)) { chl = silc_calloc(1, sizeof(*chl)); + if (!chl) + continue; chl->client = client; chl->mode = chumodes[i++]; chl->channel = channel; @@ -5338,6 +5354,8 @@ SilcBuffer silc_server_get_client_channel_list(SilcServer server, buffer = silc_buffer_realloc(buffer, (buffer ? silc_buffer_truelen(buffer) + len : len)); + if (!buffer) + return NULL; silc_buffer_pull_tail(buffer, (buffer->end - buffer->data)); silc_buffer_format(buffer, SILC_STR_UI_SHORT(name_len), @@ -5353,6 +5371,8 @@ SilcBuffer silc_server_get_client_channel_list(SilcServer server, silc_buffer_realloc(*user_mode_list, (*user_mode_list ? silc_buffer_truelen((*user_mode_list)) + 4 : 4)); + if (!(*user_mode_list)) + return NULL; silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end - (*user_mode_list)->data)); SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data); diff --git a/apps/silcd/server.h b/apps/silcd/server.h index ddefcc4d..98e9be51 100644 --- a/apps/silcd/server.h +++ b/apps/silcd/server.h @@ -161,7 +161,7 @@ void silc_server_remove_from_channels(SilcServer server, SilcClientEntry client, SilcBool notify, const char *signoff_message, - SilcBool keygen, bool killed); + SilcBool keygen, SilcBool killed); SilcBool silc_server_remove_from_one_channel(SilcServer server, SilcPacketStream sock, SilcChannelEntry channel, diff --git a/apps/silcd/server_backup.c b/apps/silcd/server_backup.c index 8f5140c1..4ae58843 100644 --- a/apps/silcd/server_backup.c +++ b/apps/silcd/server_backup.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2001 - 2007 Pekka Riikonen + Copyright (C) 2001 - 2014 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -219,13 +219,19 @@ void silc_server_backup_replaced_add(SilcServer server, int i; SilcServerBackupReplaced *r = silc_calloc(1, sizeof(*r));; + if (!r) + return; if (!server->backup) server->backup = silc_calloc(1, sizeof(*server->backup)); + if (!server->backup) + return; if (!server->backup->replaced) { server->backup->replaced = silc_calloc(1, sizeof(*server->backup->replaced)); server->backup->replaced_count = 1; } + if (!server->backup->replaced) + return; SILC_LOG_DEBUG(("Replacing router %s with %s", silc_id_render(server_id, SILC_ID_SERVER), @@ -354,7 +360,6 @@ void silc_server_backup_send(SilcServer server, SilcBool local) { SilcServerEntry backup; - SilcPacketStream sock; int i; if (!server->backup || server->server_type != SILC_ROUTER) @@ -369,8 +374,6 @@ void silc_server_backup_send(SilcServer server, if (server->backup->servers[i].server == server->id_entry) continue; - sock = backup->connection; - silc_server_packet_send(server, backup->connection, type, flags, data, data_len); } @@ -393,7 +396,6 @@ void silc_server_backup_send_dest(SilcServer server, SilcBool local) { SilcServerEntry backup; - SilcPacketStream sock; int i; if (!server->backup || server->server_type != SILC_ROUTER) @@ -408,8 +410,6 @@ void silc_server_backup_send_dest(SilcServer server, if (server->backup->servers[i].server == server->id_entry) continue; - sock = backup->connection; - silc_server_packet_send_dest(server, backup->connection, type, flags, dst_id, dst_id_type, data, data_len); } @@ -637,6 +637,11 @@ void silc_server_backup_resume_router(SilcServer server, /* Reprocess this packet after received reply from router */ pc = silc_calloc(1, sizeof(*pc)); + if (!pc) { + silc_server_backup_send_start_use(server, sock, FALSE); + silc_packet_free(packet); + return; + } pc->server = server; pc->sock = sock; pc->packet = packet; @@ -652,12 +657,12 @@ void silc_server_backup_resume_router(SilcServer server, /* We have received a start for resuming protocol. We are either primary router that came back online or normal server. */ SilcServerBackupProtocolContext proto_ctx; + unsigned char data[4]; /* If backup had closed the connection earlier we won't allow resuming since we (primary router) have never gone away. */ if (server->server_type == SILC_ROUTER && !server->backup_router && server->backup_closed) { - unsigned char data[4]; SILC_LOG_DEBUG(("Backup resuming not allowed since we are still " "primary router")); SILC_LOG_INFO(("Backup resuming not allowed since we are still " @@ -671,6 +676,14 @@ void silc_server_backup_resume_router(SilcServer server, } proto_ctx = silc_calloc(1, sizeof(*proto_ctx)); + if (!proto_ctx) { + SILC_PUT32_MSB(SILC_SERVER_BACKUP_START, data); + silc_server_packet_send(server, sock, SILC_PACKET_FAILURE, 0, + data, 4); + server->backup_closed = FALSE; + silc_packet_free(packet); + return; + } proto_ctx->server = server; proto_ctx->sock = sock; proto_ctx->responder = TRUE; @@ -824,6 +837,8 @@ void silc_server_backup_connected(SilcServer server, sock = server_entry->connection; proto_ctx = silc_calloc(1, sizeof(*proto_ctx)); + if (!proto_ctx) + return; proto_ctx->server = server; proto_ctx->sock = sock; proto_ctx->responder = FALSE; @@ -1367,6 +1382,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) /* Restart the protocol. */ proto_ctx = silc_calloc(1, sizeof(*proto_ctx)); + if (!proto_ctx) + continue; proto_ctx->server = server; proto_ctx->sock = sock; proto_ctx->responder = FALSE; diff --git a/apps/silcd/server_query.c b/apps/silcd/server_query.c index 28dd15ec..5cc2decf 100644 --- a/apps/silcd/server_query.c +++ b/apps/silcd/server_query.c @@ -238,6 +238,8 @@ SilcBool silc_server_query_command(SilcServer server, if (!old_query) { query = silc_calloc(1, sizeof(*query)); + if (!query) + return FALSE; query->querycmd = querycmd; query->cmd = silc_server_command_dup(cmd); query->router = SILC_PRIMARY_ROUTE(server); @@ -508,6 +510,8 @@ SilcBool silc_server_query_parse(SilcServer server, SilcServerQuery query, } else { /* Parse the IDs included in the query */ query->ids = silc_calloc(argc, sizeof(*query->ids)); + if (!query->ids) + return FALSE; for (i = 0; i < argc; i++) { tmp = silc_argument_get_arg_type(cmd->args, i + 4, &tmp_len); @@ -663,6 +667,8 @@ SilcBool silc_server_query_parse(SilcServer server, SilcServerQuery query, } else { /* Parse the IDs included in the query */ query->ids = silc_calloc(argc, sizeof(*query->ids)); + if (!query->ids) + return FALSE; for (i = 0; i < argc; i++) { tmp = silc_argument_get_arg_type(cmd->args, i + 5, &tmp_len); diff --git a/apps/silcd/serverid.c b/apps/silcd/serverid.c index 73641c65..c820967d 100644 --- a/apps/silcd/serverid.c +++ b/apps/silcd/serverid.c @@ -66,6 +66,8 @@ SilcBool silc_id_create_client_id(SilcServer server, SILC_LOG_DEBUG(("Creating new Client ID")); *new_id = silc_calloc(1, sizeof(**new_id)); + if (!(*new_id)) + return FALSE; /* Create hash of the nickname (it's already checked as valid identifier string). */ @@ -116,6 +118,8 @@ SilcBool silc_id_create_channel_id(SilcServer server, SILC_LOG_DEBUG(("Creating new Channel ID")); *new_id = silc_calloc(1, sizeof(**new_id)); + if (!(*new_id)) + return FALSE; /* Create the ID */ memcpy((*new_id)->ip.data, router_id->ip.data, router_id->ip.data_len); diff --git a/lib/contrib/nfkc.c b/lib/contrib/nfkc.c index e5eb4d0e..e45656e2 100644 --- a/lib/contrib/nfkc.c +++ b/lib/contrib/nfkc.c @@ -745,6 +745,9 @@ _g_utf8_normalize_wc (const gchar * str, gssize max_len, GNormalizeMode mode) gboolean do_compat = (mode == G_NORMALIZE_NFKC || mode == G_NORMALIZE_NFKD); gboolean do_compose = (mode == G_NORMALIZE_NFC || mode == G_NORMALIZE_NFKC); + if (!str) + return NULL; + n_wc = 0; p = str; while ((max_len < 0 || p < str + max_len) && *p) diff --git a/lib/silcasn1/silcasn1.c b/lib/silcasn1/silcasn1.c index 2e43b49c..9b599ffd 100644 --- a/lib/silcasn1/silcasn1.c +++ b/lib/silcasn1/silcasn1.c @@ -75,7 +75,7 @@ void silc_asn1_uninit(SilcAsn1 asn1) const char *silc_asn1_tag_name(SilcAsn1Tag tag) { - switch (tag) { + switch ((long)tag) { case SILC_ASN1_END: return "END"; case SILC_ASN1_TAG_OPTS: diff --git a/lib/silcasn1/silcasn1_decode.c b/lib/silcasn1/silcasn1_decode.c index 3030d07c..8e977661 100644 --- a/lib/silcasn1/silcasn1_decode.c +++ b/lib/silcasn1/silcasn1_decode.c @@ -408,7 +408,7 @@ silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type, } /* Decode by the type user expects the data to be. */ - switch (type) { + switch ((long)type) { case SILC_ASN1_TAG_ANY: { diff --git a/lib/silcasn1/silcasn1_encode.c b/lib/silcasn1/silcasn1_encode.c index 986909c4..81775ce2 100644 --- a/lib/silcasn1/silcasn1_encode.c +++ b/lib/silcasn1/silcasn1_encode.c @@ -163,7 +163,7 @@ silc_asn1_encoder(SilcAsn1 asn1, SilcStack stack1, SilcStack stack2, } /* Encode by the type */ - switch (type) { + switch ((long)type) { case SILC_ASN1_TAG_ANY: { diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index 2c731ebd..25533994 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2008 Pekka Riikonen + Copyright (C) 1997 - 2014 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -771,7 +771,7 @@ silc_client_connect_to_server(SilcClient client, SILC_LOG_DEBUG(("Connecting to server")); - if (!client || !remote_host) + if (!client || !remote_host || !callback) return NULL; if (client->internal->run_callback) { @@ -814,7 +814,7 @@ silc_client_connect_to_client(SilcClient client, SILC_LOG_DEBUG(("Connecting to client")); - if (!client || !remote_host) + if (!client || !remote_host || !callback) return NULL; if (client->internal->run_callback) { @@ -859,7 +859,7 @@ silc_client_key_exchange(SilcClient client, SILC_LOG_DEBUG(("Performing key exchange")); - if (!client || !stream) + if (!client || !stream || !callback) return NULL; if (client->internal->run_callback) { diff --git a/lib/silcclient/client_entry.c b/lib/silcclient/client_entry.c index c950bfb2..2a94f11b 100644 --- a/lib/silcclient/client_entry.c +++ b/lib/silcclient/client_entry.c @@ -128,6 +128,8 @@ SilcDList silc_client_get_clients_local_ext(SilcClient client, /* Take all without any further checking */ while ((id_cache = silc_list_get(list))) { entry = id_cache->context; + if (!entry) + continue; if (!get_valid || entry->internal.valid) { silc_client_ref_client(client, conn, id_cache->context); silc_dlist_add(clients, id_cache->context); @@ -137,6 +139,8 @@ SilcDList silc_client_get_clients_local_ext(SilcClient client, /* Check multiple cache entries for exact match */ while ((id_cache = silc_list_get(list))) { entry = id_cache->context; + if (!entry) + continue; /* If server was provided, find entries that either have no server set or have the same server. Ignore those that have different @@ -2228,7 +2232,6 @@ SilcServerEntry silc_client_ref_server(SilcClient client, void silc_client_unref_server(SilcClient client, SilcClientConnection conn, SilcServerEntry server_entry) { - SilcBool ret; SilcIDCacheEntry id_cache; char *namec; @@ -2244,8 +2247,8 @@ void silc_client_unref_server(SilcClient client, SilcClientConnection conn, if (silc_idcache_find_by_context(conn->internal->server_cache, server_entry, &id_cache)) { namec = id_cache->name; - ret = silc_idcache_del_by_context(conn->internal->server_cache, - server_entry, NULL); + silc_idcache_del_by_context(conn->internal->server_cache, + server_entry, NULL); silc_free(namec); } silc_mutex_unlock(conn->internal->lock); diff --git a/lib/silcclient/client_notify.c b/lib/silcclient/client_notify.c index e855e412..b1329541 100644 --- a/lib/silcclient/client_notify.c +++ b/lib/silcclient/client_notify.c @@ -1491,7 +1491,7 @@ SILC_FSM_STATE(silc_client_notify_error) /* Get error */ tmp = silc_argument_get_arg_type(args, 1, &tmp_len); - if (!tmp && tmp_len != 1) + if (!tmp || tmp_len != 1) goto out; error = (SilcStatus)tmp[0]; diff --git a/lib/silcclient/client_prvmsg.c b/lib/silcclient/client_prvmsg.c index 2242fd34..5dd74141 100644 --- a/lib/silcclient/client_prvmsg.c +++ b/lib/silcclient/client_prvmsg.c @@ -329,7 +329,8 @@ static void silc_client_private_message_key_cb(SilcClient client, /* Mark that we are responder */ client_entry = silc_dlist_get(clients); - client_entry->internal.prv_resp = TRUE; + if (client_entry) + client_entry->internal.prv_resp = TRUE; /* XXX we should notify application that remote wants to set up the static key. And we should tell if we already have key with remote. diff --git a/lib/silcclient/client_register.c b/lib/silcclient/client_register.c index a3cafe47..e0d0f862 100644 --- a/lib/silcclient/client_register.c +++ b/lib/silcclient/client_register.c @@ -446,7 +446,7 @@ SILC_FSM_STATE(silc_client_st_resume_resolve_channels) res_argc, res_argv, res_argv_lens, res_argv_types); - for (i = 0; i < resume->channel_count; i++) + for (i = 0; res_argv && i < resume->channel_count; i++) silc_free(res_argv[i]); silc_free(res_argv); silc_free(res_argv_lens); diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index 7a7fa2b1..54b77757 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -2016,7 +2016,7 @@ SILC_FSM_STATE(silc_client_command_reply_getkey) SilcServerEntry server_entry; unsigned char *tmp; SilcUInt32 len; - SilcPublicKey public_key; + SilcPublicKey public_key = NULL; SilcID id; /* Sanity checks */ diff --git a/lib/silccore/silcargument.c b/lib/silccore/silcargument.c index eac8bdf6..5a047f3c 100644 --- a/lib/silccore/silcargument.c +++ b/lib/silccore/silcargument.c @@ -41,7 +41,6 @@ SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload, SilcBufferStruct buffer; SilcArgumentPayload newp; SilcUInt16 p_len = 0; - unsigned char arg_num = 0; unsigned char arg_type = 0; SilcUInt32 pull_len = 0; int i = 0, ret; @@ -61,7 +60,6 @@ SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload, goto err; /* Get arguments */ - arg_num = 1; for (i = 0; i < argc; i++) { ret = silc_buffer_unformat(&buffer, SILC_STR_UI_SHORT(&p_len), diff --git a/lib/silccore/silcattrs.c b/lib/silccore/silcattrs.c index d40e53ac..414ecf6e 100644 --- a/lib/silccore/silcattrs.c +++ b/lib/silccore/silcattrs.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2002 - 2007 Pekka Riikonen + Copyright (C) 2002 - 2014 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -48,9 +48,12 @@ silc_attribute_payload_encode_int(SilcAttribute attribute, unsigned char tmp[4], *str = NULL, *ret; SilcUInt32 len; + if (ret_len) + *ret_len = 0; + /* Encode according to attribute type */ if (flags & SILC_ATTRIBUTE_FLAG_VALID) { - if (!object && !object_size) + if (!object || !object_size) return NULL; switch (attribute) { @@ -289,11 +292,11 @@ SilcAttributePayload silc_attribute_payload_alloc(SilcAttribute attribute, attr->data = silc_attribute_payload_encode_int(attribute, flags, object, object_size, &tmp_len); - attr->data_len = (SilcUInt16)tmp_len; if (!attr->data) { silc_free(attr); return NULL; } + attr->data_len = (SilcUInt16)tmp_len; return attr; } diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index 030291a0..8391858e 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -1803,7 +1803,7 @@ SilcBool silc_packet_send_va_ext(SilcPacketStream stream, silc_buffer_purge(&buf); va_end(va); - return TRUE; + return ret; } /***************************** Packet Receiving *****************************/ diff --git a/lib/silccrypt/aes.c b/lib/silccrypt/aes.c index f41a61d6..797b803b 100644 --- a/lib/silccrypt/aes.c +++ b/lib/silccrypt/aes.c @@ -453,8 +453,10 @@ AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]) cx->ks[v(48,(2))] = ss[2] = word_in(key, 2); cx->ks[v(48,(3))] = ss[3] = word_in(key, 3); - cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4)); - cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5)); + ss[4] = word_in(key, 4); + cx->ks[v(48,(4))] = ff(ss[4]); + ss[5] = word_in(key, 5); + cx->ks[v(48,(5))] = ff(ss[5]); kdf6(cx->ks, 0); kd6(cx->ks, 1); kd6(cx->ks, 2); kd6(cx->ks, 3); kd6(cx->ks, 4); kd6(cx->ks, 5); @@ -519,10 +521,14 @@ AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]) cx->ks[v(56,(2))] = ss[2] = word_in(key, 2); cx->ks[v(56,(3))] = ss[3] = word_in(key, 3); - cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4)); - cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5)); - cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6)); - cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7)); + ss[4] = word_in(key, 4); + cx->ks[v(56,(4))] = ff(ss[4]); + ss[5] = word_in(key, 5); + cx->ks[v(56,(5))] = ff(ss[5]); + ss[6] = word_in(key, 6); + cx->ks[v(56,(6))] = ff(ss[6]); + ss[7] = word_in(key, 7); + cx->ks[v(56,(7))] = ff(ss[7]); kdf8(cx->ks, 0); kd8(cx->ks, 1); kd8(cx->ks, 2); kd8(cx->ks, 3); kd8(cx->ks, 4); kd8(cx->ks, 5); diff --git a/lib/silccrypt/silccipher.c b/lib/silccrypt/silccipher.c index f7f64600..a14e2c3d 100644 --- a/lib/silccrypt/silccipher.c +++ b/lib/silccrypt/silccipher.c @@ -301,7 +301,8 @@ char *silc_cipher_get_supported(void) } #endif /* SILC_SYMBIAN */ - list[len - 1] = 0; + if (list) + list[len - 1] = 0; return list; } diff --git a/lib/silccrypt/silchash.c b/lib/silccrypt/silchash.c index 59cdf7f9..7c77f008 100644 --- a/lib/silccrypt/silchash.c +++ b/lib/silccrypt/silchash.c @@ -359,7 +359,8 @@ char *silc_hash_get_supported(void) } #endif /* SILC_SYMBIAN */ - list[len - 1] = 0; + if (list) + list[len - 1] = 0; return list; } diff --git a/lib/silccrypt/silchmac.c b/lib/silccrypt/silchmac.c index 1e9380db..751ca226 100644 --- a/lib/silccrypt/silchmac.c +++ b/lib/silccrypt/silchmac.c @@ -350,7 +350,8 @@ char *silc_hmac_get_supported() } #endif /* SILC_SYMBIAN */ - list[len - 1] = 0; + if (list) + list[len - 1] = 0; return list; } diff --git a/lib/silccrypt/silcpkcs.c b/lib/silccrypt/silcpkcs.c index 74fd6f03..919fbe9d 100644 --- a/lib/silccrypt/silcpkcs.c +++ b/lib/silccrypt/silcpkcs.c @@ -353,7 +353,8 @@ char *silc_pkcs_get_supported(void) } #endif /* SILC_SYMBIAN */ - list[len - 1] = 0; + if (list) + list[len - 1] = 0; return list; } diff --git a/lib/silccrypt/silcpkcs1.c b/lib/silccrypt/silcpkcs1.c index 0a75f800..514e6a21 100644 --- a/lib/silccrypt/silcpkcs1.c +++ b/lib/silccrypt/silcpkcs1.c @@ -551,6 +551,11 @@ SilcBool silc_pkcs1_decrypt(void *private_key, /* MP to data */ padded = silc_mp_mp2bin(&mp_dst, (key->bits + 7) / 8, &padded_len); + if (!padded) { + silc_mp_uninit(&mp_tmp); + silc_mp_uninit(&mp_dst); + return FALSE; + } /* Unpad data */ if (!silc_pkcs1_decode(SILC_PKCS1_BT_PUB, padded, padded_len, @@ -675,7 +680,7 @@ SilcBool silc_pkcs1_verify(void *public_key, SilcBool ret = FALSE; SilcMPInt mp_tmp2; SilcMPInt mp_dst; - unsigned char *verify, unpadded[2048 + 1], hashr[SILC_HASH_MAXLEN]; + unsigned char *verify = NULL, unpadded[65536 + 1], hashr[SILC_HASH_MAXLEN]; SilcUInt32 verify_len, len = (key->bits + 7) / 8; SilcBufferStruct di, ldi; SilcHash ihash = NULL; @@ -699,6 +704,8 @@ SilcBool silc_pkcs1_verify(void *public_key, /* MP to data */ verify = silc_mp_mp2bin(&mp_dst, len, &verify_len); + if (!verify) + goto err; /* Unpad data */ if (!silc_pkcs1_decode(SILC_PKCS1_BT_PRV1, verify, verify_len, @@ -769,8 +776,10 @@ SilcBool silc_pkcs1_verify(void *public_key, return ret; err: - memset(verify, 0, verify_len); - silc_free(verify); + if (verify) { + memset(verify, 0, verify_len); + silc_free(verify); + } silc_mp_uninit(&mp_tmp2); silc_mp_uninit(&mp_dst); if (ihash) @@ -866,6 +875,11 @@ SilcBool silc_pkcs1_verify_no_oid(void *public_key, /* MP to data */ verify = silc_mp_mp2bin(&mp_dst, len, &verify_len); + if (!verify) { + silc_mp_uninit(&mp_tmp2); + silc_mp_uninit(&mp_dst); + return FALSE; + } /* Unpad data */ if (!silc_pkcs1_decode(SILC_PKCS1_BT_PRV1, verify, verify_len, diff --git a/lib/silccrypt/silcrng.c b/lib/silccrypt/silcrng.c index 668a64ea..02998604 100644 --- a/lib/silccrypt/silcrng.c +++ b/lib/silccrypt/silcrng.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2003 Pekka Riikonen + Copyright (C) 1997 - 2014 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -149,6 +149,10 @@ SilcRng silc_rng_alloc(void) } new->devrandom = strdup("/dev/random"); + if (!new->devrandom) { + silc_rng_free(new); + return NULL; + } return new; } @@ -194,12 +198,20 @@ void silc_rng_init(SilcRng rng) /* Initialize the states for the RNG. */ rng->state = silc_calloc(1, sizeof(*rng->state)); + if (!rng->state) { + SILC_LOG_ERROR(("Error allocating memory for RNG")); + return; + } rng->state->low = 0; rng->state->pos = 8; rng->state->next = NULL; first = rng->state; for (i = SILC_RNG_STATE_NUM - 1; i >= 1; i--) { next = silc_calloc(1, sizeof(*rng->state)); + if (!next) { + SILC_LOG_ERROR(("Error allocating memory for RNG")); + return; + } next->low = (i * (sizeof(rng->pool) / SILC_RNG_STATE_NUM)); next->pos = @@ -614,6 +626,8 @@ unsigned char *silc_rng_get_rn_string(SilcRng rng, SilcUInt32 len) unsigned char *string; string = silc_calloc((len * 2 + 1), sizeof(unsigned char)); + if (!string) + return NULL; for (i = 0; i < len; i++) sprintf(string + 2 * i, "%02x", silc_rng_get_byte(rng)); @@ -629,6 +643,8 @@ unsigned char *silc_rng_get_rn_data(SilcRng rng, SilcUInt32 len) unsigned char *data; data = silc_calloc(len + 1, sizeof(*data)); + if (!data) + return NULL; for (i = 0; i < len; i++) data[i] = silc_rng_get_byte(rng); diff --git a/lib/silccrypt/twofish.c b/lib/silccrypt/twofish.c index e8f3bd44..5da3f55f 100644 --- a/lib/silccrypt/twofish.c +++ b/lib/silccrypt/twofish.c @@ -475,7 +475,7 @@ u4byte *twofish_set_key(TwofishContext *ctx, } #endif - ctx->k_len = ctx->k_len = key_len / 64; /* 2, 3 or 4 */ + ctx->k_len = key_len / 64; /* 2, 3 or 4 */ for(i = 0; i < ctx->k_len; ++i) { diff --git a/lib/silchttp/silchttpserver.c b/lib/silchttp/silchttpserver.c index e83d2f37..20b2c041 100644 --- a/lib/silchttp/silchttpserver.c +++ b/lib/silchttp/silchttpserver.c @@ -181,6 +181,9 @@ static SilcBool silc_http_server_parse(SilcHttpServer httpd, if (value && !strcasecmp(value, "close")) conn->keepalive = FALSE; + if (!conn->method) + return FALSE; + /* Deliver request to caller */ if (!strcasecmp(conn->method, "GET") || !strcasecmp(conn->method, "HEAD")) { httpd->callback(httpd, conn, conn->uri, conn->method, diff --git a/lib/silcmath/mp_gmp.c b/lib/silcmath/mp_gmp.c index d3f29b64..192d105f 100644 --- a/lib/silcmath/mp_gmp.c +++ b/lib/silcmath/mp_gmp.c @@ -28,7 +28,8 @@ void silc_mp_init(SilcMPInt *mp) void silc_mp_uninit(SilcMPInt *mp) { - mpz_clear(mp); + if (mp) + mpz_clear(mp); } size_t silc_mp_size(SilcMPInt *mp) diff --git a/lib/silcmath/mp_tfm.c b/lib/silcmath/mp_tfm.c index b3b1e73b..57cc73af 100644 --- a/lib/silcmath/mp_tfm.c +++ b/lib/silcmath/mp_tfm.c @@ -28,7 +28,8 @@ void silc_mp_init(SilcMPInt *mp) void silc_mp_uninit(SilcMPInt *mp) { - fp_zero(mp); + if (mp) + fp_zero(mp); } size_t silc_mp_size(SilcMPInt *mp) diff --git a/lib/silcmath/mp_tma.c b/lib/silcmath/mp_tma.c index e4e123ee..760f04c1 100644 --- a/lib/silcmath/mp_tma.c +++ b/lib/silcmath/mp_tma.c @@ -35,7 +35,8 @@ SilcBool silc_mp_sinit(SilcStack stack, SilcMPInt *mp) void silc_mp_uninit(SilcMPInt *mp) { - tma_mp_clear(mp); + if (mp) + tma_mp_clear(mp); } size_t silc_mp_size(SilcMPInt *mp) diff --git a/lib/silcmath/silcmp.h b/lib/silcmath/silcmp.h index 313e7548..2d4df2f9 100644 --- a/lib/silcmath/silcmp.h +++ b/lib/silcmath/silcmp.h @@ -85,7 +85,7 @@ SilcBool silc_mp_sinit(SilcStack stack, SilcMPInt *mp); * * DESCRIPTION * - * Uninitializes the MP Integer. + * Uninitializes the MP Integer. The pointer may be NULL. * ***/ void silc_mp_uninit(SilcMPInt *mp); diff --git a/lib/silcmath/tma.c b/lib/silcmath/tma.c index b29353a3..d16852d2 100644 --- a/lib/silcmath/tma.c +++ b/lib/silcmath/tma.c @@ -426,6 +426,8 @@ int fast_s_tma_mp_mul_digs (tma_mp_int * a, tma_mp_int * b, tma_mp_int * c, int /* number of output digits to produce */ pa = MIN(digs, a->used + b->used); + if (!pa) + return MP_VAL; /* clear the carry */ _W = 0; @@ -531,6 +533,9 @@ int fast_s_tma_mp_mul_high_digs (tma_mp_int * a, tma_mp_int * b, tma_mp_int * c, /* number of output digits to produce */ pa = a->used + b->used; + if (!pa) + return MP_VAL; + _W = 0; for (ix = digs; ix < pa; ix++) { int tx, ty, iy; diff --git a/lib/silcsftp/sftp_fs_memory.c b/lib/silcsftp/sftp_fs_memory.c index c111c9da..e923d7fe 100644 --- a/lib/silcsftp/sftp_fs_memory.c +++ b/lib/silcsftp/sftp_fs_memory.c @@ -179,6 +179,8 @@ static MemFSEntry memfs_find_entry_path(MemFSEntry dir, const char *p) char *path, *cp; cp = path = memfs_expand_path(dir, p); + if (!cp) + return NULL; if (strlen(cp) == 1 && cp[0] == '/') return dir; diff --git a/lib/silcske/groups.c b/lib/silcske/groups.c index 7f55aced..dd6e6873 100644 --- a/lib/silcske/groups.c +++ b/lib/silcske/groups.c @@ -169,7 +169,8 @@ char *silc_ske_get_supported_groups() len++; } - list[len - 1] = 0; + if (list) + list[len - 1] = 0; return list; } diff --git a/lib/silcske/silcske.c b/lib/silcske/silcske.c index 6fc73074..43a68438 100644 --- a/lib/silcske/silcske.c +++ b/lib/silcske/silcske.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2000 - 2008 Pekka Riikonen + Copyright (C) 2000 - 2014 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -240,6 +240,8 @@ silc_ske_select_security_properties(SilcSKE ske, SILC_LOG_DEBUG(("Parsing KE Start Payload")); rp = remote_payload; + if (!rp) + return SILC_SKE_STATUS_BAD_VERSION; /* Check for mandatory fields */ if (!rp->ke_grp_len) { @@ -710,8 +712,14 @@ static SilcSKEStatus silc_ske_make_hash(SilcSKE ske, s_len = (ske->start_payload_copy ? silc_buffer_len(ske->start_payload_copy) : 0); e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len); + if (!e) + return SILC_SKE_STATUS_OUT_OF_MEMORY; f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len); + if (!f) + return SILC_SKE_STATUS_OUT_OF_MEMORY; KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len); + if (!KEY) + return SILC_SKE_STATUS_OUT_OF_MEMORY; /* Format the buffer used to compute the hash value */ buf = silc_buffer_alloc_size(s_len + @@ -768,6 +776,8 @@ static SilcSKEStatus silc_ske_make_hash(SilcSKE ske, s_len = (ske->start_payload_copy ? silc_buffer_len(ske->start_payload_copy) : 0); e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len); + if (!e) + return SILC_SKE_STATUS_OUT_OF_MEMORY; buf = silc_buffer_alloc_size(s_len + ske->ke1_payload->pk_len + e_len); if (!buf) @@ -818,6 +828,9 @@ silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat) SilcSKERekeyMaterial rekey; const char *hash; + if (!keymat) + return NULL; + /* Create rekey material */ rekey = silc_calloc(1, sizeof(*rekey)); if (!rekey) @@ -859,12 +872,18 @@ silc_ske_assemble_security_properties(SilcSKE ske, SILC_LOG_DEBUG(("Assembling KE Start Payload")); rp = silc_calloc(1, sizeof(*rp)); + if (!rp) + return NULL; /* Set flags */ rp->flags = (unsigned char)flags; /* Set random cookie */ rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie)); + if (!rp->cookie) { + silc_free(rp); + return NULL; + } for (i = 0; i < SILC_SKE_COOKIE_LEN; i++) rp->cookie[i] = silc_rng_get_byte_fast(ske->rng); rp->cookie_len = SILC_SKE_COOKIE_LEN; @@ -876,27 +895,33 @@ silc_ske_assemble_security_properties(SilcSKE ske, /* Put version */ rp->version = strdup(version); - rp->version_len = strlen(version); + if (rp->version) + rp->version_len = strlen(version); /* Get supported Key Exhange groups */ rp->ke_grp_list = silc_ske_get_supported_groups(); - rp->ke_grp_len = strlen(rp->ke_grp_list); + if (rp->ke_grp_list) + rp->ke_grp_len = strlen(rp->ke_grp_list); /* Get supported PKCS algorithms */ rp->pkcs_alg_list = silc_pkcs_get_supported(); - rp->pkcs_alg_len = strlen(rp->pkcs_alg_list); + if (rp->pkcs_alg_list) + rp->pkcs_alg_len = strlen(rp->pkcs_alg_list); /* Get supported encryption algorithms */ rp->enc_alg_list = silc_cipher_get_supported(); - rp->enc_alg_len = strlen(rp->enc_alg_list); + if (rp->enc_alg_list) + rp->enc_alg_len = strlen(rp->enc_alg_list); /* Get supported hash algorithms */ rp->hash_alg_list = silc_hash_get_supported(); - rp->hash_alg_len = strlen(rp->hash_alg_list); + if (rp->hash_alg_list) + rp->hash_alg_len = strlen(rp->hash_alg_list); /* Get supported HMACs */ rp->hmac_alg_list = silc_hmac_get_supported(); - rp->hmac_alg_len = strlen(rp->hmac_alg_list); + if (rp->hmac_alg_list) + rp->hmac_alg_len = strlen(rp->hmac_alg_list); /* XXX */ /* Get supported compression algorithms */ @@ -972,8 +997,10 @@ static SilcBool silc_ske_packet_send(SilcSKE ske, ske->retrans.type = type; ske->retrans.flags = flags; ske->retrans.data = silc_memdup(data, data_len); - ske->retrans.data_len = data_len; - silc_ske_install_retransmission(ske); + if (ske->retrans.data) { + ske->retrans.data_len = data_len; + silc_ske_install_retransmission(ske); + } } return ret; @@ -1074,8 +1101,8 @@ void silc_ske_free(SilcSKE ske) * FSM finish routine is called. We have to be prepared to handle * that case. */ - ske->packet = NULL; - ske->status = SILC_SKE_STATUS_ERROR; + ske->packet = NULL; + ske->status = SILC_SKE_STATUS_ERROR; silc_ske_notify_failure(ske); @@ -1337,13 +1364,15 @@ SILC_FSM_STATE(silc_ske_st_initiator_phase1) silc_ske_payload_start_free(payload); if (group) silc_ske_group_free(group); - if (prop->cipher) - silc_cipher_free(prop->cipher); - if (prop->hash) - silc_hash_free(prop->hash); - if (prop->hmac) - silc_hmac_free(prop->hmac); - silc_free(prop); + if (prop) { + if (prop->cipher) + silc_cipher_free(prop->cipher); + if (prop->hash) + silc_hash_free(prop->hash); + if (prop->hmac) + silc_hmac_free(prop->hmac); + silc_free(prop); + } ske->prop = NULL; if (status == SILC_SKE_STATUS_OK) @@ -1370,7 +1399,7 @@ SILC_FSM_STATE(silc_ske_st_initiator_phase2) /* Create the random number x, 1 < x < q. */ x = silc_calloc(1, sizeof(*x)); - if (!x){ + if (!x) { /** Out of memory */ ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY; silc_fsm_next(fsm, silc_ske_st_initiator_error); @@ -1436,7 +1465,19 @@ SILC_FSM_STATE(silc_ske_st_initiator_phase2) /* Compute the hash value */ memset(hash, 0, sizeof(hash)); - silc_ske_make_hash(ske, hash, &hash_len, TRUE); + if (silc_ske_make_hash(ske, hash, &hash_len, TRUE) != SILC_SKE_STATUS_OK) + { + /** Error computing hash */ + silc_mp_uninit(x); + silc_free(x); + silc_mp_uninit(&payload->x); + silc_free(payload->pk_data); + silc_free(payload); + ske->ke1_payload = NULL; + ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR; + silc_fsm_next(fsm, silc_ske_st_initiator_error); + return SILC_FSM_CONTINUE; + } SILC_LOG_DEBUG(("Signing HASH_i value")); @@ -1542,6 +1583,10 @@ SILC_FSM_STATE(silc_ske_st_initiator_phase3) /* Compute the shared secret key */ KEY = silc_calloc(1, sizeof(*KEY)); + if (!KEY) { + ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY; + goto err; + } silc_mp_init(KEY); silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group); ske->KEY = KEY; @@ -1643,6 +1688,10 @@ SILC_FSM_STATE(silc_ske_st_initiator_phase4) if (status != SILC_SKE_STATUS_OK) goto err; ske->hash = silc_memdup(hash, hash_len); + if (!ske->hash) { + status = SILC_SKE_STATUS_OUT_OF_MEMORY; + goto err; + } ske->hash_len = hash_len; if (ske->prop->public_key) { @@ -1860,7 +1909,7 @@ SilcAsyncOperation silc_ske_initiator(SilcSKE ske, ske->timeout = params->timeout_secs ? params->timeout_secs : 30; ske->start_payload = start_payload; ske->version = params->version; - ++ ske->refcnt; + ++ske->refcnt; /* Link to packet stream to get key exchange packets */ ske->stream = stream; @@ -1941,6 +1990,13 @@ SILC_FSM_STATE(silc_ske_st_responder_phase1) /* Take a copy of the payload buffer for future use. It is used to compute the HASH value. */ ske->start_payload_copy = silc_buffer_copy(packet_buf); + if (!ske->start_payload_copy) { + silc_packet_free(ske->packet); + ske->packet = NULL; + ske->status = status; + silc_fsm_next(fsm, silc_ske_st_responder_error); + return SILC_FSM_CONTINUE; + } silc_packet_free(ske->packet); ske->packet = NULL; @@ -2118,8 +2174,8 @@ SILC_FSM_STATE(silc_ske_st_responder_phase4) { SilcSKE ske = fsm_context; SilcSKEStatus status; - SilcSKEKEPayload recv_payload, send_payload; - SilcMPInt *x, *KEY; + SilcSKEKEPayload recv_payload, send_payload = NULL; + SilcMPInt *x = NULL, *KEY; if (ske->aborted) { /** Aborted */ @@ -2131,8 +2187,7 @@ SILC_FSM_STATE(silc_ske_st_responder_phase4) if (ske->status != SILC_SKE_STATUS_OK) { /** Public key not verified */ SILC_LOG_DEBUG(("Public key verification failed")); - silc_fsm_next(fsm, silc_ske_st_initiator_error); - return SILC_FSM_CONTINUE; + goto err; } recv_payload = ske->ke1_payload; @@ -2150,9 +2205,9 @@ SILC_FSM_STATE(silc_ske_st_responder_phase4) status = silc_ske_make_hash(ske, hash, &hash_len, TRUE); if (status != SILC_SKE_STATUS_OK) { /** Error computing hash */ + SILC_LOG_DEBUG(("Error computing hash")); ske->status = status; - silc_fsm_next(fsm, silc_ske_st_responder_error); - return SILC_FSM_CONTINUE; + goto err; } SILC_LOG_DEBUG(("Verifying signature (HASH_i)")); @@ -2163,8 +2218,7 @@ SILC_FSM_STATE(silc_ske_st_responder_phase4) /** Incorrect signature */ SILC_LOG_ERROR(("Signature verification failed, incorrect signature")); ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE; - silc_fsm_next(fsm, silc_ske_st_responder_error); - return SILC_FSM_CONTINUE; + goto err; } SILC_LOG_DEBUG(("Signature is Ok")); @@ -2174,6 +2228,10 @@ SILC_FSM_STATE(silc_ske_st_responder_phase4) /* Create the random number x, 1 < x < q. */ x = silc_calloc(1, sizeof(*x)); + if (!x) { + ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY; + goto err; + } silc_mp_init(x); status = silc_ske_create_rnd(ske, &ske->prop->group->group_order, @@ -2181,15 +2239,16 @@ SILC_FSM_STATE(silc_ske_st_responder_phase4) x); if (status != SILC_SKE_STATUS_OK) { /** Error generating random number */ - silc_mp_uninit(x); - silc_free(x); ske->status = status; - silc_fsm_next(fsm, silc_ske_st_responder_error); - return SILC_FSM_CONTINUE; + goto err; } /* Save the results for later processing */ send_payload = silc_calloc(1, sizeof(*send_payload)); + if (!send_payload) { + ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY; + goto err; + } ske->x = x; ske->ke2_payload = send_payload; @@ -2204,6 +2263,10 @@ SILC_FSM_STATE(silc_ske_st_responder_phase4) /* Compute the shared secret key */ KEY = silc_calloc(1, sizeof(*KEY)); + if (!KEY) { + ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY; + goto err; + } silc_mp_init(KEY); silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x, &ske->prop->group->group); @@ -2212,6 +2275,16 @@ SILC_FSM_STATE(silc_ske_st_responder_phase4) /** Send KE2 payload */ silc_fsm_next(fsm, silc_ske_st_responder_phase5); return SILC_FSM_CONTINUE; + + err: + silc_mp_uninit(x); + silc_free(x); + ske->x = NULL; + silc_free(send_payload); + ske->ke2_payload = NULL; + + silc_fsm_next(fsm, silc_ske_st_responder_error); + return SILC_FSM_CONTINUE; } /* Phase-5. Send KE2 payload */ @@ -2233,7 +2306,7 @@ SILC_FSM_STATE(silc_ske_st_responder_phase5) pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len); if (!pk) { /** Error encoding public key */ - status = SILC_SKE_STATUS_OUT_OF_MEMORY; + ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY; silc_fsm_next(fsm, silc_ske_st_responder_error); return SILC_FSM_CONTINUE; } @@ -2253,6 +2326,12 @@ SILC_FSM_STATE(silc_ske_st_responder_phase5) return SILC_FSM_CONTINUE; } ske->hash = silc_memdup(hash, hash_len); + if (!ske->hash) { + /** Error computing hash */ + ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY; + silc_fsm_next(fsm, silc_ske_st_responder_error); + return SILC_FSM_CONTINUE; + } ske->hash_len = hash_len; if (ske->public_key && ske->private_key) { @@ -2262,11 +2341,17 @@ SILC_FSM_STATE(silc_ske_st_responder_phase5) if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign, sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) { /** Error computing signature */ - status = SILC_SKE_STATUS_SIGNATURE_ERROR; + ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR; silc_fsm_next(fsm, silc_ske_st_responder_error); return SILC_FSM_CONTINUE; } ske->ke2_payload->sign_data = silc_memdup(sign, sign_len); + if (!ske->ke2_payload->sign_data) { + /** Error computing hash */ + ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY; + silc_fsm_next(fsm, silc_ske_st_responder_error); + return SILC_FSM_CONTINUE; + } ske->ke2_payload->sign_len = sign_len; memset(sign, 0, sizeof(sign)); } @@ -2410,7 +2495,9 @@ SILC_FSM_STATE(silc_ske_st_responder_error) ske->status, silc_ske_map_status(ske->status))); /* Send FAILURE packet */ - if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE) + if (ske->status == SILC_SKE_STATUS_OUT_OF_MEMORY) + ske->status = SILC_SKE_STATUS_ERROR; + else if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE) ske->status = SILC_SKE_STATUS_BAD_PAYLOAD; SILC_PUT32_MSB(ske->status, tmp); silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4); @@ -2449,7 +2536,7 @@ SilcAsyncOperation silc_ske_responder(SilcSKE ske, ske->version = params->version; if (!ske->version) return NULL; - ++ ske->refcnt; + ++ske->refcnt; /* Link to packet stream to get key exchange packets */ ske->stream = stream; @@ -2553,13 +2640,16 @@ SILC_FSM_STATE(silc_ske_st_rekey_initiator_done) if (ske->rekey->pfs) { /* PFS */ pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len); - if (pfsbuf) { - ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len, - block_len, key_len, - hash_len, hash); - memset(pfsbuf, 0, x_len); - silc_free(pfsbuf); + if (!pfsbuf) { + SILC_LOG_ERROR(("Error processing key material")); + silc_fsm_next(fsm, silc_ske_st_initiator_error); + return SILC_FSM_CONTINUE; } + ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len, + block_len, key_len, + hash_len, hash); + memset(pfsbuf, 0, x_len); + silc_free(pfsbuf); } else { /* No PFS */ ske->keymat = @@ -2708,7 +2798,7 @@ silc_ske_rekey_initiator(SilcSKE ske, ske->rekey = rekey; ske->responder = FALSE; ske->rekeying = TRUE; - ++ ske->refcnt; + ++ske->refcnt; /* Link to packet stream to get key exchange packets */ ske->stream = stream; @@ -2830,13 +2920,16 @@ SILC_FSM_STATE(silc_ske_st_rekey_responder_done) if (ske->rekey->pfs) { /* PFS */ pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len); - if (pfsbuf) { - ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len, - block_len, key_len, - hash_len, hash); - memset(pfsbuf, 0, x_len); - silc_free(pfsbuf); + if (!pfsbuf) { + SILC_LOG_ERROR(("Error processing key material")); + silc_fsm_next(fsm, silc_ske_st_responder_error); + return SILC_FSM_CONTINUE; } + ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len, + block_len, key_len, + hash_len, hash); + memset(pfsbuf, 0, x_len); + silc_free(pfsbuf); } else { /* No PFS */ ske->keymat = @@ -2986,7 +3079,7 @@ silc_ske_rekey_responder(SilcSKE ske, ske->responder = TRUE; ske->rekeying = TRUE; ske->packet = packet; - ++ ske->refcnt; + ++ske->refcnt; /* Link to packet stream to get key exchange packets */ ske->stream = stream; @@ -3042,11 +3135,23 @@ silc_ske_process_key_material_data(unsigned char *data, buf->data[0] = 0; silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd); key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char)); + if (!key->send_iv) { + silc_buffer_clear(buf); + silc_buffer_free(buf); + silc_free(key); + return NULL; + } memcpy(key->send_iv, hashd, req_iv_len); memset(hashd, 0, sizeof(hashd)); buf->data[0] = 1; silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd); key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char)); + if (!key->receive_iv) { + silc_buffer_clear(buf); + silc_buffer_free(buf); + silc_free(key); + return NULL; + } memcpy(key->receive_iv, hashd, req_iv_len); key->iv_len = req_iv_len; @@ -3092,11 +3197,24 @@ silc_ske_process_key_material_data(unsigned char *data, /* Then, save the keys */ dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char)); + if (!dtmp) { + silc_buffer_clear(buf); + silc_buffer_free(buf); + silc_free(key); + return NULL; + } memcpy(dtmp, k1, hash_len); memcpy(dtmp + hash_len, k2, hash_len); memcpy(dtmp + hash_len + hash_len, k3, hash_len); key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char)); + if (!key->send_enc_key) { + silc_buffer_clear(buf); + silc_buffer_free(buf); + silc_free(key); + silc_free(dtmp); + return NULL; + } memcpy(key->send_enc_key, dtmp, enc_key_len); key->enc_key_len = req_enc_key_len; @@ -3112,6 +3230,12 @@ silc_ske_process_key_material_data(unsigned char *data, memset(hashd, 0, sizeof(hashd)); silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd); key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char)); + if (!key->send_enc_key) { + silc_buffer_clear(buf); + silc_buffer_free(buf); + silc_free(key); + return NULL; + } memcpy(key->send_enc_key, hashd, enc_key_len); key->enc_key_len = req_enc_key_len; } @@ -3155,11 +3279,24 @@ silc_ske_process_key_material_data(unsigned char *data, /* Then, save the keys */ dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char)); + if (!dtmp) { + silc_buffer_clear(buf); + silc_buffer_free(buf); + silc_free(key); + return NULL; + } memcpy(dtmp, k1, hash_len); memcpy(dtmp + hash_len, k2, hash_len); memcpy(dtmp + hash_len + hash_len, k3, hash_len); key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char)); + if (!key->receive_enc_key) { + silc_buffer_clear(buf); + silc_buffer_free(buf); + silc_free(key); + silc_free(dtmp); + return NULL; + } memcpy(key->receive_enc_key, dtmp, enc_key_len); key->enc_key_len = req_enc_key_len; @@ -3175,6 +3312,12 @@ silc_ske_process_key_material_data(unsigned char *data, memset(hashd, 0, sizeof(hashd)); silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd); key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char)); + if (!key->receive_enc_key) { + silc_buffer_clear(buf); + silc_buffer_free(buf); + silc_free(key); + return NULL; + } memcpy(key->receive_enc_key, hashd, enc_key_len); key->enc_key_len = req_enc_key_len; } @@ -3184,11 +3327,23 @@ silc_ske_process_key_material_data(unsigned char *data, buf->data[0] = 4; silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd); key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char)); + if (!key->send_hmac_key) { + silc_buffer_clear(buf); + silc_buffer_free(buf); + silc_free(key); + return NULL; + } memcpy(key->send_hmac_key, hashd, req_hmac_key_len); memset(hashd, 0, sizeof(hashd)); buf->data[0] = 5; silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd); key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char)); + if (!key->receive_hmac_key) { + silc_buffer_clear(buf); + silc_buffer_free(buf); + silc_free(key); + return NULL; + } memcpy(key->receive_hmac_key, hashd, req_hmac_key_len); key->hmac_key_len = req_hmac_key_len; memset(hashd, 0, sizeof(hashd)); diff --git a/lib/silcutil/silcmime.c b/lib/silcutil/silcmime.c index c0817ec0..1bd56ccc 100644 --- a/lib/silcutil/silcmime.c +++ b/lib/silcutil/silcmime.c @@ -535,6 +535,9 @@ SilcMime silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial) } } + if (!compbuf) + goto err; + /* Now parse the complete MIME message and deliver it */ complete = silc_mime_decode(NULL, (const unsigned char *)compbuf->head, silc_buffer_truelen(compbuf)); diff --git a/lib/silcutil/silcnet.c b/lib/silcutil/silcnet.c index 17c17d83..60a8a477 100644 --- a/lib/silcutil/silcnet.c +++ b/lib/silcutil/silcnet.c @@ -392,7 +392,8 @@ SilcBool silc_net_check_host_by_sock(SilcSocket sock, char **hostname, if (hostname) *hostname = NULL; - *ip = NULL; + if (ip) + *ip = NULL; SILC_LOG_DEBUG(("Resolving remote hostname and IP address")); @@ -407,16 +408,19 @@ SilcBool silc_net_check_host_by_sock(SilcSocket sock, char **hostname, NI_NUMERICHOST)) return FALSE; - *ip = silc_memdup(s, strlen(s)); - if (*ip == NULL) - return FALSE; + if (ip) { + *ip = silc_memdup(s, strlen(s)); + if (*ip == NULL) + return FALSE; + } #else struct sockaddr_in remote; char *host_ip; if (hostname) *hostname = NULL; - *ip = NULL; + if (ip) + *ip = NULL; SILC_LOG_DEBUG(("Resolving remote hostname and IP address")); @@ -430,15 +434,17 @@ SilcBool silc_net_check_host_by_sock(SilcSocket sock, char **hostname, if (!host_ip) return FALSE; - *ip = silc_memdup(host_ip, strlen(host_ip)); - if (*ip == NULL) - return FALSE; + if (ip) { + *ip = silc_memdup(host_ip, strlen(host_ip)); + if (*ip == NULL) + return FALSE; + } #endif /* Do reverse lookup if we want hostname too. */ if (hostname) { /* Get host by address */ - if (!silc_net_gethostbyaddr(*ip, host, sizeof(host))) + if (!ip || !silc_net_gethostbyaddr(*ip, host, sizeof(host))) return FALSE; *hostname = silc_memdup(host, strlen(host)); @@ -452,7 +458,8 @@ SilcBool silc_net_check_host_by_sock(SilcSocket sock, char **hostname, return FALSE; } - SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip)); + if (ip) + SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip)); return TRUE; } @@ -471,7 +478,8 @@ SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname, if (hostname) *hostname = NULL; - *ip = NULL; + if (ip) + *ip = NULL; SILC_LOG_DEBUG(("Resolving local hostname and IP address")); @@ -486,16 +494,19 @@ SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname, NI_NUMERICHOST)) return FALSE; - *ip = silc_memdup(s, strlen(s)); - if (*ip == NULL) - return FALSE; + if (ip) { + *ip = silc_memdup(s, strlen(s)); + if (*ip == NULL) + return FALSE; + } #else struct sockaddr_in local; char *host_ip; if (hostname) *hostname = NULL; - *ip = NULL; + if (ip) + *ip = NULL; SILC_LOG_DEBUG(("Resolving local hostname and IP address")); @@ -509,15 +520,17 @@ SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname, if (!host_ip) return FALSE; - *ip = silc_memdup(host_ip, strlen(host_ip)); - if (*ip == NULL) - return FALSE; + if (ip) { + *ip = silc_memdup(host_ip, strlen(host_ip)); + if (*ip == NULL) + return FALSE; + } #endif /* Do reverse lookup if we want hostname too. */ if (hostname) { /* Get host by address */ - if (!silc_net_gethostbyaddr(*ip, host, sizeof(host))) + if (!ip || !silc_net_gethostbyaddr(*ip, host, sizeof(host))) return FALSE; *hostname = silc_memdup(host, strlen(host)); @@ -531,7 +544,8 @@ SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname, return FALSE; } - SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip)); + if (ip) + SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip)); return TRUE; } diff --git a/lib/silcutil/silcschedule.c b/lib/silcutil/silcschedule.c index 8d9738de..42d060fb 100644 --- a/lib/silcutil/silcschedule.c +++ b/lib/silcutil/silcschedule.c @@ -292,14 +292,15 @@ void silc_schedule_stats(SilcSchedule schedule) fprintf(stdout, "Schedule %p statistics:\n\n", schedule); fprintf(stdout, "Num FD tasks : %u (%u bytes allocated)\n", silc_hash_table_count(schedule->fd_queue), - sizeof(*ftask) * silc_hash_table_count(schedule->fd_queue)); + (unsigned int)sizeof(*ftask) * + silc_hash_table_count(schedule->fd_queue)); fprintf(stdout, "Num Timeout tasks : %d (%d bytes allocated)\n", silc_list_count(schedule->timeout_queue), - sizeof(struct SilcTaskTimeoutStruct) * + (unsigned int)sizeof(struct SilcTaskTimeoutStruct) * silc_list_count(schedule->timeout_queue)); fprintf(stdout, "Num Timeout freelist : %d (%d bytes allocated)\n", silc_list_count(schedule->free_tasks), - sizeof(struct SilcTaskTimeoutStruct) * + (unsigned int)sizeof(struct SilcTaskTimeoutStruct) * silc_list_count(schedule->free_tasks)); } #endif /* SILC_DIST_INPLACE */ @@ -928,7 +929,7 @@ SilcBool silc_schedule_task_del_by_all(SilcSchedule schedule, int fd, SILC_SCHEDULE_UNLOCK(schedule); - return TRUE; + return ret; } /* Sets a file descriptor to be listened by scheduler. One can call this -- 2.24.0