summaryrefslogtreecommitdiff
path: root/debian
diff options
context:
space:
mode:
authorSteve Langasek <steve.langasek@canonical.com>2014-10-08 06:40:28 +0000
committerSteve Langasek <steve.langasek@canonical.com>2014-10-08 06:40:28 +0000
commit3586772f0c502d7233e07335c5245b3b0d37e771 (patch)
tree5ad37625d94a58512faa14c20b88c4a6da438278 /debian
parentbc9b5d63863a5de26b02a33858462481334ac1c5 (diff)
downloadefi-boot-shim-3586772f0c502d7233e07335c5245b3b0d37e771.tar.gz
efi-boot-shim-3586772f0c502d7233e07335c5245b3b0d37e771.zip
* SECURITY UPDATE: heap overflow and out-of-bounds read access when
parsing DHCPv6 information - debian/patches/CVE-2014-3675.patch: apply proper bounds checking when parsing data provided in DHCPv6 packets. - CVE-2014-3675 - CVE-2014-3676 * SECURITY UPDATE: memory corruption when processing user-provided key lists - debian/patches/CVE-2014-3677.patch: detect malformed machine owner key (MOK) lists and ignore them, avoiding possible memory corruption. - CVE-2014-3677
Diffstat (limited to 'debian')
-rw-r--r--debian/changelog16
-rw-r--r--debian/patches/CVE-2014-3675.patch161
-rw-r--r--debian/patches/CVE-2014-3677.patch75
-rw-r--r--debian/patches/series1
4 files changed, 253 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog
index 42eab115..f42e5e82 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,19 @@
+shim (0.7-0ubuntu3) UNRELEASED; urgency=medium
+
+ * SECURITY UPDATE: heap overflow and out-of-bounds read access when
+ parsing DHCPv6 information
+ - debian/patches/CVE-2014-3675.patch: apply proper bounds checking
+ when parsing data provided in DHCPv6 packets.
+ - CVE-2014-3675
+ - CVE-2014-3676
+ * SECURITY UPDATE: memory corruption when processing user-provided key
+ lists
+ - debian/patches/CVE-2014-3677.patch: detect malformed machine owner
+ key (MOK) lists and ignore them, avoiding possible memory corruption.
+ - CVE-2014-3677
+
+ -- Steve Langasek <steve.langasek@ubuntu.com> Tue, 07 Oct 2014 23:28:39 -0700
+
shim (0.7-0ubuntu2) utopic; urgency=medium
* Restore debian/patches/prototypes, which still is needed on shim 0.7
diff --git a/debian/patches/CVE-2014-3675.patch b/debian/patches/CVE-2014-3675.patch
new file mode 100644
index 00000000..67b50fd6
--- /dev/null
+++ b/debian/patches/CVE-2014-3675.patch
@@ -0,0 +1,161 @@
+diff --git a/netboot.c b/netboot.c
+index 5ef53f7..f01a9bc 100644
+--- a/netboot.c
++++ b/netboot.c
+@@ -116,29 +116,34 @@ BOOLEAN findNetboot(EFI_HANDLE device)
+
+ static CHAR8 *get_v6_bootfile_url(EFI_PXE_BASE_CODE_DHCPV6_PACKET *pkt)
+ {
+- void *optr;
+- EFI_DHCP6_PACKET_OPTION *option;
+- CHAR8 *url;
+- UINT32 urllen;
++ void *optr = NULL, *end = NULL;
++ EFI_DHCP6_PACKET_OPTION *option = NULL;
++ CHAR8 *url = NULL;
++ UINT32 urllen = 0;
+
+ optr = pkt->DhcpOptions;
++ end = optr + sizeof(pkt->DhcpOptions);
+
+- for(;;) {
++ for (;;) {
+ option = (EFI_DHCP6_PACKET_OPTION *)optr;
+
+ if (ntohs(option->OpCode) == 0)
+- return NULL;
++ break;
+
+ if (ntohs(option->OpCode) == 59) {
+ /* This is the bootfile url option */
+ urllen = ntohs(option->Length);
+- url = AllocateZeroPool(urllen+1);
++ if ((void *)(option->Data + urllen) > end)
++ break;
++ url = AllocateZeroPool(urllen + 1);
+ if (!url)
+- return NULL;
++ break;
+ memcpy(url, option->Data, urllen);
+ return url;
+ }
+ optr += 4 + ntohs(option->Length);
++ if (optr + sizeof(EFI_DHCP6_PACKET_OPTION) > end)
++ break;
+ }
+
+ return NULL;
+@@ -164,45 +169,60 @@ static CHAR16 str2ns(CHAR8 *str)
+
+ static CHAR8 *str2ip6(CHAR8 *str)
+ {
+- UINT8 i, j, p;
+- size_t len;
+- CHAR8 *a, *b, t;
+- static UINT16 ip[8];
++ UINT8 i = 0, j = 0, p = 0;
++ size_t len = 0, dotcount = 0;
++ enum { MAX_IP6_DOTS = 7 };
++ CHAR8 *a = NULL, *b = NULL, t = 0;
++ static UINT16 ip[8];
+
+- for(i=0; i < 8; i++) {
+- ip[i] = 0;
+- }
+- len = strlen(str);
+- a = b = str;
+- for(i=p=0; i < len; i++, b++) {
+- if (*b != ':')
+- continue;
+- *b = '\0';
+- ip[p++] = str2ns(a);
+- *b = ':';
+- a = b + 1;
+- if ( *(b+1) == ':' )
+- break;
+- }
+- a = b = (str + len);
+- for(j=len, p=7; j > i; j--, a--) {
+- if (*a != ':')
+- continue;
+- t = *b;
+- *b = '\0';
+- ip[p--] = str2ns(a+1);
+- *b = t;
+- b = a;
+- }
+- return (CHAR8 *)ip;
++ memset(ip, 0, sizeof(ip));
++
++ /* Count amount of ':' to prevent overflows.
++ * max. count = 7. Returns an invalid ip6 that
++ * can be checked against
++ */
++ for (a = str; *a != 0; ++a) {
++ if (*a == ':')
++ ++dotcount;
++ }
++ if (dotcount > MAX_IP6_DOTS)
++ return (CHAR8 *)ip;
++
++ len = strlen(str);
++ a = b = str;
++ for (i = p = 0; i < len; i++, b++) {
++ if (*b != ':')
++ continue;
++ *b = '\0';
++ ip[p++] = str2ns(a);
++ *b = ':';
++ a = b + 1;
++ if (b[1] == ':' )
++ break;
++ }
++ a = b = (str + len);
++ for (j = len, p = 7; j > i; j--, a--) {
++ if (*a != ':')
++ continue;
++ t = *b;
++ *b = '\0';
++ ip[p--] = str2ns(a+1);
++ *b = t;
++ b = a;
++ }
++ return (CHAR8 *)ip;
+ }
+
+ static BOOLEAN extract_tftp_info(CHAR8 *url)
+ {
+ CHAR8 *start, *end;
+ CHAR8 ip6str[40];
++ CHAR8 ip6inv[16];
+ CHAR8 *template = (CHAR8 *)translate_slashes(DEFAULT_LOADER_CHAR);
+
++ // to check against str2ip6() errors
++ memset(ip6inv, 0, sizeof(ip6inv));
++
+ if (strncmp((UINT8 *)url, (UINT8 *)"tftp://", 7)) {
+ Print(L"URLS MUST START WITH tftp://\n");
+ return FALSE;
+@@ -217,7 +237,7 @@ static BOOLEAN extract_tftp_info(CHAR8 *url)
+ end = start;
+ while ((*end != '\0') && (*end != ']')) {
+ end++;
+- if (end - start > 39) {
++ if (end - start >= (int)sizeof(ip6str)) {
+ Print(L"TFTP URL includes malformed IPv6 address\n");
+ return FALSE;
+ }
+@@ -226,10 +246,12 @@ static BOOLEAN extract_tftp_info(CHAR8 *url)
+ Print(L"TFTP SERVER MUST BE ENCLOSED IN [..]\n");
+ return FALSE;
+ }
+- memset(ip6str, 0, 40);
++ memset(ip6str, 0, sizeof(ip6str));
+ memcpy(ip6str, start, end - start);
+ end++;
+ memcpy(&tftp_addr.v6, str2ip6(ip6str), 16);
++ if (memcmp(&tftp_addr.v6, ip6inv, sizeof(ip6inv)) == 0)
++ return FALSE;
+ full_path = AllocateZeroPool(strlen(end)+strlen(template)+1);
+ if (!full_path)
+ return FALSE;
diff --git a/debian/patches/CVE-2014-3677.patch b/debian/patches/CVE-2014-3677.patch
new file mode 100644
index 00000000..4d05f05c
--- /dev/null
+++ b/debian/patches/CVE-2014-3677.patch
@@ -0,0 +1,75 @@
+diff --git a/MokManager.c b/MokManager.c
+index 50cb9d7..73d8ff4 100644
+--- a/MokManager.c
++++ b/MokManager.c
+@@ -100,8 +100,18 @@ static UINT32 count_keys(void *Data, UINTN DataSize)
+ EFI_GUID HashType = EFI_CERT_SHA256_GUID;
+ UINTN dbsize = DataSize;
+ UINT32 MokNum = 0;
++ void *end = Data + DataSize;
+
+ while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
++
++ /* Use ptr arithmetics to ensure bounded access. Do not allow 0
++ * SignatureListSize that will cause endless loop.
++ */
++ if ((void *)(CertList + 1) > end || CertList->SignatureListSize == 0) {
++ console_notify(L"Invalid MOK detected! Ignoring MOK List.");
++ return 0;
++ }
++
+ if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) &&
+ (CompareGuid (&CertList->SignatureType, &HashType) != 0)) {
+ console_notify(L"Doesn't look like a key or hash");
+@@ -137,6 +147,7 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
+ EFI_GUID HashType = EFI_CERT_SHA256_GUID;
+ UINTN dbsize = DataSize;
+ UINTN count = 0;
++ void *end = Data + DataSize;
+
+ list = AllocatePool(sizeof(MokListNode) * num);
+
+@@ -146,6 +157,11 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
+ }
+
+ while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
++ /* CertList out of bounds? */
++ if ((void *)(CertList + 1) > end || CertList->SignatureListSize == 0) {
++ FreePool(list);
++ return NULL;
++ }
+ if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) &&
+ (CompareGuid (&CertList->SignatureType, &HashType) != 0)) {
+ dbsize -= CertList->SignatureListSize;
+@@ -165,10 +181,22 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
+ Cert = (EFI_SIGNATURE_DATA *) (((UINT8 *) CertList) +
+ sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+
++ /* Cert out of bounds? */
++ if ((void *)(Cert + 1) > end || CertList->SignatureSize <= sizeof(EFI_GUID)) {
++ FreePool(list);
++ return NULL;
++ }
++
+ list[count].MokSize = CertList->SignatureSize - sizeof(EFI_GUID);
+ list[count].Mok = (void *)Cert->SignatureData;
+ list[count].Type = CertList->SignatureType;
+
++ /* MOK out of bounds? */
++ if (list[count].MokSize > end - (void *)list[count].Mok) {
++ FreePool(list);
++ return NULL;
++ }
++
+ count++;
+ dbsize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +
+@@ -449,6 +477,8 @@ static EFI_STATUS list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
+ }
+
+ MokNum = count_keys(KeyList, KeyListSize);
++ if (MokNum == 0)
++ return 0;
+ keys = build_mok_list(MokNum, KeyList, KeyListSize);
+
+ if (!keys) {
diff --git a/debian/patches/series b/debian/patches/series
index 49e56d23..fa2ce82d 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -2,3 +2,4 @@ prototypes
second-stage-path
sbsigntool-not-pesign
0001-Update-openssl-to-0.9.8za.patch
+CVE-2014-3675.patch