diff -Nru spice-0.12.4/debian/changelog spice-0.12.4/debian/changelog --- spice-0.12.4/debian/changelog 2013-11-06 14:42:53.000000000 +0000 +++ spice-0.12.4/debian/changelog 2013-11-07 14:46:30.000000000 +0000 @@ -1,11 +1,8 @@ -spice (0.12.4-0nocelt1.1ubuntu1) trusty; urgency=low +spice (0.12.4-0nocelt2) unstable; urgency=high - * SECURITY UPDATE: denial of service via long password in a SPICE ticket - - debian/patches/CVE-2013-4282.patch: validate password length in - server/reds.c. - - CVE-2013-4282 + * Fix CVE-2013-4282 (Closes: #728314) - -- Marc Deslauriers Wed, 06 Nov 2013 09:41:43 -0500 + -- Liang Guo Thu, 07 Nov 2013 22:44:29 +0800 spice (0.12.4-0nocelt1.1) unstable; urgency=low diff -Nru spice-0.12.4/debian/control spice-0.12.4/debian/control --- spice-0.12.4/debian/control 2013-11-06 14:43:04.000000000 +0000 +++ spice-0.12.4/debian/control 2013-08-02 17:36:08.000000000 +0000 @@ -1,8 +1,7 @@ Source: spice Section: misc Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Liang Guo +Maintainer: Liang Guo Uploaders: Michael Tokarev Build-Depends: debhelper (>= 9), pkg-config, dh-autoreconf, python, diff -Nru spice-0.12.4/debian/patches/CVE-2013-4282.patch spice-0.12.4/debian/patches/CVE-2013-4282.patch --- spice-0.12.4/debian/patches/CVE-2013-4282.patch 2013-11-06 14:41:38.000000000 +0000 +++ spice-0.12.4/debian/patches/CVE-2013-4282.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -From 8af619009660b24e0b41ad26b30289eea288fcc2 Mon Sep 17 00:00:00 2001 -From: Christophe Fergeau -Date: Fri, 23 Aug 2013 09:29:44 +0000 -Subject: Fix buffer overflow when decrypting client SPICE ticket - -reds_handle_ticket uses a fixed size 'password' buffer for the decrypted -password whose size is SPICE_MAX_PASSWORD_LENGTH. However, -RSA_private_decrypt which we call for the decryption expects the -destination buffer to be at least RSA_size(link->tiTicketing.rsa) -bytes long. On my spice-server build, SPICE_MAX_PASSWORD_LENGTH -is 60 while RSA_size() is 128, so we end up overflowing 'password' -when using long passwords (this was reproduced using the string: -'fullscreen=1proxy=#enter proxy here; e.g spice_proxy = http://[proxy]:[port]' -as a password). - -When the overflow occurs, QEMU dies with: -Index: spice-0.12.4/server/reds.c -=================================================================== ---- spice-0.12.4.orig/server/reds.c 2013-11-06 09:41:35.216667818 -0500 -+++ spice-0.12.4/server/reds.c 2013-11-06 09:41:35.212667818 -0500 -@@ -1931,39 +1931,59 @@ - static void reds_handle_ticket(void *opaque) - { - RedLinkInfo *link = (RedLinkInfo *)opaque; -- char password[SPICE_MAX_PASSWORD_LENGTH]; -+ char *password; - time_t ltime; -+ int password_size; - - //todo: use monotonic time - time(<ime); -- RSA_private_decrypt(link->tiTicketing.rsa_size, -- link->tiTicketing.encrypted_ticket.encrypted_data, -- (unsigned char *)password, link->tiTicketing.rsa, RSA_PKCS1_OAEP_PADDING); -+ if (RSA_size(link->tiTicketing.rsa) < SPICE_MAX_PASSWORD_LENGTH) { -+ spice_warning("RSA modulus size is smaller than SPICE_MAX_PASSWORD_LENGTH (%d < %d), " -+ "SPICE ticket sent from client may be truncated", -+ RSA_size(link->tiTicketing.rsa), SPICE_MAX_PASSWORD_LENGTH); -+ } -+ -+ password = g_malloc0(RSA_size(link->tiTicketing.rsa) + 1); -+ password_size = RSA_private_decrypt(link->tiTicketing.rsa_size, -+ link->tiTicketing.encrypted_ticket.encrypted_data, -+ (unsigned char *)password, -+ link->tiTicketing.rsa, -+ RSA_PKCS1_OAEP_PADDING); -+ if (password_size == -1) { -+ spice_warning("failed to decrypt RSA encrypted password: %s", -+ ERR_error_string(ERR_get_error(), NULL)); -+ goto error; -+ } -+ password[password_size] = '\0'; - - if (ticketing_enabled && !link->skip_auth) { - int expired = taTicket.expiration_time < ltime; - - if (strlen(taTicket.password) == 0) { -- reds_send_link_result(link, SPICE_LINK_ERR_PERMISSION_DENIED); - spice_warning("Ticketing is enabled, but no password is set. " -- "please set a ticket first"); -- reds_link_free(link); -- return; -+ "please set a ticket first"); -+ goto error; - } - -- if (expired || strncmp(password, taTicket.password, SPICE_MAX_PASSWORD_LENGTH) != 0) { -+ if (expired || strcmp(password, taTicket.password) != 0) { - if (expired) { - spice_warning("Ticket has expired"); - } else { - spice_warning("Invalid password"); - } -- reds_send_link_result(link, SPICE_LINK_ERR_PERMISSION_DENIED); -- reds_link_free(link); -- return; -+ goto error; - } - } - - reds_handle_link(link); -+ goto end; -+ -+error: -+ reds_send_link_result(link, SPICE_LINK_ERR_PERMISSION_DENIED); -+ reds_link_free(link); -+ -+end: -+ g_free(password); - } - - static inline void async_read_clear_handlers(AsyncRead *obj) diff -Nru spice-0.12.4/debian/patches/fix-buffer-overflow-when-decrypting-client-spice-ticket.patch spice-0.12.4/debian/patches/fix-buffer-overflow-when-decrypting-client-spice-ticket.patch --- spice-0.12.4/debian/patches/fix-buffer-overflow-when-decrypting-client-spice-ticket.patch 1970-01-01 00:00:00.000000000 +0000 +++ spice-0.12.4/debian/patches/fix-buffer-overflow-when-decrypting-client-spice-ticket.patch 2013-11-07 14:44:12.000000000 +0000 @@ -0,0 +1,90 @@ +From 8af619009660b24e0b41ad26b30289eea288fcc2 Mon Sep 17 00:00:00 2001 +From: Christophe Fergeau +Date: Fri, 23 Aug 2013 09:29:44 +0000 +Subject: Fix buffer overflow when decrypting client SPICE ticket + +reds_handle_ticket uses a fixed size 'password' buffer for the decrypted +password whose size is SPICE_MAX_PASSWORD_LENGTH. However, +RSA_private_decrypt which we call for the decryption expects the +destination buffer to be at least RSA_size(link->tiTicketing.rsa) +bytes long. On my spice-server build, SPICE_MAX_PASSWORD_LENGTH +is 60 while RSA_size() is 128, so we end up overflowing 'password' +when using long passwords (this was reproduced using the string: +'fullscreen=1proxy=#enter proxy here; e.g spice_proxy = http://[proxy]:[port]' +as a password). + +When the overflow occurs, QEMU dies with: +--- a/server/reds.c ++++ b/server/reds.c +@@ -1931,39 +1931,59 @@ + static void reds_handle_ticket(void *opaque) + { + RedLinkInfo *link = (RedLinkInfo *)opaque; +- char password[SPICE_MAX_PASSWORD_LENGTH]; ++ char *password; + time_t ltime; ++ int password_size; + + //todo: use monotonic time + time(<ime); +- RSA_private_decrypt(link->tiTicketing.rsa_size, +- link->tiTicketing.encrypted_ticket.encrypted_data, +- (unsigned char *)password, link->tiTicketing.rsa, RSA_PKCS1_OAEP_PADDING); ++ if (RSA_size(link->tiTicketing.rsa) < SPICE_MAX_PASSWORD_LENGTH) { ++ spice_warning("RSA modulus size is smaller than SPICE_MAX_PASSWORD_LENGTH (%d < %d), " ++ "SPICE ticket sent from client may be truncated", ++ RSA_size(link->tiTicketing.rsa), SPICE_MAX_PASSWORD_LENGTH); ++ } ++ ++ password = g_malloc0(RSA_size(link->tiTicketing.rsa) + 1); ++ password_size = RSA_private_decrypt(link->tiTicketing.rsa_size, ++ link->tiTicketing.encrypted_ticket.encrypted_data, ++ (unsigned char *)password, ++ link->tiTicketing.rsa, ++ RSA_PKCS1_OAEP_PADDING); ++ if (password_size == -1) { ++ spice_warning("failed to decrypt RSA encrypted password: %s", ++ ERR_error_string(ERR_get_error(), NULL)); ++ goto error; ++ } ++ password[password_size] = '\0'; + + if (ticketing_enabled && !link->skip_auth) { + int expired = taTicket.expiration_time < ltime; + + if (strlen(taTicket.password) == 0) { +- reds_send_link_result(link, SPICE_LINK_ERR_PERMISSION_DENIED); + spice_warning("Ticketing is enabled, but no password is set. " +- "please set a ticket first"); +- reds_link_free(link); +- return; ++ "please set a ticket first"); ++ goto error; + } + +- if (expired || strncmp(password, taTicket.password, SPICE_MAX_PASSWORD_LENGTH) != 0) { ++ if (expired || strcmp(password, taTicket.password) != 0) { + if (expired) { + spice_warning("Ticket has expired"); + } else { + spice_warning("Invalid password"); + } +- reds_send_link_result(link, SPICE_LINK_ERR_PERMISSION_DENIED); +- reds_link_free(link); +- return; ++ goto error; + } + } + + reds_handle_link(link); ++ goto end; ++ ++error: ++ reds_send_link_result(link, SPICE_LINK_ERR_PERMISSION_DENIED); ++ reds_link_free(link); ++ ++end: ++ g_free(password); + } + + static inline void async_read_clear_handlers(AsyncRead *obj) diff -Nru spice-0.12.4/debian/patches/series spice-0.12.4/debian/patches/series --- spice-0.12.4/debian/patches/series 2013-11-06 14:41:33.000000000 +0000 +++ spice-0.12.4/debian/patches/series 2013-11-07 14:43:49.000000000 +0000 @@ -2,4 +2,4 @@ make-celt-to-be-optional.patch link-server-test-with-libm-libpthread.patch enable_subdir-objects.patch -CVE-2013-4282.patch +fix-buffer-overflow-when-decrypting-client-spice-ticket.patch