Avoid preallocated streams in tcp.c

We don't know when the caller might be done with a stream, so we
can end up with code overwriting things in a stream that is in use
elsewhere.

Solve the issue by returning a new stream each time and leave it
up to the callers to free it.
This commit is contained in:
Pierre Ossman 2019-04-12 14:22:35 +02:00
parent 75221eb3c5
commit c6d8b933c8
14 changed files with 36 additions and 45 deletions

View File

@ -137,6 +137,7 @@ channel_send(STREAM s, VCHANNEL * channel)
out_uint8a(s, data, thislength);
s_mark_end(s);
sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
s_free(s);
data += thislength;
}

View File

@ -52,6 +52,7 @@ cliprdr_send_packet(uint16 type, uint16 status, uint8 * data, uint32 length)
out_uint32(s, 0); /* pad? */
s_mark_end(s);
channel_send(s, cliprdr_channel);
s_free(s);
}
/* Helper which announces our readiness to supply clipboard data

1
cssp.c
View File

@ -575,6 +575,7 @@ cssp_send_tsrequest(STREAM token, STREAM auth, STREAM pubkey)
s_free(h1);
tcp_send(s);
s_free(s);
// cleanup
xfree(message.data);

3
dvc.c
View File

@ -268,6 +268,7 @@ dvc_send(const char *name, STREAM s)
s_mark_end(ls);
channel_send(ls, dvc_channel);
s_free(ls);
}
@ -292,6 +293,7 @@ dvc_send_capabilities_response()
s_mark_end(s);
channel_send(s, dvc_channel);
s_free(s);
}
static void
@ -320,6 +322,7 @@ dvc_send_create_response(RD_BOOL success, dvc_hdr_t hdr, uint32 channelid)
s_mark_end(s);
channel_send(s, dvc_channel);
s_free(s);
}
static void

2
iso.c
View File

@ -55,6 +55,7 @@ iso_send_msg(uint8 code)
s_mark_end(s);
tcp_send(s);
s_free(s);
}
static void
@ -95,6 +96,7 @@ iso_send_connection_request(char *username, uint32 neg_proto)
s_mark_end(s);
tcp_send(s);
s_free(s);
}
/* Receive a message on the ISO layer, return code */

View File

@ -97,6 +97,7 @@ licence_info(uint8 * client_random, uint8 * rsa_data,
s_mark_end(s);
sec_send(s, sec_flags);
s_free(s);
}
/* Send a new licence request packet */
@ -138,6 +139,7 @@ licence_send_new_licence_request(uint8 * client_random, uint8 * rsa_data, char *
s_mark_end(s);
sec_send(s, sec_flags);
s_free(s);
}
/* Process a licence request packet */
@ -214,6 +216,7 @@ licence_send_platform_challenge_response(uint8 * token, uint8 * crypt_hwid, uint
s_mark_end(s);
sec_send(s, sec_flags);
s_free(s);
}
/* Parse an platform challenge request packet */

View File

@ -165,4 +165,5 @@ lspci_send(const char *output)
s = channel_init(lspci_channel, len);
out_uint8a(s, output, len) s_mark_end(s);
channel_send(s, lspci_channel);
s_free(s);
}

5
mcs.c
View File

@ -86,6 +86,7 @@ mcs_send_connect_initial(STREAM mcs_data)
s_mark_end(s);
iso_send(s);
s_free(s);
}
/* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
@ -159,6 +160,7 @@ mcs_send_edrq(void)
s_mark_end(s);
iso_send(s);
s_free(s);
}
/* Send an AUrq message (ASN.1 PER) */
@ -173,6 +175,7 @@ mcs_send_aurq(void)
s_mark_end(s);
iso_send(s);
s_free(s);
}
/* Expect a AUcf message (ASN.1 PER) */
@ -226,6 +229,7 @@ mcs_send_cjrq(uint16 chanid)
s_mark_end(s);
iso_send(s);
s_free(s);
}
/* Expect a CJcf message (ASN.1 PER) */
@ -285,6 +289,7 @@ mcs_send_dpu(unsigned short reason)
s_mark_end(s);
iso_send(s);
s_free(s);
}
/* Initialise an MCS transport data packet */

8
rdp.c
View File

@ -535,6 +535,7 @@ rdp_send_client_info_pdu(uint32 flags, char *domain, char *user,
g_redirect = False;
sec_send(s, sec_flags);
s_free(s);
}
/* Send a control PDU */
@ -551,6 +552,7 @@ rdp_send_control(uint16 action)
s_mark_end(s);
rdp_send_data(s, RDP_DATA_PDU_CONTROL);
s_free(s);
}
/* Send a synchronisation PDU */
@ -568,6 +570,7 @@ rdp_send_synchronise(void)
s_mark_end(s);
rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
s_free(s);
}
/* Send a single input event */
@ -591,6 +594,7 @@ rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 par
s_mark_end(s);
rdp_send_data(s, RDP_DATA_PDU_INPUT);
s_free(s);
}
/* Send a Suppress Output PDU */
@ -625,6 +629,7 @@ rdp_send_suppress_output_pdu(enum RDP_SUPPRESS_STATUS allowupdates)
s_mark_end(s);
rdp_send_data(s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS);
s_free(s);
current_status = allowupdates;
}
@ -669,6 +674,7 @@ rdp_enum_bmpcache2(void)
s_mark_end(s);
rdp_send_data(s, 0x2b);
s_free(s);
offset += 169;
}
@ -691,6 +697,7 @@ rdp_send_fonts(uint16 seq)
s_mark_end(s);
rdp_send_data(s, RDP_DATA_PDU_FONT2);
s_free(s);
}
/* Output general capability set (TS_GENERAL_CAPABILITYSET) */
@ -1129,6 +1136,7 @@ rdp_send_confirm_active(void)
s_mark_end(s);
sec_send(s, sec_flags);
s_free(s);
}
/* Process a general capability set */

View File

@ -204,6 +204,7 @@ rdpdr_send_client_announce_reply(void)
out_uint32_be(s, g_client_id); /* ClientID */
s_mark_end(s);
channel_send(s, rdpdr_channel);
s_free(s);
}
@ -233,6 +234,7 @@ rdpdr_send_client_name_request(void)
out_stream(s, &name);
s_mark_end(s);
channel_send(s, rdpdr_channel);
s_free(s);
}
/* Returns the size of the payload of the announce packet */
@ -357,6 +359,7 @@ rdpdr_send_client_device_list_announce(void)
s_mark_end(s);
channel_send(s, rdpdr_channel);
s_free(s);
}
void
@ -392,6 +395,7 @@ rdpdr_send_completion(uint32 device, uint32 id, uint32 status, uint32 result, ui
/* hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8); */
channel_send(s, rdpdr_channel);
s_free(s);
#ifdef WITH_SCARD
scard_unlock(SCARD_LOCK_RDPDR);
#endif
@ -868,6 +872,7 @@ rdpdr_send_client_capability_response(void)
s_mark_end(s);
channel_send(s, rdpdr_channel);
s_free(s);
}
static void

View File

@ -103,6 +103,7 @@ rdpsnd_send_waveconfirm(uint16 tick, uint8 packet_index)
out_uint8(s, 0);
s_mark_end(s);
rdpsnd_send(s);
s_free(s);
logger(Sound, Debug, "rdpsnd_send_waveconfirm(), tick=%u, index=%u",
(unsigned) tick, (unsigned) packet_index);
@ -259,6 +260,7 @@ rdpsnd_process_negotiate(STREAM in)
(int) format_count);
rdpsnd_send(out);
s_free(out);
rdpsnd_negotiated = True;
}
@ -286,6 +288,7 @@ rdpsnd_process_training(STREAM in)
out_uint16_le(out, packsize);
s_mark_end(out);
rdpsnd_send(out);
s_free(out);
}
static void

View File

@ -445,6 +445,7 @@ seamless_send(const char *command, const char *format, ...)
logger(Core, Debug, "seamless_send(), sending '%s'", buf);
channel_send(s, seamless_channel);
s_free(s);
return seamless_serial++;
}

View File

@ -389,6 +389,7 @@ sec_establish_key(void)
s_mark_end(s);
sec_send(s, flags);
s_free(s);
}
/* Output connect initial data blob */

46
tcp.c
View File

@ -58,12 +58,6 @@
#define INADDR_NONE ((unsigned long) -1)
#endif
#ifdef WITH_SCARD
#define STREAM_COUNT 8
#else
#define STREAM_COUNT 1
#endif
#ifdef IPv6
static struct addrinfo *g_server_address = NULL;
#else
@ -75,7 +69,6 @@ static RD_BOOL g_ssl_initialized = False;
static int g_sock;
static RD_BOOL g_run_ui = False;
static struct stream g_in;
static struct stream g_out[STREAM_COUNT];
int g_tcp_port_rdp = TCP_PORT_RDP;
extern RD_BOOL g_exit_mainloop;
@ -109,20 +102,7 @@ tcp_can_send(int sck, int millis)
STREAM
tcp_init(uint32 maxlen)
{
static int cur_stream_id = 0;
STREAM result = NULL;
#ifdef WITH_SCARD
scard_lock(SCARD_LOCK_TCP);
#endif
result = &g_out[cur_stream_id];
s_realloc(result, maxlen);
s_reset(result);
cur_stream_id = (cur_stream_id + 1) % STREAM_COUNT;
#ifdef WITH_SCARD
scard_unlock(SCARD_LOCK_TCP);
#endif
return result;
return s_alloc(maxlen);
}
/* Send TCP transport data packet */
@ -527,7 +507,6 @@ tcp_connect(char *server)
{
socklen_t option_len;
uint32 option_value;
int i;
char buf[NI_MAXHOST];
#ifdef IPv6
@ -678,12 +657,6 @@ tcp_connect(char *server)
g_in.size = 4096;
g_in.data = (uint8 *) xmalloc(g_in.size);
for (i = 0; i < STREAM_COUNT; i++)
{
g_out[i].size = 4096;
g_out[i].data = (uint8 *) xmalloc(g_out[i].size);
}
/* After successful connect: update the last server name */
if (g_last_server_name)
xfree(g_last_server_name);
@ -695,8 +668,6 @@ tcp_connect(char *server)
void
tcp_disconnect(void)
{
int i;
if (g_ssl_initialized) {
(void)gnutls_bye(g_tls_session, GNUTLS_SHUT_WR);
gnutls_deinit(g_tls_session);
@ -712,13 +683,6 @@ tcp_disconnect(void)
g_in.size = 0;
xfree(g_in.data);
g_in.data = NULL;
for (i = 0; i < STREAM_COUNT; i++)
{
g_out[i].size = 0;
xfree(g_out[i].data);
g_out[i].data = NULL;
}
}
char *
@ -752,16 +716,8 @@ tcp_is_connected()
void
tcp_reset_state(void)
{
int i;
/* Clear the incoming stream */
s_reset(&g_in);
/* Clear the outgoing stream(s) */
for (i = 0; i < STREAM_COUNT; i++)
{
s_reset(&g_out[i]);
}
}
void