diff options
| author | Peter Marko <peter.marko@siemens.com> | 2024-01-17 00:29:46 +0100 |
|---|---|---|
| committer | Steve Sakoman <steve@sakoman.com> | 2024-01-24 04:04:55 -1000 |
| commit | 906af0cb8b86afb595f1b78482634ed4217d491e (patch) | |
| tree | 0d83f2b819a75bf2c785e8b0e66c86e7dbd53269 | |
| parent | 426dfdc8d246cae5f4fd37415ece280f169bee08 (diff) | |
| download | poky-906af0cb8b86afb595f1b78482634ed4217d491e.tar.gz | |
dropbear: backport patch for CVE-2023-48795
Documentation for this patch is under
https://github.com/mkj/dropbear/commit/66bc1fcdee594c6cb1139df0ef8a6c9c5fc3fde3
(From OE-Core rev: 626711a95f387090a4705401d2f9406909821f95)
Signed-off-by: Peter Marko <peter.marko@siemens.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
| -rw-r--r-- | meta/recipes-core/dropbear/dropbear.inc | 1 | ||||
| -rw-r--r-- | meta/recipes-core/dropbear/dropbear/CVE-2023-48795.patch | 234 |
2 files changed, 235 insertions, 0 deletions
diff --git a/meta/recipes-core/dropbear/dropbear.inc b/meta/recipes-core/dropbear/dropbear.inc index e61930f7db..a32242949b 100644 --- a/meta/recipes-core/dropbear/dropbear.inc +++ b/meta/recipes-core/dropbear/dropbear.inc | |||
| @@ -30,6 +30,7 @@ SRC_URI = "http://matt.ucc.asn.au/dropbear/releases/dropbear-${PV}.tar.bz2 \ | |||
| 30 | ${@bb.utils.contains('PACKAGECONFIG', 'disable-weak-ciphers', 'file://dropbear-disable-weak-ciphers.patch', '', d)} \ | 30 | ${@bb.utils.contains('PACKAGECONFIG', 'disable-weak-ciphers', 'file://dropbear-disable-weak-ciphers.patch', '', d)} \ |
| 31 | file://CVE-2021-36369.patch \ | 31 | file://CVE-2021-36369.patch \ |
| 32 | file://CVE-2023-36328.patch \ | 32 | file://CVE-2023-36328.patch \ |
| 33 | file://CVE-2023-48795.patch \ | ||
| 33 | " | 34 | " |
| 34 | 35 | ||
| 35 | PAM_SRC_URI = "file://0005-dropbear-enable-pam.patch \ | 36 | PAM_SRC_URI = "file://0005-dropbear-enable-pam.patch \ |
diff --git a/meta/recipes-core/dropbear/dropbear/CVE-2023-48795.patch b/meta/recipes-core/dropbear/dropbear/CVE-2023-48795.patch new file mode 100644 index 0000000000..6800672ab0 --- /dev/null +++ b/meta/recipes-core/dropbear/dropbear/CVE-2023-48795.patch | |||
| @@ -0,0 +1,234 @@ | |||
| 1 | From 6e43be5c7b99dbee49dc72b6f989f29fdd7e9356 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Matt Johnston <matt@ucc.asn.au> | ||
| 3 | Date: Mon, 20 Nov 2023 14:02:47 +0800 | ||
| 4 | Subject: [PATCH] Implement Strict KEX mode | ||
| 5 | |||
| 6 | As specified by OpenSSH with kex-strict-c-v00@openssh.com and | ||
| 7 | kex-strict-s-v00@openssh.com. | ||
| 8 | |||
| 9 | CVE: CVE-2023-48795 | ||
| 10 | Upstream-Status: Backport [https://github.com/mkj/dropbear/commit/6e43be5c7b99dbee49dc72b6f989f29fdd7e9356] | ||
| 11 | |||
| 12 | Signed-off-by: Peter Marko <peter.marko@siemens.com> | ||
| 13 | --- | ||
| 14 | cli-session.c | 11 +++++++++++ | ||
| 15 | common-algo.c | 6 ++++++ | ||
| 16 | common-kex.c | 26 +++++++++++++++++++++++++- | ||
| 17 | kex.h | 3 +++ | ||
| 18 | process-packet.c | 34 +++++++++++++++++++--------------- | ||
| 19 | ssh.h | 4 ++++ | ||
| 20 | svr-session.c | 3 +++ | ||
| 21 | 7 files changed, 71 insertions(+), 16 deletions(-) | ||
| 22 | |||
| 23 | diff --git a/cli-session.c b/src/cli-session.c | ||
| 24 | index 5981b2470..d261c8f82 100644 | ||
| 25 | --- a/cli-session.c | ||
| 26 | +++ b/cli-session.c | ||
| 27 | @@ -46,6 +46,7 @@ static void cli_finished(void) ATTRIB_NORETURN; | ||
| 28 | static void recv_msg_service_accept(void); | ||
| 29 | static void cli_session_cleanup(void); | ||
| 30 | static void recv_msg_global_request_cli(void); | ||
| 31 | +static void cli_algos_initialise(void); | ||
| 32 | |||
| 33 | struct clientsession cli_ses; /* GLOBAL */ | ||
| 34 | |||
| 35 | @@ -114,6 +115,7 @@ void cli_session(int sock_in, int sock_out, struct dropbear_progress_connection | ||
| 36 | } | ||
| 37 | |||
| 38 | chaninitialise(cli_chantypes); | ||
| 39 | + cli_algos_initialise(); | ||
| 40 | |||
| 41 | /* Set up cli_ses vars */ | ||
| 42 | cli_session_init(proxy_cmd_pid); | ||
| 43 | @@ -473,3 +475,12 @@ void cli_dropbear_log(int priority, const char* format, va_list param) { | ||
| 44 | fflush(stderr); | ||
| 45 | } | ||
| 46 | |||
| 47 | +static void cli_algos_initialise(void) { | ||
| 48 | + algo_type *algo; | ||
| 49 | + for (algo = sshkex; algo->name; algo++) { | ||
| 50 | + if (strcmp(algo->name, SSH_STRICT_KEX_S) == 0) { | ||
| 51 | + algo->usable = 0; | ||
| 52 | + } | ||
| 53 | + } | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | diff --git a/common-algo.c b/src/common-algo.c | ||
| 57 | index 378f0ca8e..f9d46ebb6 100644 | ||
| 58 | --- a/common-algo.c | ||
| 59 | +++ b/common-algo.c | ||
| 60 | @@ -332,6 +332,12 @@ algo_type sshkex[] = { | ||
| 61 | /* Set unusable by svr_algos_initialise() */ | ||
| 62 | {SSH_EXT_INFO_C, 0, NULL, 1, NULL}, | ||
| 63 | #endif | ||
| 64 | +#endif | ||
| 65 | +#if DROPBEAR_CLIENT | ||
| 66 | + {SSH_STRICT_KEX_C, 0, NULL, 1, NULL}, | ||
| 67 | +#endif | ||
| 68 | +#if DROPBEAR_SERVER | ||
| 69 | + {SSH_STRICT_KEX_S, 0, NULL, 1, NULL}, | ||
| 70 | #endif | ||
| 71 | {NULL, 0, NULL, 0, NULL} | ||
| 72 | }; | ||
| 73 | diff --git a/common-kex.c b/src/common-kex.c | ||
| 74 | index ac8844246..8e33b12a6 100644 | ||
| 75 | --- a/common-kex.c | ||
| 76 | +++ b/common-kex.c | ||
| 77 | @@ -183,6 +183,10 @@ void send_msg_newkeys() { | ||
| 78 | gen_new_keys(); | ||
| 79 | switch_keys(); | ||
| 80 | |||
| 81 | + if (ses.kexstate.strict_kex) { | ||
| 82 | + ses.transseq = 0; | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | TRACE(("leave send_msg_newkeys")) | ||
| 86 | } | ||
| 87 | |||
| 88 | @@ -193,7 +197,11 @@ void recv_msg_newkeys() { | ||
| 89 | |||
| 90 | ses.kexstate.recvnewkeys = 1; | ||
| 91 | switch_keys(); | ||
| 92 | - | ||
| 93 | + | ||
| 94 | + if (ses.kexstate.strict_kex) { | ||
| 95 | + ses.recvseq = 0; | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | TRACE(("leave recv_msg_newkeys")) | ||
| 99 | } | ||
| 100 | |||
| 101 | @@ -551,6 +559,10 @@ void recv_msg_kexinit() { | ||
| 102 | |||
| 103 | ses.kexstate.recvkexinit = 1; | ||
| 104 | |||
| 105 | + if (ses.kexstate.strict_kex && !ses.kexstate.donefirstkex && ses.recvseq != 1) { | ||
| 106 | + dropbear_exit("First packet wasn't kexinit"); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | TRACE(("leave recv_msg_kexinit")) | ||
| 110 | } | ||
| 111 | |||
| 112 | @@ -861,6 +873,18 @@ static void read_kex_algos() { | ||
| 113 | } | ||
| 114 | #endif | ||
| 115 | |||
| 116 | + if (!ses.kexstate.donefirstkex) { | ||
| 117 | + const char* strict_name; | ||
| 118 | + if (IS_DROPBEAR_CLIENT) { | ||
| 119 | + strict_name = SSH_STRICT_KEX_S; | ||
| 120 | + } else { | ||
| 121 | + strict_name = SSH_STRICT_KEX_C; | ||
| 122 | + } | ||
| 123 | + if (buf_has_algo(ses.payload, strict_name) == DROPBEAR_SUCCESS) { | ||
| 124 | + ses.kexstate.strict_kex = 1; | ||
| 125 | + } | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | algo = buf_match_algo(ses.payload, sshkex, kexguess2, &goodguess); | ||
| 129 | allgood &= goodguess; | ||
| 130 | if (algo == NULL || algo->data == NULL) { | ||
| 131 | diff --git a/kex.h b/src/kex.h | ||
| 132 | index 77cf21a37..7fcc3c252 100644 | ||
| 133 | --- a/kex.h | ||
| 134 | +++ b/kex.h | ||
| 135 | @@ -83,6 +83,9 @@ struct KEXState { | ||
| 136 | |||
| 137 | unsigned our_first_follows_matches : 1; | ||
| 138 | |||
| 139 | + /* Boolean indicating that strict kex mode is in use */ | ||
| 140 | + unsigned int strict_kex; | ||
| 141 | + | ||
| 142 | time_t lastkextime; /* time of the last kex */ | ||
| 143 | unsigned int datatrans; /* data transmitted since last kex */ | ||
| 144 | unsigned int datarecv; /* data received since last kex */ | ||
| 145 | diff --git a/process-packet.c b/src/process-packet.c | ||
| 146 | index 945416023..133a152d0 100644 | ||
| 147 | --- a/process-packet.c | ||
| 148 | +++ b/process-packet.c | ||
| 149 | @@ -44,6 +44,7 @@ void process_packet() { | ||
| 150 | |||
| 151 | unsigned char type; | ||
| 152 | unsigned int i; | ||
| 153 | + unsigned int first_strict_kex = ses.kexstate.strict_kex && !ses.kexstate.donefirstkex; | ||
| 154 | time_t now; | ||
| 155 | |||
| 156 | TRACE2(("enter process_packet")) | ||
| 157 | @@ -54,22 +55,24 @@ void process_packet() { | ||
| 158 | now = monotonic_now(); | ||
| 159 | ses.last_packet_time_keepalive_recv = now; | ||
| 160 | |||
| 161 | - /* These packets we can receive at any time */ | ||
| 162 | - switch(type) { | ||
| 163 | |||
| 164 | - case SSH_MSG_IGNORE: | ||
| 165 | - goto out; | ||
| 166 | - case SSH_MSG_DEBUG: | ||
| 167 | - goto out; | ||
| 168 | + if (type == SSH_MSG_DISCONNECT) { | ||
| 169 | + /* Allowed at any time */ | ||
| 170 | + dropbear_close("Disconnect received"); | ||
| 171 | + } | ||
| 172 | |||
| 173 | - case SSH_MSG_UNIMPLEMENTED: | ||
| 174 | - /* debugging XXX */ | ||
| 175 | - TRACE(("SSH_MSG_UNIMPLEMENTED")) | ||
| 176 | - goto out; | ||
| 177 | - | ||
| 178 | - case SSH_MSG_DISCONNECT: | ||
| 179 | - /* TODO cleanup? */ | ||
| 180 | - dropbear_close("Disconnect received"); | ||
| 181 | + /* These packets may be received at any time, | ||
| 182 | + except during first kex with strict kex */ | ||
| 183 | + if (!first_strict_kex) { | ||
| 184 | + switch(type) { | ||
| 185 | + case SSH_MSG_IGNORE: | ||
| 186 | + goto out; | ||
| 187 | + case SSH_MSG_DEBUG: | ||
| 188 | + goto out; | ||
| 189 | + case SSH_MSG_UNIMPLEMENTED: | ||
| 190 | + TRACE(("SSH_MSG_UNIMPLEMENTED")) | ||
| 191 | + goto out; | ||
| 192 | + } | ||
| 193 | } | ||
| 194 | |||
| 195 | /* Ignore these packet types so that keepalives don't interfere with | ||
| 196 | @@ -98,7 +101,8 @@ void process_packet() { | ||
| 197 | if (type >= 1 && type <= 49 | ||
| 198 | && type != SSH_MSG_SERVICE_REQUEST | ||
| 199 | && type != SSH_MSG_SERVICE_ACCEPT | ||
| 200 | - && type != SSH_MSG_KEXINIT) | ||
| 201 | + && type != SSH_MSG_KEXINIT | ||
| 202 | + && !first_strict_kex) | ||
| 203 | { | ||
| 204 | TRACE(("unknown allowed packet during kexinit")) | ||
| 205 | recv_unimplemented(); | ||
| 206 | diff --git a/ssh.h b/src/ssh.h | ||
| 207 | index 1b4fec65f..ef3efdca0 100644 | ||
| 208 | --- a/ssh.h | ||
| 209 | +++ b/ssh.h | ||
| 210 | @@ -100,6 +100,10 @@ | ||
| 211 | #define SSH_EXT_INFO_C "ext-info-c" | ||
| 212 | #define SSH_SERVER_SIG_ALGS "server-sig-algs" | ||
| 213 | |||
| 214 | +/* OpenSSH strict KEX feature */ | ||
| 215 | +#define SSH_STRICT_KEX_S "kex-strict-s-v00@openssh.com" | ||
| 216 | +#define SSH_STRICT_KEX_C "kex-strict-c-v00@openssh.com" | ||
| 217 | + | ||
| 218 | /* service types */ | ||
| 219 | #define SSH_SERVICE_USERAUTH "ssh-userauth" | ||
| 220 | #define SSH_SERVICE_USERAUTH_LEN 12 | ||
| 221 | diff --git a/svr-session.c b/src/svr-session.c | ||
| 222 | index 769f0731d..a538e2c5c 100644 | ||
| 223 | --- a/svr-session.c | ||
| 224 | +++ b/svr-session.c | ||
| 225 | @@ -342,6 +342,9 @@ static void svr_algos_initialise(void) { | ||
| 226 | algo->usable = 0; | ||
| 227 | } | ||
| 228 | #endif | ||
| 229 | + if (strcmp(algo->name, SSH_STRICT_KEX_C) == 0) { | ||
| 230 | + algo->usable = 0; | ||
| 231 | + } | ||
| 232 | } | ||
| 233 | } | ||
| 234 | |||
