diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2014-05-24 18:18:11 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2014-05-24 18:18:11 +0200 |
commit | faae8f470b3f1cec6b77c7844b78ac64ce2845b6 (patch) | |
tree | 0c78cdda29a5b02d8d32e96bc11c4a155bce5212 /src/plugins | |
parent | 7aaf3be15bdb3ff2bd9815cc35bd1699c20ce7a6 (diff) | |
download | weechat-faae8f470b3f1cec6b77c7844b78ac64ce2845b6.zip |
relay: check pointers received in hdata command to prevent crashes with bad pointers (WeeChat protocol)
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/relay/weechat/relay-weechat-msg.c | 32 | ||||
-rw-r--r-- | src/plugins/relay/weechat/relay-weechat-msg.h | 4 | ||||
-rw-r--r-- | src/plugins/relay/weechat/relay-weechat-protocol.c | 66 |
3 files changed, 75 insertions, 27 deletions
diff --git a/src/plugins/relay/weechat/relay-weechat-msg.c b/src/plugins/relay/weechat/relay-weechat-msg.c index c05aa1e44..0d2bb4809 100644 --- a/src/plugins/relay/weechat/relay-weechat-msg.c +++ b/src/plugins/relay/weechat/relay-weechat-msg.c @@ -541,9 +541,13 @@ relay_weechat_msg_add_hdata_path (struct t_relay_weechat_msg *msg, * * Argument keys is optional: if not NULL, comma-separated list of keys to * return for hdata. + * + * Returns: + * 1: hdata added to message + * 0: error (hdata NOT added to message) */ -void +int relay_weechat_msg_add_hdata (struct t_relay_weechat_msg *msg, const char *path, const char *keys) { @@ -553,9 +557,11 @@ relay_weechat_msg_add_hdata (struct t_relay_weechat_msg *msg, const char *hdata_name, *array_size; void *pointer, **path_pointers; long unsigned int value; - int num_keys, num_path, i, type, pos_count, count, rc; + int rc, num_keys, num_path, i, type, pos_count, count, rc_sscanf; uint32_t count32; + rc = 0; + hdata_head = NULL; list_keys = NULL; num_keys = 0; @@ -587,9 +593,23 @@ relay_weechat_msg_add_hdata (struct t_relay_weechat_msg *msg, pos[0] = '\0'; if (strncmp (list_path[0], "0x", 2) == 0) { - rc = sscanf (list_path[0], "%lx", &value); - if ((rc != EOF) && (rc != 0)) + rc_sscanf = sscanf (list_path[0], "%lx", &value); + if ((rc_sscanf != EOF) && (rc_sscanf != 0)) + { pointer = (void *)value; + if (!weechat_hdata_check_pointer (ptr_hdata_head, NULL, pointer)) + { + if (weechat_relay_plugin->debug >= 1) + { + weechat_printf (NULL, + _("%s: invalid pointer in hdata path: " + "\"%s\""), + RELAY_PLUGIN_NAME, + path); + } + goto end; + } + } } else pointer = weechat_hdata_get_list (ptr_hdata_head, list_path[0]); @@ -709,6 +729,8 @@ relay_weechat_msg_add_hdata (struct t_relay_weechat_msg *msg, count32 = htonl ((uint32_t)count); relay_weechat_msg_set_bytes (msg, pos_count, &count32, 4); + rc = 1; + end: if (list_keys) weechat_string_free_split (list_keys); @@ -720,6 +742,8 @@ end: free (path_returned); if (hdata_head) free (hdata_head); + + return rc; } /* diff --git a/src/plugins/relay/weechat/relay-weechat-msg.h b/src/plugins/relay/weechat/relay-weechat-msg.h index 4b4412d4a..0284563a5 100644 --- a/src/plugins/relay/weechat/relay-weechat-msg.h +++ b/src/plugins/relay/weechat/relay-weechat-msg.h @@ -68,8 +68,8 @@ extern void relay_weechat_msg_add_pointer (struct t_relay_weechat_msg *msg, void *pointer); extern void relay_weechat_msg_add_time (struct t_relay_weechat_msg *msg, time_t time); -extern void relay_weechat_msg_add_hdata (struct t_relay_weechat_msg *msg, - const char *path, const char *keys); +extern int relay_weechat_msg_add_hdata (struct t_relay_weechat_msg *msg, + const char *path, const char *keys); extern void relay_weechat_msg_add_infolist (struct t_relay_weechat_msg *msg, const char *name, void *pointer, diff --git a/src/plugins/relay/weechat/relay-weechat-protocol.c b/src/plugins/relay/weechat/relay-weechat-protocol.c index d95747179..863a9b018 100644 --- a/src/plugins/relay/weechat/relay-weechat-protocol.c +++ b/src/plugins/relay/weechat/relay-weechat-protocol.c @@ -215,9 +215,11 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(hdata) msg = relay_weechat_msg_new (id); if (msg) { - relay_weechat_msg_add_hdata (msg, argv[0], - (argc > 1) ? argv_eol[1] : NULL); - relay_weechat_msg_send (client, msg); + if (relay_weechat_msg_add_hdata (msg, argv[0], + (argc > 1) ? argv_eol[1] : NULL)) + { + relay_weechat_msg_send (client, msg); + } relay_weechat_msg_free (msg); } @@ -311,7 +313,18 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(nicklist) { ptr_buffer = relay_weechat_protocol_get_buffer (argv[0]); if (!ptr_buffer) + { + if (weechat_relay_plugin->debug >= 1) + { + weechat_printf (NULL, + _("%s: invalid buffer pointer in message: " + "\"%s %s\""), + RELAY_PLUGIN_NAME, + command, + argv_eol[0]); + } return WEECHAT_RC_OK; + } } msg = relay_weechat_msg_new (id); @@ -379,26 +392,37 @@ RELAY_WEECHAT_PROTOCOL_CALLBACK(input) RELAY_WEECHAT_PROTOCOL_MIN_ARGS(2); ptr_buffer = relay_weechat_protocol_get_buffer (argv[0]); - if (ptr_buffer) + if (!ptr_buffer) { - pos = strchr (argv_eol[0], ' '); - if (pos) + if (weechat_relay_plugin->debug >= 1) { - /* - * use a timer to execute the command after we go back in the - * WeeChat main loop (some commands like /upgrade executed now can - * cause a crash) - */ - timer_args = malloc (2 * sizeof (*timer_args)); - if (timer_args) - { - timer_args[0] = strdup (weechat_buffer_get_string (ptr_buffer, - "full_name")); - timer_args[1] = strdup (pos + 1); - weechat_hook_timer (1, 0, 1, - &relay_weechat_protocol_input_timer_cb, - timer_args); - } + weechat_printf (NULL, + _("%s: invalid buffer pointer in message: " + "\"%s %s\""), + RELAY_PLUGIN_NAME, + command, + argv_eol[0]); + } + return WEECHAT_RC_OK; + } + + pos = strchr (argv_eol[0], ' '); + if (pos) + { + /* + * use a timer to execute the command after we go back in the + * WeeChat main loop (some commands like /upgrade executed now can + * cause a crash) + */ + timer_args = malloc (2 * sizeof (*timer_args)); + if (timer_args) + { + timer_args[0] = strdup (weechat_buffer_get_string (ptr_buffer, + "full_name")); + timer_args[1] = strdup (pos + 1); + weechat_hook_timer (1, 0, 1, + &relay_weechat_protocol_input_timer_cb, + timer_args); } } |