diff options
author | Mauro Matteo Cascella <mcascell@redhat.com> | 2022-09-25 22:45:11 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2022-10-11 15:30:27 +0200 |
commit | d307040b18bfcb1393b910f1bae753d5c12a4dc7 (patch) | |
tree | 11b4dcdb7576102e8b9fc71f0401a2c15b78d4ed /ui/vnc.c | |
parent | b6d93282ccac79e42d87d02652db353894cd1db9 (diff) | |
download | qemu-d307040b18bfcb1393b910f1bae753d5c12a4dc7.zip qemu-d307040b18bfcb1393b910f1bae753d5c12a4dc7.tar.gz qemu-d307040b18bfcb1393b910f1bae753d5c12a4dc7.tar.bz2 |
ui/vnc-clipboard: fix integer underflow in vnc_client_cut_text_ext
Extended ClientCutText messages start with a 4-byte header. If len < 4,
an integer underflow occurs in vnc_client_cut_text_ext. The result is
used to decompress data in a while loop in inflate_buffer, leading to
CPU consumption and denial of service. Prevent this by checking dlen in
protocol_client_msg.
Fixes: CVE-2022-3165
Fixes: 0bf41cab93e5 ("ui/vnc: clipboard support")
Reported-by: TangPeng <tangpeng@qianxin.com>
Signed-off-by: Mauro Matteo Cascella <mcascell@redhat.com>
Message-Id: <20220925204511.1103214-1-mcascell@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'ui/vnc.c')
-rw-r--r-- | ui/vnc.c | 11 |
1 files changed, 8 insertions, 3 deletions
@@ -2442,8 +2442,8 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) if (len == 1) { return 8; } + uint32_t dlen = abs(read_s32(data, 4)); if (len == 8) { - uint32_t dlen = abs(read_s32(data, 4)); if (dlen > (1 << 20)) { error_report("vnc: client_cut_text msg payload has %u bytes" " which exceeds our limit of 1MB.", dlen); @@ -2456,8 +2456,13 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) } if (read_s32(data, 4) < 0) { - vnc_client_cut_text_ext(vs, abs(read_s32(data, 4)), - read_u32(data, 8), data + 12); + if (dlen < 4) { + error_report("vnc: malformed payload (header less than 4 bytes)" + " in extended clipboard pseudo-encoding."); + vnc_client_error(vs); + break; + } + vnc_client_cut_text_ext(vs, dlen, read_u32(data, 8), data + 12); break; } vnc_client_cut_text(vs, read_u32(data, 4), data + 8); |