From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 391C221E8799E for ; Thu, 14 Sep 2017 23:21:35 -0700 (PDT) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga104.jf.intel.com with ESMTP; 14 Sep 2017 23:24:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.42,396,1500966000"; d="scan'208";a="135617257" Received: from shwdeopenpsi114.ccr.corp.intel.com ([10.239.157.135]) by orsmga002.jf.intel.com with ESMTP; 14 Sep 2017 23:24:33 -0700 From: Dandan Bi To: edk2-devel@lists.01.org Cc: Eric Dong , Liming Gao Date: Fri, 15 Sep 2017 14:23:40 +0800 Message-Id: <1505456623-414328-4-git-send-email-dandan.bi@intel.com> X-Mailer: git-send-email 1.9.5.msysgit.1 In-Reply-To: <1505456623-414328-1-git-send-email-dandan.bi@intel.com> References: <1505456623-414328-1-git-send-email-dandan.bi@intel.com> Subject: [PATCH v3 3/6] MdeModulePkg/UefiHiiLib: Add codes to validate question with bit fields X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2017 06:21:35 -0000 V3: Use API BitFieldRead/Write to replace the same logic in the codes. REF:https://bugzilla.tianocore.org/show_bug.cgi?id=545 In UefiHiiLib, there are codes to validate the current setting of questions, now update the logic to handle question with bit storage. Cc: Eric Dong Cc: Liming Gao Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Dandan Bi --- MdeModulePkg/Library/UefiHiiLib/HiiLib.c | 246 ++++++++++++++++------- MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h | 4 +- MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf | 5 +- 3 files changed, 178 insertions(+), 77 deletions(-) diff --git a/MdeModulePkg/Library/UefiHiiLib/HiiLib.c b/MdeModulePkg/Library/UefiHiiLib/HiiLib.c index cd0cd35..d24be7c 100644 --- a/MdeModulePkg/Library/UefiHiiLib/HiiLib.c +++ b/MdeModulePkg/Library/UefiHiiLib/HiiLib.c @@ -1167,10 +1167,16 @@ ValidateQuestionFromVfr ( EFI_IFR_STRING *IfrString; CHAR8 *VarStoreName; UINTN Index; CHAR16 *QuestionName; CHAR16 *StringPtr; + UINT16 BitOffset; + UINT16 BitWidth; + UINT16 TotalBits; + UINTN StartBit; + UINTN EndBit; + BOOLEAN QuestionReferBitField; // // Initialize the local variables. // Index = 0; @@ -1180,10 +1186,13 @@ ValidateQuestionFromVfr ( IfrVarStore = NULL; IfrNameValueStore = NULL; IfrEfiVarStore = NULL; ZeroMem (&VarStoreData, sizeof (IFR_VARSTORAGE_DATA)); ZeroMem (&VarBlockData, sizeof (VarBlockData)); + BitOffset = 0; + BitWidth = 0; + QuestionReferBitField = FALSE; // // Check IFR value is in block data, then Validate Value // PackageOffset = sizeof (EFI_HII_PACKAGE_LIST_HEADER); @@ -1343,12 +1352,23 @@ ValidateQuestionFromVfr ( } } else { // // Get Offset by Question header and Width by DataType Flags // - Offset = IfrOneOf->Question.VarStoreInfo.VarOffset; - Width = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE)); + if (QuestionReferBitField) { + // + // Get the byte offset/width for bit field. + // + BitOffset = IfrOneOf->Question.VarStoreInfo.VarOffset; + BitWidth = IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE_BIT; + Offset = BitOffset / 8; + TotalBits = BitOffset % 8 + BitWidth; + Width = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1); + } else { + Offset = IfrOneOf->Question.VarStoreInfo.VarOffset; + Width = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE)); + } // // Check whether this question is in current block array. // if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) { // @@ -1368,11 +1388,20 @@ ValidateQuestionFromVfr ( // // Get the current value for oneof opcode // VarValue = 0; - CopyMem (&VarValue, VarBuffer + Offset, Width); + if (QuestionReferBitField) { + // + // Get the value in bit fields. + // + StartBit = BitOffset % 8; + EndBit = StartBit + BitWidth - 1; + VarValue = BitFieldRead32 (*(UINT32*)(VarBuffer + Offset), StartBit, EndBit); + } else { + CopyMem (&VarValue, VarBuffer + Offset, Width); + } } // // Set Block Data, to be checked in the following Oneof option opcode. // VarBlockData.OpCode = IfrOpHdr->OpCode; @@ -1414,12 +1443,23 @@ ValidateQuestionFromVfr ( } } else { // // Get Offset by Question header and Width by DataType Flags // - Offset = IfrNumeric->Question.VarStoreInfo.VarOffset; - Width = (UINT16) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE)); + if (QuestionReferBitField) { + // + // Get the byte offset/width for bit field. + // + BitOffset = IfrNumeric->Question.VarStoreInfo.VarOffset; + BitWidth = IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE_BIT; + Offset = BitOffset / 8; + TotalBits = BitOffset % 8 + BitWidth; + Width = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1); + } else { + Offset = IfrNumeric->Question.VarStoreInfo.VarOffset; + Width = (UINT16) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE)); + } // // Check whether this question is in current block array. // if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) { // @@ -1439,81 +1479,111 @@ ValidateQuestionFromVfr ( // // Check the current value is in the numeric range. // VarValue = 0; - CopyMem (&VarValue, VarBuffer + Offset, Width); - } - if ((IfrNumeric->Flags & EFI_IFR_DISPLAY) == 0) { - switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) { - case EFI_IFR_NUMERIC_SIZE_1: - if ((INT8) VarValue < (INT8) IfrNumeric->data.u8.MinValue || (INT8) VarValue > (INT8) IfrNumeric->data.u8.MaxValue) { - // - // Not in the valid range. - // - return EFI_INVALID_PARAMETER; - } - break; - case EFI_IFR_NUMERIC_SIZE_2: - if ((INT16) VarValue < (INT16) IfrNumeric->data.u16.MinValue || (INT16) VarValue > (INT16) IfrNumeric->data.u16.MaxValue) { - // - // Not in the valid range. - // - return EFI_INVALID_PARAMETER; - } - break; - case EFI_IFR_NUMERIC_SIZE_4: - if ((INT32) VarValue < (INT32) IfrNumeric->data.u32.MinValue || (INT32) VarValue > (INT32) IfrNumeric->data.u32.MaxValue) { - // - // Not in the valid range. - // - return EFI_INVALID_PARAMETER; - } - break; - case EFI_IFR_NUMERIC_SIZE_8: - if ((INT64) VarValue < (INT64) IfrNumeric->data.u64.MinValue || (INT64) VarValue > (INT64) IfrNumeric->data.u64.MaxValue) { - // - // Not in the valid range. - // - return EFI_INVALID_PARAMETER; - } - break; + if (QuestionReferBitField) { + // + // Get the value in the bit fields. + // + StartBit = BitOffset % 8; + EndBit = StartBit + BitWidth - 1; + VarValue = BitFieldRead32 (*(UINT32*)(VarBuffer + Offset), StartBit, EndBit); + } else { + CopyMem (&VarValue, VarBuffer + Offset, Width); } + } + if ( QuestionReferBitField) { + // + // Value in bit fields was stored as UINt32 type. + // + if ((IfrNumeric->Flags & EFI_IFR_DISPLAY_BIT) == 0) { + if ((INT32) VarValue < (INT32) IfrNumeric->data.u32.MinValue || (INT32) VarValue > (INT32) IfrNumeric->data.u32.MaxValue) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + } else { + if (VarValue < IfrNumeric->data.u32.MinValue || VarValue > IfrNumeric->data.u32.MaxValue) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + } } else { - switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) { - case EFI_IFR_NUMERIC_SIZE_1: - if ((UINT8) VarValue < IfrNumeric->data.u8.MinValue || (UINT8) VarValue > IfrNumeric->data.u8.MaxValue) { - // - // Not in the valid range. - // - return EFI_INVALID_PARAMETER; - } - break; - case EFI_IFR_NUMERIC_SIZE_2: - if ((UINT16) VarValue < IfrNumeric->data.u16.MinValue || (UINT16) VarValue > IfrNumeric->data.u16.MaxValue) { - // - // Not in the valid range. - // - return EFI_INVALID_PARAMETER; - } - break; - case EFI_IFR_NUMERIC_SIZE_4: - if ((UINT32) VarValue < IfrNumeric->data.u32.MinValue || (UINT32) VarValue > IfrNumeric->data.u32.MaxValue) { - // - // Not in the valid range. - // - return EFI_INVALID_PARAMETER; + if ((IfrNumeric->Flags & EFI_IFR_DISPLAY) == 0) { + switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) { + case EFI_IFR_NUMERIC_SIZE_1: + if ((INT8) VarValue < (INT8) IfrNumeric->data.u8.MinValue || (INT8) VarValue > (INT8) IfrNumeric->data.u8.MaxValue) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + break; + case EFI_IFR_NUMERIC_SIZE_2: + if ((INT16) VarValue < (INT16) IfrNumeric->data.u16.MinValue || (INT16) VarValue > (INT16) IfrNumeric->data.u16.MaxValue) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + break; + case EFI_IFR_NUMERIC_SIZE_4: + if ((INT32) VarValue < (INT32) IfrNumeric->data.u32.MinValue || (INT32) VarValue > (INT32) IfrNumeric->data.u32.MaxValue) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + break; + case EFI_IFR_NUMERIC_SIZE_8: + if ((INT64) VarValue < (INT64) IfrNumeric->data.u64.MinValue || (INT64) VarValue > (INT64) IfrNumeric->data.u64.MaxValue) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + break; } - break; - case EFI_IFR_NUMERIC_SIZE_8: - if ((UINT64) VarValue < IfrNumeric->data.u64.MinValue || (UINT64) VarValue > IfrNumeric->data.u64.MaxValue) { - // - // Not in the valid range. - // - return EFI_INVALID_PARAMETER; + } else { + switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) { + case EFI_IFR_NUMERIC_SIZE_1: + if ((UINT8) VarValue < IfrNumeric->data.u8.MinValue || (UINT8) VarValue > IfrNumeric->data.u8.MaxValue) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + break; + case EFI_IFR_NUMERIC_SIZE_2: + if ((UINT16) VarValue < IfrNumeric->data.u16.MinValue || (UINT16) VarValue > IfrNumeric->data.u16.MaxValue) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + break; + case EFI_IFR_NUMERIC_SIZE_4: + if ((UINT32) VarValue < IfrNumeric->data.u32.MinValue || (UINT32) VarValue > IfrNumeric->data.u32.MaxValue) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + break; + case EFI_IFR_NUMERIC_SIZE_8: + if ((UINT64) VarValue < IfrNumeric->data.u64.MinValue || (UINT64) VarValue > IfrNumeric->data.u64.MaxValue) { + // + // Not in the valid range. + // + return EFI_INVALID_PARAMETER; + } + break; } - break; } } break; case EFI_IFR_CHECKBOX_OP: // @@ -1552,12 +1622,23 @@ ValidateQuestionFromVfr ( } } else { // // Get Offset by Question header // - Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset; - Width = (UINT16) sizeof (BOOLEAN); + if (QuestionReferBitField) { + // + // Get the byte offset/width for bit field. + // + BitOffset = IfrCheckBox->Question.VarStoreInfo.VarOffset; + BitWidth = 1; + Offset = BitOffset / 8; + TotalBits = BitOffset % 8 + BitWidth; + Width = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1); + } else { + Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset; + Width = (UINT16) sizeof (BOOLEAN); + } // // Check whether this question is in current block array. // if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) { // @@ -1576,11 +1657,20 @@ ValidateQuestionFromVfr ( } // // Check the current value is in the numeric range. // VarValue = 0; - CopyMem (&VarValue, VarBuffer + Offset, Width); + if (QuestionReferBitField) { + // + // Get the value in bit fields. + // + StartBit = BitOffset % 8; + EndBit = StartBit + BitWidth - 1; + VarValue = BitFieldRead32 (*(UINT32*)(VarBuffer + Offset), StartBit, EndBit); + } else { + CopyMem (&VarValue, VarBuffer + Offset, Width); + } } // // Boolean type, only 1 and 0 is valid. // if (VarValue > 1) { @@ -1692,10 +1782,11 @@ ValidateQuestionFromVfr ( VarBlockData.OpCode = 0; } } break; case EFI_IFR_END_OP: + QuestionReferBitField = FALSE; // // Decrease opcode scope for the validated opcode // if (VarBlockData.Scope > 0) { VarBlockData.Scope --; @@ -1706,10 +1797,15 @@ ValidateQuestionFromVfr ( // if ((VarBlockData.Scope == 0) && (VarBlockData.OpCode == EFI_IFR_ONE_OF_OP)) { return EFI_INVALID_PARAMETER; } break; + case EFI_IFR_GUID_OP: + if (CompareGuid ((EFI_GUID *)((UINT8*)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEfiIfrBitvarstoreGuid)) { + QuestionReferBitField = TRUE; + } + break; default: // // Increase Scope for the validated opcode // if (VarBlockData.Scope > 0) { diff --git a/MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h b/MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h index 9bf7696..293c226 100644 --- a/MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h +++ b/MdeModulePkg/Library/UefiHiiLib/InternalHiiLib.h @@ -1,9 +1,9 @@ /** @file Internal include file for the HII Library instance. - Copyright (c) 2007, Intel Corporation. All rights reserved.
+ Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php @@ -18,10 +18,12 @@ #include #include #include +#include + #include #include #include #include #include diff --git a/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf b/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf index 62f435a..411c758 100644 --- a/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf +++ b/MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf @@ -1,9 +1,9 @@ ## @file # HII Library implementation using UEFI HII protocols and services. # -# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at # http://opensource.org/licenses/bsd-license.php @@ -49,5 +49,8 @@ PrintLib [Protocols] gEfiFormBrowser2ProtocolGuid ## SOMETIMES_CONSUMES gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES + +[Guids] + gEfiIfrBitvarstoreGuid ## SOMETIMES_CONSUMES ## GUID -- 1.9.5.msysgit.1