summaryrefslogtreecommitdiffstats
path: root/meta/recipes-support/curl/curl/CVE-2023-27533.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-support/curl/curl/CVE-2023-27533.patch')
-rw-r--r--meta/recipes-support/curl/curl/CVE-2023-27533.patch208
1 files changed, 208 insertions, 0 deletions
diff --git a/meta/recipes-support/curl/curl/CVE-2023-27533.patch b/meta/recipes-support/curl/curl/CVE-2023-27533.patch
new file mode 100644
index 0000000000..b69b20c85a
--- /dev/null
+++ b/meta/recipes-support/curl/curl/CVE-2023-27533.patch
@@ -0,0 +1,208 @@
+From 538b1e79a6e7b0bb829ab4cecc828d32105d0684 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Mon, 6 Mar 2023 12:07:33 +0100
+Subject: [PATCH] telnet: parse telnet options without sscanf & only accept option arguments in ascii
+
+To avoid embedded telnet negotiation commands etc.
+
+Reported-by: Harry Sintonen
+Closes #10728
+
+CVE: CVE-2023-27533
+Upstream-Status: Backport [https://github.com/curl/curl/commit/0c28ba2faae2d7da780a66d2446045a560192cdc && https://github.com/curl/curl/commit/538b1e79a6e7b0bb829ab4cecc828d32105d0684]
+
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ lib/telnet.c | 149 +++++++++++++++++++++++++++++++--------------------
+ 1 file changed, 91 insertions(+), 58 deletions(-)
+
+diff --git a/lib/telnet.c b/lib/telnet.c
+index e709973..3ecd680 100644
+--- a/lib/telnet.c
++++ b/lib/telnet.c
+@@ -768,22 +768,32 @@ static void printsub(struct Curl_easy *data,
+ }
+ }
+
++static bool str_is_nonascii(const char *str)
++{
++ size_t len = strlen(str);
++ while(len--) {
++ if(*str & 0x80)
++ return TRUE;
++ str++;
++ }
++ return FALSE;
++}
++
+ static CURLcode check_telnet_options(struct Curl_easy *data)
+ {
+ struct curl_slist *head;
+ struct curl_slist *beg;
+- char option_keyword[128] = "";
+- char option_arg[256] = "";
+ struct TELNET *tn = data->req.p.telnet;
+- struct connectdata *conn = data->conn;
+ CURLcode result = CURLE_OK;
+- int binary_option;
+
+ /* Add the user name as an environment variable if it
+ was given on the command line */
+ if(data->state.aptr.user) {
+- msnprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user);
+- beg = curl_slist_append(tn->telnet_vars, option_arg);
++ char buffer[256];
++ if(str_is_nonascii(data->conn->user))
++ return CURLE_BAD_FUNCTION_ARGUMENT;
++ msnprintf(buffer, sizeof(buffer), "USER,%s", data->conn->user);
++ beg = curl_slist_append(tn->telnet_vars, buffer);
+ if(!beg) {
+ curl_slist_free_all(tn->telnet_vars);
+ tn->telnet_vars = NULL;
+@@ -793,68 +803,91 @@ static CURLcode check_telnet_options(struct Curl_easy *data)
+ tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
+ }
+
+- for(head = data->set.telnet_options; head; head = head->next) {
+- if(sscanf(head->data, "%127[^= ]%*[ =]%255s",
+- option_keyword, option_arg) == 2) {
+-
+- /* Terminal type */
+- if(strcasecompare(option_keyword, "TTYPE")) {
+- strncpy(tn->subopt_ttype, option_arg, 31);
+- tn->subopt_ttype[31] = 0; /* String termination */
+- tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES;
++ for(head = data->set.telnet_options; head && !result; head = head->next) {
++ size_t olen;
++ char *option = head->data;
++ char *arg;
++ char *sep = strchr(option, '=');
++ if(sep) {
++ olen = sep - option;
++ arg = ++sep;
++ if(str_is_nonascii(arg))
+ continue;
+- }
++ switch(olen) {
++ case 5:
++ /* Terminal type */
++ if(strncasecompare(option, "TTYPE", 5)) {
++ strncpy(tn->subopt_ttype, arg, 31);
++ tn->subopt_ttype[31] = 0; /* String termination */
++ tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES;
++ }
++ else
++ result = CURLE_UNKNOWN_OPTION;
++ break;
+
+- /* Display variable */
+- if(strcasecompare(option_keyword, "XDISPLOC")) {
+- strncpy(tn->subopt_xdisploc, option_arg, 127);
+- tn->subopt_xdisploc[127] = 0; /* String termination */
+- tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES;
+- continue;
+- }
++ case 8:
++ /* Display variable */
++ if(strncasecompare(option, "XDISPLOC", 8)) {
++ strncpy(tn->subopt_xdisploc, arg, 127);
++ tn->subopt_xdisploc[127] = 0; /* String termination */
++ tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES;
++ }
++ else
++ result = CURLE_UNKNOWN_OPTION;
++ break;
+
+- /* Environment variable */
+- if(strcasecompare(option_keyword, "NEW_ENV")) {
+- beg = curl_slist_append(tn->telnet_vars, option_arg);
+- if(!beg) {
+- result = CURLE_OUT_OF_MEMORY;
+- break;
++ case 7:
++ /* Environment variable */
++ if(strncasecompare(option, "NEW_ENV", 7)) {
++ beg = curl_slist_append(tn->telnet_vars, arg);
++ if(!beg) {
++ result = CURLE_OUT_OF_MEMORY;
++ break;
++ }
++ tn->telnet_vars = beg;
++ tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
+ }
+- tn->telnet_vars = beg;
+- tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
+- continue;
+- }
++ else
++ result = CURLE_UNKNOWN_OPTION;
++ break;
+
+- /* Window Size */
+- if(strcasecompare(option_keyword, "WS")) {
+- if(sscanf(option_arg, "%hu%*[xX]%hu",
+- &tn->subopt_wsx, &tn->subopt_wsy) == 2)
+- tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES;
+- else {
+- failf(data, "Syntax error in telnet option: %s", head->data);
+- result = CURLE_SETOPT_OPTION_SYNTAX;
+- break;
++ case 2:
++ /* Window Size */
++ if(strncasecompare(option, "WS", 2)) {
++ if(sscanf(arg, "%hu%*[xX]%hu",
++ &tn->subopt_wsx, &tn->subopt_wsy) == 2)
++ tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES;
++ else {
++ failf(data, "Syntax error in telnet option: %s", head->data);
++ result = CURLE_SETOPT_OPTION_SYNTAX;
++ }
+ }
+- continue;
+- }
++ else
++ result = CURLE_UNKNOWN_OPTION;
++ break;
+
+- /* To take care or not of the 8th bit in data exchange */
+- if(strcasecompare(option_keyword, "BINARY")) {
+- binary_option = atoi(option_arg);
+- if(binary_option != 1) {
+- tn->us_preferred[CURL_TELOPT_BINARY] = CURL_NO;
+- tn->him_preferred[CURL_TELOPT_BINARY] = CURL_NO;
++ case 6:
++ /* To take care or not of the 8th bit in data exchange */
++ if(strncasecompare(option, "BINARY", 6)) {
++ int binary_option = atoi(arg);
++ if(binary_option != 1) {
++ tn->us_preferred[CURL_TELOPT_BINARY] = CURL_NO;
++ tn->him_preferred[CURL_TELOPT_BINARY] = CURL_NO;
++ }
+ }
+- continue;
++ else
++ result = CURLE_UNKNOWN_OPTION;
++ break;
++ default:
++ failf(data, "Unknown telnet option %s", head->data);
++ result = CURLE_UNKNOWN_OPTION;
++ break;
+ }
+-
+- failf(data, "Unknown telnet option %s", head->data);
+- result = CURLE_UNKNOWN_OPTION;
+- break;
+ }
+- failf(data, "Syntax error in telnet option: %s", head->data);
+- result = CURLE_SETOPT_OPTION_SYNTAX;
+- break;
++ else {
++ failf(data, "Syntax error in telnet option: %s", head->data);
++ result = CURLE_SETOPT_OPTION_SYNTAX;
++ }
+ }
+
+ if(result) {
+--
+2.25.1
+