NetworkPkg/TlsDxe: verify DataSize for EfiTlsCipherList
authorLaszlo Ersek <lersek@redhat.com>
Sat, 31 Mar 2018 14:04:10 +0000 (16:04 +0200)
committerLaszlo Ersek <lersek@redhat.com>
Fri, 13 Apr 2018 12:06:09 +0000 (14:06 +0200)
TlsSetSessionData() shouldn't just ignore an incomplete EFI_TLS_CIPHER
element at the end of "Data":

- Generally speaking, malformed input for a security API is best rejected
  explicitly.

- Specifically speaking, the size of EFI_TLS_CIPHER is 2 bytes. If
  DataSize is 1 on input, then the initial check for (DataSize == 0) will
  fail, but then TlsSetCipherList() will be called with CipherNum=0.

Return EFI_INVALID_PARAMETER from TlsSetSessionData() if "Data" doesn't
contain a whole number of EFI_TLS_CIPHER elements. While at it, introduce
the dedicated variable CipherCount.

Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=915
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
Reviewed-by: Long Qin <qin.long@intel.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
NetworkPkg/TlsDxe/TlsProtocol.c

index ad4c922c60bd2ea5300d0084a19460da56d58c0d..a5f95a09834516e9ca7f90e0726216c3f22c2f25 100644 (file)
@@ -38,6 +38,7 @@ EFI_TLS_PROTOCOL  mTlsProtocol = {
                                   This is NULL.\r
                                   Data is NULL.\r
                                   DataSize is 0.\r
                                   This is NULL.\r
                                   Data is NULL.\r
                                   DataSize is 0.\r
+                                  DataSize is invalid for DataType.\r
   @retval EFI_UNSUPPORTED         The DataType is unsupported.\r
   @retval EFI_ACCESS_DENIED       If the DataType is one of below:\r
                                   EfiTlsClientRandom\r
   @retval EFI_UNSUPPORTED         The DataType is unsupported.\r
   @retval EFI_ACCESS_DENIED       If the DataType is one of below:\r
                                   EfiTlsClientRandom\r
@@ -59,6 +60,7 @@ TlsSetSessionData (
   EFI_STATUS                Status;\r
   TLS_INSTANCE              *Instance;\r
   UINT16                    *CipherId;\r
   EFI_STATUS                Status;\r
   TLS_INSTANCE              *Instance;\r
   UINT16                    *CipherId;\r
+  UINTN                     CipherCount;\r
   UINTN                     Index;\r
 \r
   EFI_TPL                   OldTpl;\r
   UINTN                     Index;\r
 \r
   EFI_TPL                   OldTpl;\r
@@ -100,17 +102,23 @@ TlsSetSessionData (
     Status = TlsSetConnectionEnd (Instance->TlsConn, *((EFI_TLS_CONNECTION_END *) Data));\r
     break;\r
   case EfiTlsCipherList:\r
     Status = TlsSetConnectionEnd (Instance->TlsConn, *((EFI_TLS_CONNECTION_END *) Data));\r
     break;\r
   case EfiTlsCipherList:\r
+    if (DataSize % sizeof (EFI_TLS_CIPHER) != 0) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto ON_EXIT;\r
+    }\r
+\r
     CipherId = AllocatePool (DataSize);\r
     if (CipherId == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto ON_EXIT;\r
     }\r
 \r
     CipherId = AllocatePool (DataSize);\r
     if (CipherId == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto ON_EXIT;\r
     }\r
 \r
-    for (Index = 0; Index < DataSize / sizeof (EFI_TLS_CIPHER); Index++) {\r
+    CipherCount = DataSize / sizeof (EFI_TLS_CIPHER);\r
+    for (Index = 0; Index < CipherCount; Index++) {\r
       *(CipherId +Index) = HTONS (*(((UINT16 *) Data) + Index));\r
     }\r
 \r
       *(CipherId +Index) = HTONS (*(((UINT16 *) Data) + Index));\r
     }\r
 \r
-    Status = TlsSetCipherList (Instance->TlsConn, CipherId, DataSize / sizeof (EFI_TLS_CIPHER));\r
+    Status = TlsSetCipherList (Instance->TlsConn, CipherId, CipherCount);\r
 \r
     FreePool (CipherId);\r
     break;\r
 \r
     FreePool (CipherId);\r
     break;\r