diff options
Diffstat (limited to 'meta-networking/recipes-support/spice/files/spice-fix-CVE-2013-4282.patch')
-rw-r--r-- | meta-networking/recipes-support/spice/files/spice-fix-CVE-2013-4282.patch | 100 |
1 files changed, 0 insertions, 100 deletions
diff --git a/meta-networking/recipes-support/spice/files/spice-fix-CVE-2013-4282.patch b/meta-networking/recipes-support/spice/files/spice-fix-CVE-2013-4282.patch deleted file mode 100644 index 1a00a8518..000000000 --- a/meta-networking/recipes-support/spice/files/spice-fix-CVE-2013-4282.patch +++ /dev/null | |||
@@ -1,100 +0,0 @@ | |||
1 | Fix buffer overflow when decrypting client SPICE ticket | ||
2 | |||
3 | commit 8af619009660b24e0b41ad26b30289eea288fcc2 upstream | ||
4 | |||
5 | reds_handle_ticket uses a fixed size 'password' buffer for the decrypted | ||
6 | password whose size is SPICE_MAX_PASSWORD_LENGTH. However, | ||
7 | RSA_private_decrypt which we call for the decryption expects the | ||
8 | destination buffer to be at least RSA_size(link->tiTicketing.rsa) | ||
9 | bytes long. On my spice-server build, SPICE_MAX_PASSWORD_LENGTH | ||
10 | is 60 while RSA_size() is 128, so we end up overflowing 'password' | ||
11 | when using long passwords (this was reproduced using the string: | ||
12 | 'fullscreen=1proxy=#enter proxy here; e.g spice_proxy = http://[proxy]:[port]' | ||
13 | as a password). | ||
14 | |||
15 | When the overflow occurs, QEMU dies with: | ||
16 | *** stack smashing detected ***: qemu-system-x86_64 terminated | ||
17 | |||
18 | This commit ensures we use a corectly sized 'password' buffer, | ||
19 | and that it's correctly nul-terminated so that we can use strcmp | ||
20 | instead of strncmp. To keep using strncmp, we'd need to figure out | ||
21 | which one of 'password' and 'taTicket.password' is the smaller buffer, | ||
22 | and use that size. | ||
23 | |||
24 | This fixes rhbz#999839 | ||
25 | diff --git a/server/reds.c b/server/reds.c | ||
26 | index 30d0652..6f262b0 100644 | ||
27 | --- a/server/reds.c | ||
28 | +++ b/server/reds.c | ||
29 | @@ -1931,39 +1931,59 @@ static void reds_handle_link(RedLinkInfo *link) | ||
30 | static void reds_handle_ticket(void *opaque) | ||
31 | { | ||
32 | RedLinkInfo *link = (RedLinkInfo *)opaque; | ||
33 | - char password[SPICE_MAX_PASSWORD_LENGTH]; | ||
34 | + char *password; | ||
35 | time_t ltime; | ||
36 | + int password_size; | ||
37 | |||
38 | //todo: use monotonic time | ||
39 | time(<ime); | ||
40 | - RSA_private_decrypt(link->tiTicketing.rsa_size, | ||
41 | - link->tiTicketing.encrypted_ticket.encrypted_data, | ||
42 | - (unsigned char *)password, link->tiTicketing.rsa, RSA_PKCS1_OAEP_PADDING); | ||
43 | + if (RSA_size(link->tiTicketing.rsa) < SPICE_MAX_PASSWORD_LENGTH) { | ||
44 | + spice_warning("RSA modulus size is smaller than SPICE_MAX_PASSWORD_LENGTH (%d < %d), " | ||
45 | + "SPICE ticket sent from client may be truncated", | ||
46 | + RSA_size(link->tiTicketing.rsa), SPICE_MAX_PASSWORD_LENGTH); | ||
47 | + } | ||
48 | + | ||
49 | + password = g_malloc0(RSA_size(link->tiTicketing.rsa) + 1); | ||
50 | + password_size = RSA_private_decrypt(link->tiTicketing.rsa_size, | ||
51 | + link->tiTicketing.encrypted_ticket.encrypted_data, | ||
52 | + (unsigned char *)password, | ||
53 | + link->tiTicketing.rsa, | ||
54 | + RSA_PKCS1_OAEP_PADDING); | ||
55 | + if (password_size == -1) { | ||
56 | + spice_warning("failed to decrypt RSA encrypted password: %s", | ||
57 | + ERR_error_string(ERR_get_error(), NULL)); | ||
58 | + goto error; | ||
59 | + } | ||
60 | + password[password_size] = '\0'; | ||
61 | |||
62 | if (ticketing_enabled && !link->skip_auth) { | ||
63 | int expired = taTicket.expiration_time < ltime; | ||
64 | |||
65 | if (strlen(taTicket.password) == 0) { | ||
66 | - reds_send_link_result(link, SPICE_LINK_ERR_PERMISSION_DENIED); | ||
67 | spice_warning("Ticketing is enabled, but no password is set. " | ||
68 | - "please set a ticket first"); | ||
69 | - reds_link_free(link); | ||
70 | - return; | ||
71 | + "please set a ticket first"); | ||
72 | + goto error; | ||
73 | } | ||
74 | |||
75 | - if (expired || strncmp(password, taTicket.password, SPICE_MAX_PASSWORD_LENGTH) != 0) { | ||
76 | + if (expired || strcmp(password, taTicket.password) != 0) { | ||
77 | if (expired) { | ||
78 | spice_warning("Ticket has expired"); | ||
79 | } else { | ||
80 | spice_warning("Invalid password"); | ||
81 | } | ||
82 | - reds_send_link_result(link, SPICE_LINK_ERR_PERMISSION_DENIED); | ||
83 | - reds_link_free(link); | ||
84 | - return; | ||
85 | + goto error; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | reds_handle_link(link); | ||
90 | + goto end; | ||
91 | + | ||
92 | +error: | ||
93 | + reds_send_link_result(link, SPICE_LINK_ERR_PERMISSION_DENIED); | ||
94 | + reds_link_free(link); | ||
95 | + | ||
96 | +end: | ||
97 | + g_free(password); | ||
98 | } | ||
99 | |||
100 | static inline void async_read_clear_handlers(AsyncRead *obj) | ||