[PATCH] Fix for silc client multiple heap corruption bugs + work to prevent refcount overflow in client + fix for null deref when leaving channel with private key set
Skywing <[email protected]> Sat, 19 Apr 2008 11:15:21 -0500
| Newsgroups | gmane.network.silc.devel |
|---|---|
| Message-ID | <982D8D05B6407A49AD506E6C3AC8E7D626DC012C3A@caralain.haven.nynaeve.net> |
Hi, This patch fixes a number of silc client bugs that I have encountered: - Sometimes, silcd seems to send a duplicate notify packet for notify client signoff when there are users with the same nick present. I assume that this is a silcd bug, but regardless, the end effect of this condition is that the silc client will try to use a SilcClientEntry object after deletion. The client should never corrupt the heap because of the server sending messages in the wrong state, so this fixes that bug. (This has historically been the cause for most of my "silc randomly dies with segfault after running for a long time" problems.) - I have also fixed a similar bug with channel deletion in the silc client, and although I have not seen the server get into a broken state and send duplicate messages that would cause a channel to be attempted to be deleted twice, a malicious server could do so and cause heap corruption clientside. This has been fixed. - I have fixed a null dereference that occurs when leaving a channel with a private key (also often happens when disconnecting from a server after having been in a channel with a private key, depending on how graceful the disconnect is). This problem occurred because by the time we delete any private keys attached to a channel, the cipher information for the channel is already gone, and we assume that it is still valid. - The silc client uses 16-bit and even 8-bit atomic integers for refcounts in places. This is unsafe, I think, as it places us in danger of a malicious server overflowing a reference count and causing heap corruption (heap use after free). I have changed the silc client to use 32-bit integers for reference counts universally. Command IDs are kept as 16-bit sequence numbers. There are still some outstanding bugs I that haven't dealt with. The silc FSM logic seems to either be subtlety broken or something is using it wrong as, particularly when running many clients within the same silc process and connecting and disconnecting them repeatedly, I'll often get asserts about threadcount going to zero. I'm hoping that somebody who has already more familiar with the FSM logic might be willing to take a look at some of those crashes first. Also, there still exists a bug where a timed out key exchange will leave a prompt up that will crash your client if you respond to it (bad). Furthermore, if you attempt to do a "/key negotiate user address_of_silc_server 706" (obviously intended to be run against a client and not a server), silc will blow up in interesting ways, leading me to believe that the client to client key exchange logic is a bit flaky as well. - S _______________________________________________________________________ Info: https://lists.silcnet.org/mailman/listinfo/silc-announce Archive: https://lists.silcnet.org/pipermail/silc-announce FAQ: http://silcnet.org/support/faq/
client.patch
(application/octet-stream, 20.9 KB)
diff -ru silc-client-orig/lib/silcclient/client.c silc-client-1.1.4/lib/silcclient/client.c
--- silc-client-orig/lib/silcclient/client.c 2008-03-20 01:46:52.000000000 -0500
+++ silc-client-1.1.4/lib/silcclient/client.c 2008-04-19 10:03:41.000000000 -0500
@@ -55,7 +55,7 @@
SilcClient client = silc_fsm_get_state_context(fsm);
/* Signal client that we have finished */
- silc_atomic_sub_int16(&client->internal->conns, 1);
+ silc_atomic_sub_int32(&client->internal->conns, 1);
client->internal->connection_closed = TRUE;
SILC_FSM_EVENT_SIGNAL(&client->internal->wait_event);
@@ -529,7 +529,7 @@
/* A connection finished */
SILC_LOG_DEBUG(("Event: connection closed"));
client->internal->connection_closed = FALSE;
- if (silc_atomic_get_int16(&client->internal->conns) == 0 &&
+ if (silc_atomic_get_int32(&client->internal->conns) == 0 &&
client->internal->stop)
SILC_FSM_EVENT_SIGNAL(&client->internal->wait_event);
return SILC_FSM_CONTINUE;
@@ -538,7 +538,7 @@
if (client->internal->stop) {
/* Stop client libarry. If we have running connections, wait until
they finish first. */
- if (silc_atomic_get_int16(&client->internal->conns) == 0) {
+ if (silc_atomic_get_int32(&client->internal->conns) == 0) {
SILC_LOG_DEBUG(("Event: stop"));
silc_fsm_next(fsm, silc_client_st_stop);
}
@@ -672,7 +672,7 @@
silc_fsm_start(thread, silc_client_connection_st_start);
SILC_LOG_DEBUG(("New connection %p", conn));
- silc_atomic_add_int16(&client->internal->conns, 1);
+ silc_atomic_add_int32(&client->internal->conns, 1);
return conn;
}
@@ -936,7 +936,7 @@
nickname_format[sizeof(new_client->internal->
params->nickname_format) - 1] = 0;
- silc_atomic_init16(&new_client->internal->conns, 0);
+ silc_atomic_init32(&new_client->internal->conns, 0);
return new_client;
}
@@ -964,7 +964,7 @@
silc_dlist_uninit(client->internal->ftp_sessions);
if (client->internal->lock)
silc_mutex_free(client->internal->lock);
- silc_atomic_uninit16(&client->internal->conns);
+ silc_atomic_uninit32(&client->internal->conns);
silc_free(client->username);
silc_free(client->hostname);
silc_free(client->realname);
diff -ru silc-client-orig/lib/silcclient/client.h silc-client-1.1.4/lib/silcclient/client.h
--- silc-client-orig/lib/silcclient/client.h 2008-03-14 07:06:09.000000000 -0500
+++ silc-client-1.1.4/lib/silcclient/client.h 2008-04-19 10:23:44.000000000 -0500
@@ -60,7 +60,9 @@
unsigned int prv_resp : 1; /* TRUE if we are responder when using
private message keys. */
SilcUInt16 resolve_cmd_ident; /* Command identifier when resolving */
- SilcAtomic8 refcnt; /* Reference counter */
+ SilcAtomic32 refcnt; /* Reference counter */
+ SilcAtomic32 deleted; /* Flag indicating whether the client object is
+ already scheduled for deletion.*/
} SilcClientEntryInternal;
/* Internal channel entry context */
@@ -87,14 +89,16 @@
stuff that relates to the
channel. Not used for the
channel resolving itself. */
- SilcAtomic16 refcnt; /* Reference counter */
+ SilcAtomic32 refcnt; /* Reference counter */
+ SilcAtomic32 deleted; /* Flag indicating whether the channel object is
+ already scheduled for deletion.*/
} SilcChannelEntryInternal;
/* Internal server entry context */
typedef struct SilcServerEntryInternalStruct {
SilcRwLock lock; /* Read/write lock */
SilcUInt16 resolve_cmd_ident; /* Resolving identifier */
- SilcAtomic8 refcnt; /* Reference counter */
+ SilcAtomic32 refcnt; /* Reference counter */
} SilcServerEntryInternal;
#endif /* CLIENT_H */
diff -ru silc-client-orig/lib/silcclient/client_channel.c silc-client-1.1.4/lib/silcclient/client_channel.c
--- silc-client-orig/lib/silcclient/client_channel.c 2008-03-14 07:06:09.000000000 -0500
+++ silc-client-1.1.4/lib/silcclient/client_channel.c 2008-04-18 17:15:48.000000000 -0500
@@ -626,8 +626,16 @@
}
channel->internal.curr_key = NULL;
- channel->cipher = silc_cipher_get_name(channel->internal.send_key);
- channel->hmac = silc_hmac_get_name(channel->internal.hmac);
+
+ if (channel->internal.send_key)
+ channel->cipher = silc_cipher_get_name(channel->internal.send_key);
+ else
+ channel->cipher = NULL;
+
+ if (channel->internal.hmac)
+ channel->hmac = silc_hmac_get_name(channel->internal.hmac);
+ else
+ channel->hmac = NULL;
silc_dlist_uninit(channel->internal.private_keys);
channel->internal.private_keys = NULL;
diff -ru silc-client-orig/lib/silcclient/client_entry.c silc-client-1.1.4/lib/silcclient/client_entry.c
--- silc-client-orig/lib/silcclient/client_entry.c 2008-03-14 07:06:09.000000000 -0500
+++ silc-client-1.1.4/lib/silcclient/client_entry.c 2008-04-19 10:28:57.000000000 -0500
@@ -791,7 +791,8 @@
return NULL;
silc_rwlock_alloc(&client_entry->internal.lock);
- silc_atomic_init8(&client_entry->internal.refcnt, 0);
+ silc_atomic_init32(&client_entry->internal.refcnt, 0);
+ silc_atomic_init32(&client_entry->internal.deleted, 1);
client_entry->id = *id;
client_entry->mode = mode;
client_entry->realname = userinfo ? strdup(userinfo) : NULL;
@@ -995,7 +996,8 @@
silc_client_ftp_session_free_client(client, client_entry);
if (client_entry->internal.ke)
silc_client_abort_key_agreement(client, conn, client_entry);
- silc_atomic_uninit8(&client_entry->internal.refcnt);
+ silc_atomic_uninit32(&client_entry->internal.deleted);
+ silc_atomic_uninit32(&client_entry->internal.refcnt);
silc_rwlock_free(client_entry->internal.lock);
silc_free(client_entry);
}
@@ -1005,30 +1007,19 @@
SilcBool silc_client_del_client(SilcClient client, SilcClientConnection conn,
SilcClientEntry client_entry)
{
- SilcBool ret;
-
if (!client_entry)
return FALSE;
- if (silc_atomic_sub_int8(&client_entry->internal.refcnt, 1) > 0)
- return FALSE;
-
- SILC_LOG_DEBUG(("Deleting client %p", client_entry));
-
- silc_mutex_lock(conn->internal->lock);
- ret = silc_idcache_del_by_context(conn->internal->client_cache,
- client_entry, NULL);
- silc_mutex_unlock(conn->internal->lock);
-
- if (ret) {
- /* Remove from channels */
- silc_client_remove_from_channels(client, conn, client_entry);
-
- /* Free the client entry data */
- silc_client_del_client_entry(client, conn, client_entry);
+ if (silc_atomic_sub_int32(&client_entry->internal.deleted, 1) != 0)
+ {
+ SILC_LOG_DEBUG(("** WARNING ** Deleting a client twice %p", client_entry));
+// asm("int3");
+ return FALSE;
}
- return ret;
+ silc_client_unref_client(client, conn, client_entry);
+ return TRUE;
+
}
/* Internal routine used to find client by ID and if not found this creates
@@ -1072,10 +1063,10 @@
SilcClientConnection conn,
SilcClientEntry client_entry)
{
- silc_atomic_add_int8(&client_entry->internal.refcnt, 1);
+ silc_atomic_add_int32(&client_entry->internal.refcnt, 1);
SILC_LOG_DEBUG(("Client %p refcnt %d->%d", client_entry,
- silc_atomic_get_int8(&client_entry->internal.refcnt) - 1,
- silc_atomic_get_int8(&client_entry->internal.refcnt)));
+ silc_atomic_get_int32(&client_entry->internal.refcnt) - 1,
+ silc_atomic_get_int32(&client_entry->internal.refcnt)));
return client_entry;
}
@@ -1085,10 +1076,30 @@
SilcClientEntry client_entry)
{
if (client_entry) {
+ SilcBool ret;
+
SILC_LOG_DEBUG(("Client %p refcnt %d->%d", client_entry,
- silc_atomic_get_int8(&client_entry->internal.refcnt),
- silc_atomic_get_int8(&client_entry->internal.refcnt) - 1));
- silc_client_del_client(client, conn, client_entry);
+ silc_atomic_get_int32(&client_entry->internal.refcnt),
+ silc_atomic_get_int32(&client_entry->internal.refcnt) - 1));
+
+ if (silc_atomic_sub_int32(&client_entry->internal.refcnt, 1) > 0)
+ return;
+
+ SILC_LOG_DEBUG(("Deleting client %p (%d)", client_entry,
+ silc_atomic_get_int32(&client_entry->internal.deleted)));
+
+ silc_mutex_lock(conn->internal->lock);
+ ret = silc_idcache_del_by_context(conn->internal->client_cache,
+ client_entry, NULL);
+ silc_mutex_unlock(conn->internal->lock);
+
+ if (ret) {
+ /* Remove from channels */
+ silc_client_remove_from_channels(client, conn, client_entry);
+
+ /* Free the client entry data */
+ silc_client_del_client_entry(client, conn, client_entry);
+ }
}
}
@@ -1626,7 +1637,8 @@
return NULL;
silc_rwlock_alloc(&channel->internal.lock);
- silc_atomic_init16(&channel->internal.refcnt, 0);
+ silc_atomic_init32(&channel->internal.refcnt, 0);
+ silc_atomic_init32(&channel->internal.deleted, 1);
channel->id = *channel_id;
channel->mode = mode;
@@ -1639,7 +1651,7 @@
if (!channel->channel_name) {
silc_rwlock_free(channel->internal.lock);
- silc_atomic_uninit16(&channel->internal.refcnt);
+ silc_atomic_uninit32(&channel->internal.refcnt);
silc_free(channel);
return NULL;
}
@@ -1648,7 +1660,7 @@
NULL, NULL, NULL, TRUE);
if (!channel->user_list) {
silc_rwlock_free(channel->internal.lock);
- silc_atomic_uninit16(&channel->internal.refcnt);
+ silc_atomic_uninit32(&channel->internal.refcnt);
silc_free(channel->channel_name);
silc_free(channel);
return NULL;
@@ -1659,7 +1671,7 @@
SILC_STRING_UTF8, 256, NULL);
if (!channel_namec) {
silc_rwlock_free(channel->internal.lock);
- silc_atomic_uninit16(&channel->internal.refcnt);
+ silc_atomic_uninit32(&channel->internal.refcnt);
silc_free(channel->channel_name);
silc_hash_table_free(channel->user_list);
silc_free(channel);
@@ -1672,7 +1684,7 @@
if (!silc_idcache_add(conn->internal->channel_cache, channel_namec,
&channel->id, channel)) {
silc_rwlock_free(channel->internal.lock);
- silc_atomic_uninit16(&channel->internal.refcnt);
+ silc_atomic_uninit32(&channel->internal.refcnt);
silc_free(channel_namec);
silc_free(channel->channel_name);
silc_hash_table_free(channel->user_list);
@@ -1694,67 +1706,18 @@
SilcBool silc_client_del_channel(SilcClient client, SilcClientConnection conn,
SilcChannelEntry channel)
{
- SilcIDCacheEntry id_cache;
- SilcBool ret = TRUE;
- SilcCipher key;
- SilcHmac hmac;
- char *namec;
-
if (!channel)
return FALSE;
- if (silc_atomic_sub_int16(&channel->internal.refcnt, 1) > 0)
- return FALSE;
-
- SILC_LOG_DEBUG(("Deleting channel %p", channel));
-
- silc_mutex_lock(conn->internal->lock);
- if (silc_idcache_find_by_context(conn->internal->channel_cache, channel,
- &id_cache)) {
- namec = id_cache->name;
- ret = silc_idcache_del_by_context(conn->internal->channel_cache,
- channel, NULL);
- silc_free(namec);
- }
- silc_mutex_unlock(conn->internal->lock);
-
- if (!ret)
+ if (silc_atomic_sub_int32(&channel->internal.deleted, 1) > 0)
+ {
+ SILC_LOG_DEBUG(("** WARNING ** Deleting a channel twice %p", channel));
+// asm("int3");
return FALSE;
-
- silc_client_empty_channel(client, conn, channel);
- silc_client_del_channel_private_keys(client, conn, channel);
- silc_hash_table_free(channel->user_list);
- silc_free(channel->channel_name);
- silc_free(channel->topic);
- if (channel->founder_key)
- silc_pkcs_public_key_free(channel->founder_key);
- if (channel->internal.send_key)
- silc_cipher_free(channel->internal.send_key);
- if (channel->internal.receive_key)
- silc_cipher_free(channel->internal.receive_key);
- if (channel->internal.hmac)
- silc_hmac_free(channel->internal.hmac);
- if (channel->internal.old_channel_keys) {
- silc_dlist_start(channel->internal.old_channel_keys);
- while ((key = silc_dlist_get(channel->internal.old_channel_keys)))
- silc_cipher_free(key);
- silc_dlist_uninit(channel->internal.old_channel_keys);
- }
- if (channel->internal.old_hmacs) {
- silc_dlist_start(channel->internal.old_hmacs);
- while ((hmac = silc_dlist_get(channel->internal.old_hmacs)))
- silc_hmac_free(hmac);
- silc_dlist_uninit(channel->internal.old_hmacs);
}
- if (channel->channel_pubkeys)
- silc_argument_list_free(channel->channel_pubkeys,
- SILC_ARGUMENT_PUBLIC_KEY);
- silc_atomic_uninit16(&channel->internal.refcnt);
- silc_rwlock_free(channel->internal.lock);
- silc_schedule_task_del_by_context(conn->client->schedule, channel);
- silc_free(channel);
- return ret;
+ silc_client_unref_channel(client, conn, channel);
+ return TRUE;
}
/* Replaces the channel ID of the `channel' to `new_id'. Returns FALSE
@@ -1806,10 +1769,10 @@
SilcClientConnection conn,
SilcChannelEntry channel_entry)
{
- silc_atomic_add_int16(&channel_entry->internal.refcnt, 1);
+ silc_atomic_add_int32(&channel_entry->internal.refcnt, 1);
SILC_LOG_DEBUG(("Channel %p refcnt %d->%d", channel_entry,
- silc_atomic_get_int16(&channel_entry->internal.refcnt) - 1,
- silc_atomic_get_int16(&channel_entry->internal.refcnt)));
+ silc_atomic_get_int32(&channel_entry->internal.refcnt) - 1,
+ silc_atomic_get_int32(&channel_entry->internal.refcnt)));
return channel_entry;
}
@@ -1819,11 +1782,68 @@
SilcChannelEntry channel_entry)
{
if (channel_entry) {
+ SilcIDCacheEntry id_cache;
+ SilcBool ret = TRUE;
+ SilcCipher key;
+ SilcHmac hmac;
+ char *namec;
+
SILC_LOG_DEBUG(("Channel %p refcnt %d->%d", channel_entry,
- silc_atomic_get_int16(&channel_entry->internal.refcnt),
- silc_atomic_get_int16(&channel_entry->internal.refcnt)
+ silc_atomic_get_int32(&channel_entry->internal.refcnt),
+ silc_atomic_get_int32(&channel_entry->internal.refcnt)
- 1));
- silc_client_del_channel(client, conn, channel_entry);
+
+ if (silc_atomic_sub_int32(&channel_entry->internal.refcnt, 1) > 0)
+ return;
+
+ SILC_LOG_DEBUG(("Deleting channel %p", channel_entry));
+
+ silc_mutex_lock(conn->internal->lock);
+ if (silc_idcache_find_by_context(conn->internal->channel_cache, channel_entry,
+ &id_cache)) {
+ namec = id_cache->name;
+ ret = silc_idcache_del_by_context(conn->internal->channel_cache,
+ channel_entry, NULL);
+ silc_free(namec);
+ }
+ silc_mutex_unlock(conn->internal->lock);
+
+ if (!ret)
+ return;
+
+ silc_client_empty_channel(client, conn, channel_entry);
+ silc_client_del_channel_private_keys(client, conn, channel_entry);
+ silc_hash_table_free(channel_entry->user_list);
+ silc_free(channel_entry->channel_name);
+ silc_free(channel_entry->topic);
+ if (channel_entry->founder_key)
+ silc_pkcs_public_key_free(channel_entry->founder_key);
+ if (channel_entry->internal.send_key)
+ silc_cipher_free(channel_entry->internal.send_key);
+ if (channel_entry->internal.receive_key)
+ silc_cipher_free(channel_entry->internal.receive_key);
+ if (channel_entry->internal.hmac)
+ silc_hmac_free(channel_entry->internal.hmac);
+ if (channel_entry->internal.old_channel_keys) {
+ silc_dlist_start(channel_entry->internal.old_channel_keys);
+ while ((key = silc_dlist_get(channel_entry->internal.old_channel_keys)))
+ silc_cipher_free(key);
+ silc_dlist_uninit(channel_entry->internal.old_channel_keys);
+ }
+ if (channel_entry->internal.old_hmacs) {
+ silc_dlist_start(channel_entry->internal.old_hmacs);
+ while ((hmac = silc_dlist_get(channel_entry->internal.old_hmacs)))
+ silc_hmac_free(hmac);
+ silc_dlist_uninit(channel_entry->internal.old_hmacs);
+ }
+ if (channel_entry->channel_pubkeys)
+ silc_argument_list_free(channel_entry->channel_pubkeys,
+ SILC_ARGUMENT_PUBLIC_KEY);
+ silc_atomic_uninit32(&channel_entry->internal.deleted);
+ silc_atomic_uninit32(&channel_entry->internal.refcnt);
+ silc_rwlock_free(channel_entry->internal.lock);
+ silc_schedule_task_del_by_context(conn->client->schedule, channel_entry);
+ silc_free(channel_entry);
}
}
@@ -2059,7 +2079,7 @@
return NULL;
silc_rwlock_alloc(&server_entry->internal.lock);
- silc_atomic_init8(&server_entry->internal.refcnt, 0);
+ silc_atomic_init32(&server_entry->internal.refcnt, 0);
server_entry->id = *server_id;
if (server_name)
server_entry->server_name = strdup(server_name);
@@ -2111,7 +2131,7 @@
if (!server)
return FALSE;
- if (silc_atomic_sub_int8(&server->internal.refcnt, 1) > 0)
+ if (silc_atomic_sub_int32(&server->internal.refcnt, 1) > 0)
return FALSE;
SILC_LOG_DEBUG(("Deleting server %p", server));
@@ -2130,7 +2150,7 @@
silc_free(server->server_info);
if (server->public_key)
silc_pkcs_public_key_free(server->public_key);
- silc_atomic_uninit8(&server->internal.refcnt);
+ silc_atomic_uninit32(&server->internal.refcnt);
silc_rwlock_free(server->internal.lock);
silc_free(server);
@@ -2198,10 +2218,10 @@
SilcClientConnection conn,
SilcServerEntry server_entry)
{
- silc_atomic_add_int8(&server_entry->internal.refcnt, 1);
+ silc_atomic_add_int32(&server_entry->internal.refcnt, 1);
SILC_LOG_DEBUG(("Server %p refcnt %d->%d", server_entry,
- silc_atomic_get_int8(&server_entry->internal.refcnt) - 1,
- silc_atomic_get_int8(&server_entry->internal.refcnt)));
+ silc_atomic_get_int32(&server_entry->internal.refcnt) - 1,
+ silc_atomic_get_int32(&server_entry->internal.refcnt)));
return server_entry;
}
@@ -2212,8 +2232,8 @@
{
if (server_entry) {
SILC_LOG_DEBUG(("Server %p refcnt %d->%d", server_entry,
- silc_atomic_get_int8(&server_entry->internal.refcnt),
- silc_atomic_get_int8(&server_entry->internal.refcnt)
+ silc_atomic_get_int32(&server_entry->internal.refcnt),
+ silc_atomic_get_int32(&server_entry->internal.refcnt)
- 1));
silc_client_del_server(client, conn, server_entry);
}
diff -ru silc-client-orig/lib/silcclient/client_internal.h silc-client-1.1.4/lib/silcclient/client_internal.h
--- silc-client-orig/lib/silcclient/client_internal.h 2008-03-14 07:06:09.000000000 -0500
+++ silc-client-1.1.4/lib/silcclient/client_internal.h 2008-04-19 10:04:19.000000000 -0500
@@ -108,7 +108,7 @@
char *silc_client_version; /* Version set by application */
SilcClientRunning running; /* Running/Stopped callback */
void *running_context; /* Context for runnign callback */
- SilcAtomic16 conns; /* Number of connections in client */
+ SilcAtomic32 conns; /* Number of connections in client */
SilcUInt16 next_session_id; /* Next FTP session ID */
/* Events */
diff -ru silc-client-orig/lib/silccore/silcpacket.c silc-client-1.1.4/lib/silccore/silcpacket.c
--- silc-client-orig/lib/silccore/silcpacket.c 2008-03-14 07:06:09.000000000 -0500
+++ silc-client-1.1.4/lib/silccore/silcpacket.c 2008-04-19 09:58:22.000000000 -0500
@@ -81,7 +81,7 @@
unsigned char *dst_id; /* Destination ID */
SilcUInt32 send_psn; /* Sending sequence */
SilcUInt32 receive_psn; /* Receiving sequence */
- SilcAtomic8 refcnt; /* Reference counter */
+ SilcAtomic32 refcnt; /* Reference counter */
SilcUInt8 sid; /* Security ID, set if IV included */
unsigned int src_id_len : 6;
unsigned int src_id_type : 2;
@@ -697,7 +697,7 @@
return NULL;
ps->stream = stream;
- silc_atomic_init8(&ps->refcnt, 1);
+ silc_atomic_init32(&ps->refcnt, 1);
silc_mutex_alloc(&ps->lock);
/* Allocate out buffer */
@@ -818,7 +818,7 @@
return NULL;
ps->sc = stream->sc;
- silc_atomic_init8(&ps->refcnt, 1);
+ silc_atomic_init32(&ps->refcnt, 1);
silc_mutex_alloc(&ps->lock);
/* Set the UDP packet stream as underlaying stream */
@@ -886,7 +886,7 @@
if (!stream)
return;
- if (silc_atomic_sub_int8(&stream->refcnt, 1) > 0) {
+ if (silc_atomic_sub_int32(&stream->refcnt, 1) > 0) {
stream->destroyed = TRUE;
SILC_LOG_DEBUG(("Marking packet stream %p destroyed", stream));
@@ -971,7 +971,7 @@
silc_free(stream->src_id);
silc_free(stream->dst_id);
- silc_atomic_uninit8(&stream->refcnt);
+ silc_atomic_uninit32(&stream->refcnt);
silc_mutex_free(stream->lock);
silc_free(stream);
}
@@ -1152,10 +1152,10 @@
void silc_packet_stream_ref(SilcPacketStream stream)
{
- silc_atomic_add_int8(&stream->refcnt, 1);
+ silc_atomic_add_int32(&stream->refcnt, 1);
SILC_LOG_DEBUG(("Stream %p, refcnt %d->%d", stream,
- silc_atomic_get_int8(&stream->refcnt) - 1,
- silc_atomic_get_int8(&stream->refcnt)));
+ silc_atomic_get_int32(&stream->refcnt) - 1,
+ silc_atomic_get_int32(&stream->refcnt)));
}
/* Unreference packet stream */
@@ -1163,11 +1163,11 @@
void silc_packet_stream_unref(SilcPacketStream stream)
{
SILC_LOG_DEBUG(("Stream %p, refcnt %d->%d", stream,
- silc_atomic_get_int8(&stream->refcnt),
- silc_atomic_get_int8(&stream->refcnt) - 1));
- if (silc_atomic_sub_int8(&stream->refcnt, 1) > 0)
+ silc_atomic_get_int32(&stream->refcnt),
+ silc_atomic_get_int32(&stream->refcnt) - 1));
+ if (silc_atomic_sub_int32(&stream->refcnt, 1) > 0)
return;
- silc_atomic_add_int8(&stream->refcnt, 1);
+ silc_atomic_add_int32(&stream->refcnt, 1);
silc_packet_stream_destroy(stream);
}