1 |
Fix for VU#922681 |
2 |
|
3 |
This includes fix for various CVEs by more or less backporting the whole unique_service_name() function from 1.6.18. |
4 |
|
5 |
CVE-2012-5961 Issue #1: Stack buffer overflow of Evt->UDN |
6 |
CVE-2012-5958 Issue #2: Stack buffer overflow of Tempbuf |
7 |
CVE-2012-5962 Issue #3: Stack buffer overflow of Evt->DeviceType |
8 |
CVE-2012-5959 Issue #4: Stack buffer overflow of Event->UDN |
9 |
CVE-2012-5960 Issue #8: Stack buffer overflow of Event->UDN |
10 |
CVE-2012-5963 Issue #5: Stack buffer overflow of Event->UDN |
11 |
CVE-2012-5964 Issue #6: Stack buffer overflow of Event->DeviceType |
12 |
CVE-2012-5965 Issue #7: Stack buffer overflow of Event->DeviceType |
13 |
|
14 |
--- libupnp-1.6.15/upnp/src/ssdp/ssdp_server.c.orig 2011-11-04 18:33:59.000000000 -0400 |
15 |
+++ libupnp-1.6.15/upnp/src/ssdp/ssdp_server.c 2012-12-06 12:46:09.000000000 -0500 |
16 |
@@ -452,7 +454,7 @@ int unique_service_name(char *cmd, SsdpE |
17 |
char *ptr2 = NULL; |
18 |
char *ptr3 = NULL; |
19 |
int CommandFound = 0; |
20 |
- size_t n = 0; |
21 |
+ size_t n = (size_t)0; |
22 |
|
23 |
if ((TempPtr = strstr(cmd, "uuid:schemas")) != NULL) { |
24 |
ptr1 = strstr(cmd, ":device"); |
25 |
@@ -464,45 +466,60 @@ int unique_service_name(char *cmd, SsdpE |
26 |
ptr3 = strstr(ptr2 + 1, ":"); |
27 |
else |
28 |
return -1; |
29 |
- if (ptr3 != NULL) |
30 |
- sprintf(Evt->UDN, "uuid:%s", ptr3 + 1); |
31 |
+ if (ptr3 != NULL) { |
32 |
+ if (strlen("uuid:") + strlen(ptr3 + 1) >= sizeof Evt->UDN) |
33 |
+ return -1; |
34 |
+ snprintf(Evt->UDN, sizeof Evt->UDN, "uuid:%s", ptr3 + 1); |
35 |
+ } |
36 |
else |
37 |
return -1; |
38 |
ptr1 = strstr(cmd, ":"); |
39 |
if (ptr1 != NULL) { |
40 |
- n = (size_t) (ptr3 - ptr1); |
41 |
+ n = (size_t)ptr3 - (size_t)ptr1; |
42 |
+ n = n >= sizeof TempBuf ? sizeof TempBuf - 1 : n; |
43 |
strncpy(TempBuf, ptr1, n); |
44 |
TempBuf[n] = '\0'; |
45 |
- sprintf(Evt->DeviceType, "urn%s", TempBuf); |
46 |
+ if (strlen("urn") + strlen(TempBuf) >= sizeof(Evt->DeviceType)) |
47 |
+ return -1; |
48 |
+ snprintf(Evt->DeviceType, sizeof(Evt->DeviceType), |
49 |
+ "urn%s", TempBuf); |
50 |
} else |
51 |
return -1; |
52 |
return 0; |
53 |
} |
54 |
if ((TempPtr = strstr(cmd, "uuid")) != NULL) { |
55 |
if ((Ptr = strstr(cmd, "::")) != NULL) { |
56 |
- n = (size_t) (Ptr - TempPtr); |
57 |
+ n = (size_t)Ptr - (size_t)TempPtr; |
58 |
+ n = n >= sizeof Evt->UDN ? sizeof Evt->UDN - 1 : n; |
59 |
strncpy(Evt->UDN, TempPtr, n); |
60 |
Evt->UDN[n] = '\0'; |
61 |
- } else |
62 |
- strcpy(Evt->UDN, TempPtr); |
63 |
+ } else { |
64 |
+ memset(Evt->UDN, 0, sizeof(Evt->UDN)); |
65 |
+ strncpy(Evt->UDN, TempPtr, sizeof Evt->UDN - 1); |
66 |
+ } |
67 |
CommandFound = 1; |
68 |
} |
69 |
if (strstr(cmd, "urn:") != NULL && strstr(cmd, ":service:") != NULL) { |
70 |
if ((TempPtr = strstr(cmd, "urn")) != NULL) { |
71 |
- strcpy(Evt->ServiceType, TempPtr); |
72 |
+ memset(Evt->ServiceType, 0, sizeof Evt->ServiceType); |
73 |
+ strncpy(Evt->ServiceType, TempPtr, |
74 |
+ sizeof Evt->ServiceType - 1); |
75 |
CommandFound = 1; |
76 |
} |
77 |
} |
78 |
if (strstr(cmd, "urn:") != NULL && strstr(cmd, ":device:") != NULL) { |
79 |
if ((TempPtr = strstr(cmd, "urn")) != NULL) { |
80 |
- strcpy(Evt->DeviceType, TempPtr); |
81 |
+ memset(Evt->DeviceType, 0, sizeof Evt->DeviceType); |
82 |
+ strncpy(Evt->DeviceType, TempPtr, |
83 |
+ sizeof Evt->DeviceType - 1); |
84 |
CommandFound = 1; |
85 |
} |
86 |
} |
87 |
if ((TempPtr = strstr(cmd, "::upnp:rootdevice")) != NULL) { |
88 |
/* Everything before "::upnp::rootdevice" is the UDN. */ |
89 |
if (TempPtr != cmd) { |
90 |
- n = (size_t) (TempPtr - cmd); |
91 |
+ n = (size_t)TempPtr - (size_t)cmd; |
92 |
+ n = n >= sizeof Evt->UDN ? sizeof Evt->UDN - 1 : n; |
93 |
strncpy(Evt->UDN, cmd, n); |
94 |
Evt->UDN[n] = 0; |
95 |
CommandFound = 1; |