On Wed, Oct 23, 2024 at 03:52:43PM +0200, Daniel Kiper wrote: > On Mon, Oct 21, 2024 at 04:06:38PM +0800, Gary Lin wrote: > > GIT repo for v20: https://github.com/lcp/grub2/tree/tpm2-unlock-v20 > > > > This patch series is based on "Automatic TPM Disk Unlock"(*1) posted by > > Hernan Gatta to introduce the key protector framework and TPM2 stack > > to GRUB, and this could be a useful feature for the systems to > > implement full disk encryption. > > > > To support TPM 2.0 Key File format(*2), patch 1~7,9-17 are grabbed from > > Daniel Axtens's "appended signature secure boot support" (*3) to import > > libtasn1 into GRUB. Besides, the libtasn1 version is upgraded to > > 4.19.0 instead of 4.16.0 in the original patch. > > > > Patch 8 fixes a potential buffer overrun in libtasn1. > > (https://gitlab.com/gnutls/libtasn1/-/issues/49) > > > > Patch 17 adds the document for libtasn1 and the steps to upgrade the > > library. > > > > Patch 19~25 are based on Hernan Gatta's patches with the follow-up fixes > > and improvements: > > - Converting 8 spaces into 1 tab > > - Merging the minor build fix from Michael Chang > > - Replacing "lu" with "PRIuGRUB_SIZE" for grub_dprintf > > - Adding "enable = efi" to the tpm2 module in grub-core/Makefile.core.def > > - Rebasing "cryptodisk: Support key protectors" to the git master > > - Removing the measurement on the sealed key > > - Based on the patch from Olaf Kirch <o...@suse.com> > > - Adjusting the input parameters of TPM2_EvictControl to match the order > > in "TCG TPM2 Part3 Commands" > > - Declaring the input arguments of TPM2 functions as const > > - Resending TPM2 commands on TPM_RC_RETRY > > - Adding checks for the parameters of TPM2 commands > > - Packing the missing authorization command for TPM2_PCR_Read > > - Tweaking the TPM2 command functions to allow some parameters to be > > NULL so that we don't have to declare empty variables > > - Using grub_cpu_to_be*() in the TPM2 stack instead of grub_swap_bytes*() > > which may cause problems in big-indian machines > > - Changing the short name of "--protector" of "cryptomount" from "-k" to > > "-P" to avoid the conflict with "--key-file" > > - Supporting TPM 2.0 Key File Format besides the raw sealed key > > - Adding the external libtasn1 dependency to grub-protect to write the > > TPM 2.0 Key files > > - Extending the TPM2 TSS stack to support authorized policy > > > > Patch 26 implements the authorized policy support. > > > > Patch 27 implements the missing NV index mode. (Thanks to Patrick Colp) > > > > Patch 28 improves the 'cryptomount' command to fall back to the > > passphrase mode when the key protector fails to unlock the encrypted > > partition. (Another patch from Patrick Colp) > > > > Patch 29 and 30 fix the potential security issues spotted by Fabian Vogt. > > > > Patch 31 and 32 implement the TPM2 key unsealing testcases. > > > > Patch 33 documents TPM2 key protector including the new GRUB commands and > > the user-space utility. > > > > To utilize the TPM2 key protector to unlock the encrypted partition > > (sdb1), here are the sample steps: > > > > 1. Add an extra random key for LUKS (luks-key) > > $ dd if=/dev/urandom of=luks-key bs=1 count=32 > > $ sudo cryptsetup luksAddKey /dev/sdb1 luks-key --pbkdf=pbkdf2 > > > > 2. Seal the key > > $ sudo grub-protect --action=add \ > > --protector=tpm2 \ > > --tpm2key \ > > --tpm2-keyfile=luks-key \ > > --tpm2-outfile=/boot/efi/efi/grub/sealed.tpm > > > > 3. Unseal the key with the proper commands in grub.cfg: > > tpm2_key_protector_init --tpm2key=(hd0,gpt1)/efi/grub/sealed.tpm > > cryptomount -u <SDB1_UUID> -P tpm2 > > > > (*1) https://lists.gnu.org/archive/html/grub-devel/2022-02/msg00006.html > > (*2) https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html > > (*3) https://lists.gnu.org/archive/html/grub-devel/2021-06/msg00044.html > > > > v20: > > - Rearranging the order of the libtasn1 patches > > - libtasn1 patches are created by the following repo against the > > libtasn1-4.19.0-base-v4 tag: > > https://github.com/lcp/grub2/tree/import-libtasn1-4.19.0-v4 > > - Excluding a libtasn1 testcase to avoid a potential gcc warning when > > 'long' is the same as 'int' > > - Replacing grub_swap_bytes32() with grub_cpu_to_be32() to make the TPM > > command size always big endian > > - Correcting the GRUB path in the commit messages and the document > > - "/efi/grub2" => "/efi/grub" > > - "/boot/efi/boot/grub2" => "/boot/efi/efi/grub/" > > - "(hd0,gpt1)/boot/grub2/" => "(hd0,gpt1)/efi/grub" > > - Removing the unnecessary "grub_errno = GRUB_ERR_NONE;" > > - Replacing 'lu' with 'PRIuGRUB_UINT64_T' when setting the error > > message for 'uint64_t' to avoid the portability issue > > - Removing the 'grub_' and 'GRUB_' prefixes from the local types, > > functions, and variables > > - Documenting the option '-P' for 'cryptomount' > > - Fixing coding style issues > > - Removing the unused headers from grub-core/lib/tss2/tcg2_emu.c > > - Updating the TPM2 key protector in user manual > > [...] > > > ********************************************* > > * Anaylses for Coverity issuses on libtasn1 * > > s/Anaylses for Coverity issuses on libtasn1/Analysis of libtasn1 Coverity > issuses/ > > > ********************************************* > > > > 2 Memory corruptions: CID 435762, CID 435766 > > > > ________________________________________________________________________________________________________ > > *** CID 435762: Memory - corruptions (OVERRUN) > > /grub-core/lib/libtasn1/lib/coding.c: 152 in _asn1_tag_der() > > 146 if (k > ASN1_MAX_TAG_SIZE - 1) > > 147 break; /* will not encode larger tags */ > > 148 } > > 149 *ans_len = k + 1; > > 150 while (k--) > > 151 ans[*ans_len - 1 - k] = temp[k] + 128; > > >>> CID 435762: Memory - corruptions (OVERRUN) > > >>> Overrunning array of 4 bytes at byte offset 4 by dereferencing > > >>> pointer "ans + (*ans_len - 1)". > > 152 ans[*ans_len - 1] -= 128; > > 153 } > > 154 } > > 155 > > 156 /** > > 157 * asn1_octet_der: > > > > Reported to upstream: https://gitlab.com/gnutls/libtasn1/-/issues/49 > > OK but do we need a fix right now or not? If yes do we have one now? > If not can we ignore this Coverity issue? Please comment that in next > cover letter. > Oops, I forgot to copy the summary to the cover letter.
CID 435762 is fixed by Patch 08, and CID 435766 is likely to be false positive. > > ________________________________________________________________________________________________________ > > *** CID 435766: Memory - corruptions (OVERRUN) > > /grub-core/lib/libtasn1/lib/decoding.c: 1204 in asn1_der_decoding2() > > 1198 } > > 1199 > > 1200 DECR_LEN (ider_len, len2); > > 1201 > > 1202 tlen = strlen (temp); > > 1203 if (tlen > 0) > > >>> CID 435766: Memory - corruptions (OVERRUN) > > >>> Allocating insufficient memory for the terminating null of the > > >>> string. > > 1204 _asn1_set_value (p, temp, tlen); > > 1205 > > 1206 counter += len2; > > 1207 move = RIGHT; > > 1208 break; > > 1209 case ASN1_ETYPE_OCTET_STRING: > > > > False positive? > > https://gitlab.com/gnutls/libtasn1/-/issues/50 > > Ditto. > > > == > > 7 Integer handling issues: > > CID 435774, CID 435773, CID 435772, CID 435768, CID 435765, CID 435764, CID > > 435763 > > All those integer handling issues are false positive. The results are expected, and those issues can be ignored. Gary Lin > > ________________________________________________________________________________________________________ > > *** CID 435774: Integer handling issues (CONSTANT_EXPRESSION_RESULT) > > /grub-core/lib/libtasn1/lib/decoding.c: 481 in asn1_get_object_id_der() > > 475 */ > > 476 if (leading != 0 && der[len_len + k] == 0x80) > > 477 return ASN1_DER_ERROR; > > 478 leading = 0; > > 479 > > 480 /* check for wrap around */ > > >>> CID 435774: Integer handling issues (CONSTANT_EXPRESSION_RESULT) > > >>> "val < ((((1 ? 0 : val) - 1 < 0) ? ~((((1 ? 0 : val) + 1 << 62UL /* > > >>> sizeof (+val) * 8 - 2 */) - 1) * 2 + 1) : ((1 ? 0 : val) + 0)) >> 7)" > > >>> is always false regardless of the values of its operands. This occurs > > >>> as the second operand of "?:". > > 481 if (INT_LEFT_SHIFT_OVERFLOW (val, 7)) > > 482 return ASN1_DER_ERROR; > > 483 > > 484 val = val << 7; > > 485 val |= der[len_len + k] & 0x7F; > > 486 > > > > /grub-core/lib/libtasn1/lib/decoding.c: 481 in asn1_get_object_id_der() > > > > Here are the related macros from gnulib: > > > > #define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v)) > > > > #define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) > > > > #define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v)) > > > > #define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) > > > > #define _GL_SIGNED_INT_MAXIMUM(e) \ > > (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1) > > > > #define _GL_INT_MINIMUM(e) \ > > (EXPR_SIGNED (e) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (e) \ > > : _GL_INT_CONVERT (e, 0)) > > > > #define _GL_INT_MAXIMUM(e) \ > > (EXPR_SIGNED (e) \ > > ? _GL_SIGNED_INT_MAXIMUM (e) \ > > : _GL_INT_NEGATE_CONVERT (e, 1)) > > > > #define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max) \ > > ((a) < 0 \ > > ? (a) < (min) >> (b) \ > > : (max) >> (b) < (a)) > > > > #define INT_LEFT_SHIFT_OVERFLOW(a, b) \ > > INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \ > > _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) > > > > The statement in question is expanded "(a) < (min) >> (b)" from > > 'INT_LEFT_SHIFT_RANGE_OVERFLOW'. > > > > '(a) < (min) >> (b)' > > => '(val) < _GL_INT_MINIMUM (val) >> (7)' > > => '(val) < \ > > (EXPR_SIGNED (val) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (val) \ > > : _GL_INT_CONVERT (val, 0)) \ > > >> (7)' > > => '(val) < \ > > ((_GL_INT_NEGATE_CONVERT (val, 1) < 0) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (val) \ > > : _GL_INT_CONVERT (val, 0)) \ > > >> (7)' > > => '(val) < \ > > ((((1 ? 0 : (val)) - (1)) < 0) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (val) \ > > : _GL_INT_CONVERT (val, 0)) \ > > >> (7)' > > => '(val) < \ > > ((((1 ? 0 : (val)) - (1)) < 0) \ > > ? ~ (((_GL_INT_CONVERT (val, 1) << (TYPE_WIDTH (+ (val)) - 2)) - 1) * > > 2 + 1) \ > > : _GL_INT_CONVERT (val, 0)) \ > > >> (7)' > > => '(val) < \ > > ((((1 ? 0 : (val)) - (1)) < 0) \ > > ? ~ (((((1 ? 0 : (val)) + (1)) << (TYPE_WIDTH (+ (val)) - 2)) - 1) * > > 2 + 1) \ > > : _GL_INT_CONVERT (val, 0)) \ > > >> (7)' > > => '(val) < \ > > ((((1 ? 0 : (val)) - (1)) < 0) \ > > ? ~ (((((1 ? 0 : (val)) + (1)) << ((sizeof (val) * CHAR_BIT) - 2)) - > > 1) * 2 + 1) \ > > : _GL_INT_CONVERT (val, 0)) \ > > >> (7)' > > => '(val) < \ > > ((((1 ? 0 : (val)) - (1)) < 0) \ > > ? ~ (((((1 ? 0 : (val)) + (1)) << ((sizeof (val) * CHAR_BIT) - 2)) - > > 1) * 2 + 1) \ > > : ((1 ? 0 : (val)) + (0))) \ > > >> (7)' > > > > '_GL_INT_MINIMUM' returns the minimum value of the given type. Since 'val' > > is > > 'uint64_t', '_GL_INT_MINIMUM (val)' is 0 > > > > '(val) < _GL_INT_MINIMUM (val) >> (7)' => '(val) < 0 >> (7)' => '(val) < 0' > > > > For 'uint64_t val', the result is always false. > > > > However, in 'INT_LEFT_SHIFT_RANGE_OVERFLOW': > > > > ((a) < 0 \ > > ? (a) < (min) >> (b) \ > > : (max) >> (b) < (a)) > > > > '(a) < 0' is false for 'uint64_t val', so the second operand, '(a) < (min) > > >> (b)', > > is always skipped. Thus, the result of the second operand doesn't matter. > > What about the third operand? Does it return correct values? Can we > ignore this Coverity issue? If yes why? > > > ________________________________________________________________________________________________________ > > *** CID 435773: Integer handling issues (NO_EFFECT) > > /grub-core/lib/libtasn1/lib/decoding.c: 439 in asn1_get_object_id_der() > > 433 return ASN1_DER_ERROR; > > 434 > > 435 val0 = 0; > > 436 > > 437 for (k = 0; k < len; k++) > > 438 { > > >>> CID 435773: Integer handling issues (NO_EFFECT) > > >>> This less-than-zero comparison of an unsigned value is never true. > > >>> "(1 ? 0UL : val0) - 1UL < 0UL". > > 439 if (INT_LEFT_SHIFT_OVERFLOW (val0, 7)) > > 440 return ASN1_DER_ERROR; > > 441 > > 442 val0 <<= 7; > > 443 val0 |= der[len_len + k] & 0x7F; > > 444 if (!(der[len_len + k] & 0x80)) > > > > Here are the related macros from gnulib: > > > > #define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v)) > > > > #define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) > > > > #define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v)) > > > > #define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) > > > > #define _GL_SIGNED_INT_MAXIMUM(e) \ > > (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1) > > > > #define _GL_INT_MINIMUM(e) \ > > (EXPR_SIGNED (e) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (e) \ > > : _GL_INT_CONVERT (e, 0)) > > > > #define _GL_INT_MAXIMUM(e) \ > > (EXPR_SIGNED (e) \ > > ? _GL_SIGNED_INT_MAXIMUM (e) \ > > : _GL_INT_NEGATE_CONVERT (e, 1)) > > > > #define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max) \ > > ((a) < 0 \ > > ? (a) < (min) >> (b) \ > > : (max) >> (b) < (a)) > > > > #define INT_LEFT_SHIFT_OVERFLOW(a, b) \ > > INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \ > > _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) > > > > The statement in question is the expanded 'EXPR_SIGNED (val0)' from either > > '_GL_INT_MAXIMUM' or '_GL_INT_MINIMUM' > > > > 'EXPR_SIGNED (val0)' > > => '(_GL_INT_NEGATE_CONVERT (val0, 1) < 0)' > > => '(((1 ? 0 : (val0)) - (1)) < 0)' > > > > 'EXPR_SIGNED' is designed to test if the given expression is signed, and > > 'EXPR_SIGNED (val0)' is expected to be false for 'uint64_t val0'. The macro > > dutifully reflects the fact. > > Again, can we ignore this Coverity issue? Why? > > > ________________________________________________________________________________________________________ > > *** CID 435772: Integer handling issues (NO_EFFECT) > > /grub-core/lib/libtasn1/lib/decoding.c: 204 in asn1_get_tag_der() > > 198 /* Long form */ > > 199 punt = 1; > > 200 ris = 0; > > 201 while (punt < der_len && der[punt] & 128) > > 202 { > > 203 > > >>> CID 435772: Integer handling issues (NO_EFFECT) > > >>> This less-than-zero comparison of an unsigned value is never true. > > >>> "(1 ? 0U : ((1 ? 0U : ris) + 128U)) - 1U < 0U". > > 204 if (INT_MULTIPLY_OVERFLOW (ris, 128)) > > 205 return ASN1_DER_ERROR; > > 206 ris *= 128; > > 207 > > 208 if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F)))) > > 209 return ASN1_DER_ERROR; > > > > Here are the related macros gnulib: > > > > #define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v)) > > > > #define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v)) > > > > #define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) > > > > #define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) > > > > #define _GL_SIGNED_INT_MAXIMUM(e) \ > > (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1) > > > > #define _GL_INT_MINIMUM(e) \ > > (EXPR_SIGNED (e) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (e) \ > > : _GL_INT_CONVERT (e, 0)) > > > > #define _GL_INT_MAXIMUM(e) \ > > (EXPR_SIGNED (e) \ > > ? _GL_SIGNED_INT_MAXIMUM (e) \ > > : _GL_INT_NEGATE_CONVERT (e, 1)) > > > > #define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \ > > ((b) < 0 \ > > ? ((a) < 0 \ > > ? (a) < (max) / (b) \ > > : (b) == -1 \ > > ? 0 \ > > : (min) / (b) < (a)) \ > > : (b) == 0 \ > > ? 0 \ > > : ((a) < 0 \ > > ? (a) < (min) / (b) \ > > : (max) / (b) < (a))) > > > > # define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ > > (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \ > > || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) > > > > #define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \ > > op_result_overflow (a, b, \ > > _GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \ > > _GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b))) > > > > #define INT_MULTIPLY_OVERFLOW(a, b) \ > > _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW) > > > > The statement in question is the expanded 'EXPR_SIGNED (_GL_INT_CONVERT > > (ris, 128))' > > from either '_GL_INT_MINIMUM' or '_GL_INT_MAXIMUM'. > > > > 'EXPR_SIGNED (_GL_INT_CONVERT (ris, 128))' > > => 'EXPR_SIGNED ((1 ? 0 : (ris)) + (128))' > > => '(_GL_INT_NEGATE_CONVERT (((1 ? 0 : (ris)) + (128), 1) < 0))' > > => '((1 ? 0 : ((1 ? 0 : ris) + 128)) - 1 < 0)' > > > > '_GL_INT_CONVERT(e, v)' returns a value with the common real type of 'e' > > and 'v' and > > the value of 'v'. Since the common type of 'unsigned int ris' and '128' is > > 'unsigned int', '_GL_INT_CONVERT (ris, 128)' is '128U'. > > > > 'EXPR_SIGNED' is designed to check if the given expression is signed. Thus, > > 'EXPR_SIGNED (128U)' is expected to be false. > > > > The combination of 'EXPR_SIGNED(e)' and '_GL_INT_CONVERT(e, v)' is used to > > test if > > the common type of the given two variables is signed, and those macros > > dutifully > > reflect the fact: the common type of 'ris' and '128' is unsigned. > > Ditto. > > > ________________________________________________________________________________________________________ > > *** CID 435768: (CONSTANT_EXPRESSION_RESULT) > > /grub-core/lib/libtasn1/lib/decoding.c: 204 in asn1_get_tag_der() > > 198 /* Long form */ > > 199 punt = 1; > > 200 ris = 0; > > 201 while (punt < der_len && der[punt] & 128) > > 202 { > > 203 > > >>> CID 435768: (CONSTANT_EXPRESSION_RESULT) > > >>> "ris < (((1 ? 0 : ((1 ? 0 : ris) + 128)) - 1 < 0) ? ~((((1 ? 0 : > > >>> ((1 ? 0 : ris) + 128)) + 1 << 30UL /* sizeof (+((1 ? 0 : ris) + 128)) * > > >>> 8 - 2 */) - 1) * 2 + 1) : ((1 ? 0 : ((1 ? 0 : ris) + 128)) + 0)) / 128" > > >>> is always false regardless of the values of its operands. This occurs > > >>> as the second operand of "?:". > > 204 if (INT_MULTIPLY_OVERFLOW (ris, 128)) > > 205 return ASN1_DER_ERROR; > > 206 ris *= 128; > > 207 > > 208 if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F)))) > > 209 return ASN1_DER_ERROR; > > /grub-core/lib/libtasn1/lib/decoding.c: 217 in asn1_get_tag_der() > > 211 punt++; > > 212 } > > 213 > > 214 if (punt >= der_len) > > 215 return ASN1_DER_ERROR; > > 216 > > >>> CID 435768: (CONSTANT_EXPRESSION_RESULT) > > >>> "ris < (((1 ? 0 : ((1 ? 0 : ris) + 128)) - 1 < 0) ? ~((((1 ? 0 : > > >>> ((1 ? 0 : ris) + 128)) + 1 << 30UL /* sizeof (+((1 ? 0 : ris) + 128)) * > > >>> 8 - 2 */) - 1) * 2 + 1) : ((1 ? 0 : ((1 ? 0 : ris) + 128)) + 0)) / 128" > > >>> is always false regardless of the values of its operands. This occurs > > >>> as the second operand of "?:". > > 217 if (INT_MULTIPLY_OVERFLOW (ris, 128)) > > 218 return ASN1_DER_ERROR; > > 219 ris *= 128; > > 220 > > 221 if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F)))) > > 222 return ASN1_DER_ERROR; > > > > Here are the related macros gnulib: > > > > #define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v)) > > > > #define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v)) > > > > #define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) > > > > #define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) > > > > #define _GL_SIGNED_INT_MAXIMUM(e) \ > > (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1) > > > > #define _GL_INT_MINIMUM(e) \ > > (EXPR_SIGNED (e) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (e) \ > > : _GL_INT_CONVERT (e, 0)) > > > > #define _GL_INT_MAXIMUM(e) \ > > (EXPR_SIGNED (e) \ > > ? _GL_SIGNED_INT_MAXIMUM (e) \ > > : _GL_INT_NEGATE_CONVERT (e, 1)) > > > > #define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \ > > ((b) < 0 \ > > ? ((a) < 0 \ > > ? (a) < (max) / (b) \ > > : (b) == -1 \ > > ? 0 \ > > : (min) / (b) < (a)) \ > > : (b) == 0 \ > > ? 0 \ > > : ((a) < 0 \ > > ? (a) < (min) / (b) \ > > : (max) / (b) < (a))) > > > > # define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ > > (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \ > > || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) > > > > #define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \ > > op_result_overflow (a, b, \ > > _GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \ > > _GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b))) > > > > #define INT_MULTIPLY_OVERFLOW(a, b) \ > > _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW) > > > > The statement in question is the expanded '(a) < (min) / (b)' from > > 'INT_MULTIPLY_RANGE_OVERFLOW'. > > > > '(a) < (min) / (b)' > > => '(a) < (_GL_INT_MINIMUM (_GL_INT_CONVERT (a, b))) / (b)' > > => '(ris) < (_GL_INT_MINIMUM (_GL_INT_CONVERT (ris, 128))) / (128)' > > => '(ris) < \ > > (EXPR_SIGNED (_GL_INT_CONVERT (ris, 128)) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (_GL_INT_CONVERT (ris, 128)) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \ > > / (128)' > > => '(ris) < \ > > ((_GL_INT_NEGATE_CONVERT (_GL_INT_CONVERT (ris, 128), 1) < 0) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (_GL_INT_CONVERT (ris, 128)) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \ > > / (128)' > > => '(ris) < \ > > ((((1 ? 0 : (_GL_INT_CONVERT (ris, 128))) - (1)) < 0) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (_GL_INT_CONVERT (ris, 128)) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \ > > / (128)' > > => '(ris) < \ > > ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (_GL_INT_CONVERT (ris, 128)) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \ > > / (128)' > > => '(ris) < \ > > ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \ > > ? ~ (((_GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 1) << (TYPE_WIDTH > > (+ (_GL_INT_CONVERT (ris, 128))) - 2)) - 1) * 2 + 1) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \ > > / (128)' > > => '(ris) < \ > > ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \ > > ? ~ (((((1 ? 0 : (_GL_INT_CONVERT (ris, 128))) + (1)) << (TYPE_WIDTH > > (+ (_GL_INT_CONVERT (ris, 128))) - 2)) - 1) * 2 + 1) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \ > > / (128)' > > => '(ris) < \ > > ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \ > > ? ~ (((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) + (1)) << (TYPE_WIDTH (+ > > (_GL_INT_CONVERT (ris, 128))) - 2)) - 1) * 2 + 1) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \ > > / (128)' > > => '(ris) < \ > > ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \ > > ? ~ (((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) + (1)) << ((sizeof (+ > > (_GL_INT_CONVERT (ris, 128))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \ > > / (128)' > > => '(ris) < \ > > ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \ > > ? ~ (((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) + (1)) << ((sizeof (+ ((1 > > ? 0 : (ris)) + (128))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \ > > / (128)' > > => '(ris) < \ > > ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \ > > ? ~ (((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) + (1)) << ((sizeof (+ ((1 > > ? 0 : (ris)) + (128))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ris, 128), 0)) \ > > / (128)' > > => '(ris) < \ > > ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \ > > ? ~ (((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) + (1)) << ((sizeof (+ ((1 > > ? 0 : (ris)) + (128))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \ > > : ((1 ? 0 : (_GL_INT_CONVERT (ris, 128)) + (0)) \ > > / (128)' > > => '(ris) < \ > > ((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) - (1)) < 0) \ > > ? ~ (((((1 ? 0 : ((1 ? 0 : (ris)) + (128))) + (1)) << ((sizeof (+ ((1 > > ? 0 : (ris)) + (128))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \ > > : ((1 ? 0 : ((1 ? 0 : (ris)) + (128)) + (0)) \ > > / (128)' > > > > '_GL_INT_CONVERT(e, v)' returns a value with the common real type of 'e' > > and 'v' and > > the value of 'v'. Since the common type of 'unsigned int ris' and '128' is > > 'unsigned int', '_GL_INT_CONVERT (ris, 128)' is '128U'. > > > > '_GL_INT_MINIMUM (128U)' returns the minimum value of 'unsigned int', i.e. > > 0. > > > > '(ris) < (_GL_INT_MINIMUM (_GL_INT_CONVERT (ris, 128))) / (128)' => '(ris) > > < 0 / (128)' => '(ris) < 0' > > > > For 'unsigned int ris', the result is always false. > > > > However, in 'INT_MULTIPLY_RANGE_OVERFLOW', 'a' is 'unsigned int ris' and > > 'b' is '128'. > > We can skip the statements for 'b < 0' and 'b == 0' and reduce the macro to > > > > (a) < 0 \ > > ? (a) < (min) / (b) \ > > : (max) / (b) < (a))) \ > > > > Since '(a) < 0' is false for 'unsigned int ris', the statement in question, > > '(a) < (min) / (b)', is always skipped. Thus, the result of the statement > > doesn't > > matter. > > Same questions as for CID 435774... > > > ________________________________________________________________________________________________________ > > *** CID 435765: Integer handling issues (CONSTANT_EXPRESSION_RESULT) > > /grub-core/lib/libtasn1/lib/decoding.c: 439 in asn1_get_object_id_der() > > 433 return ASN1_DER_ERROR; > > 434 > > 435 val0 = 0; > > 436 > > 437 for (k = 0; k < len; k++) > > 438 { > > >>> CID 435765: Integer handling issues (CONSTANT_EXPRESSION_RESULT) > > >>> "val0 < ((((1 ? 0 : val0) - 1 < 0) ? ~((((1 ? 0 : val0) + 1 << 62UL > > >>> /* sizeof (+val0) * 8 - 2 */) - 1) * 2 + 1) : ((1 ? 0 : val0) + 0)) >> > > >>> 7)" is always false regardless of the values of its operands. This > > >>> occurs as the second operand of "?:". > > 439 if (INT_LEFT_SHIFT_OVERFLOW (val0, 7)) > > 440 return ASN1_DER_ERROR; > > 441 > > 442 val0 <<= 7; > > 443 val0 |= der[len_len + k] & 0x7F; > > 444 if (!(der[len_len + k] & 0x80)) > > > > Here are the related macros from gnulib: > > > > #define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v)) > > > > #define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) > > > > #define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v)) > > > > #define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) > > > > #define _GL_SIGNED_INT_MAXIMUM(e) \ > > (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1) > > > > #define _GL_INT_MINIMUM(e) \ > > (EXPR_SIGNED (e) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (e) \ > > : _GL_INT_CONVERT (e, 0)) > > > > #define _GL_INT_MAXIMUM(e) \ > > (EXPR_SIGNED (e) \ > > ? _GL_SIGNED_INT_MAXIMUM (e) \ > > : _GL_INT_NEGATE_CONVERT (e, 1)) > > > > #define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max) \ > > ((a) < 0 \ > > ? (a) < (min) >> (b) \ > > : (max) >> (b) < (a)) > > > > #define INT_LEFT_SHIFT_OVERFLOW(a, b) \ > > INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \ > > _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) > > > > The statement in question is expanded '(a) < (min) >> (b)' from > > INT_LEFT_SHIFT_RANGE_OVERFLOW. > > > > '(a) < (min) >> (b)' > > => '(val) < (_GL_INT_MINIMUM (val)) >> (7)' > > => '(val) < \ > > (EXPR_SIGNED (val) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (val) \ > > : _GL_INT_CONVERT (val, 0)) \ > > >> (7)' > > => '(val) < \ > > ((_GL_INT_NEGATE_CONVERT (val, 1) < 0) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (val) \ > > : _GL_INT_CONVERT (val, 0)) \ > > >> (7)' > > => '(val) < \ > > ((((1 ? 0 : (val)) - (1)) < 0) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (val) \ > > : _GL_INT_CONVERT (val, 0)) \ > > >> (7)' > > => '(val) < \ > > ((((1 ? 0 : (val)) - (1)) < 0) \ > > ? ~ (((_GL_INT_CONVERT (val, 1) << (TYPE_WIDTH (+ (val)) - 2)) - 1) * > > 2 + 1) \ > > : _GL_INT_CONVERT (val, 0)) \ > > >> (7)' > > => '(val) < \ > > ((((1 ? 0 : (val)) - (1)) < 0) \ > > ? ~ (((((1 ? 0 : (val)) + (1)) << (TYPE_WIDTH (+ (val)) - 2)) - 1) * > > 2 + 1) \ > > : _GL_INT_CONVERT (val, 0)) \ > > >> (7)' > > => '(val) < \ > > ((((1 ? 0 : (val)) - (1)) < 0) \ > > ? ~ (((((1 ? 0 : (val)) + (1)) << ((sizeof (+ (val)) * CHAR_BIT) - > > 2)) - 1) * 2 + 1) \ > > : _GL_INT_CONVERT (val, 0)) \ > > >> (7)' > > => '(val) < \ > > ((((1 ? 0 : (val)) - (1)) < 0) \ > > ? ~ (((((1 ? 0 : (val)) + (1)) << ((sizeof (+ (val)) * CHAR_BIT) - > > 2)) - 1) * 2 + 1) \ > > : ((1 ? 0 : (val)) + (0))) \ > > >> (7)' > > > > '_GL_INT_MINIMUM' returns the minimum value of the given type. For > > 'uint64_t val', > > '_GL_INT_MINIMUM (val)' is 0. > > > > '(val) < (_GL_INT_MINIMUM (val)) >> (7)' => '(val) < 0 >> (7)' => '(val) < > > 0' > > > > For 'uint64_t val', the result is always false. > > > > However, in 'INT_LEFT_SHIFT_RANGE_OVERFLOW': > > > > ((a) < 0 \ > > ? (a) < (min) >> (b) \ > > : (max) >> (b) < (a)) > > > > '(a) < 0' is false for 'uint64_t val', so the statement in question, > > '(a) < (min) >> (b)', is always skipped. Thus, the result of the statement > > doesn't > > matter. > > Ditto. > > > ________________________________________________________________________________________________________ > > *** CID 435764: Integer handling issues (NO_EFFECT) > > /grub-core/lib/libtasn1/lib/decoding.c: 137 in asn1_get_length_der() > > 131 punt = 1; > > 132 if (k) > > 133 { /* definite length method */ > > 134 ans = 0; > > 135 while (punt <= k && punt < der_len) > > 136 { > > >>> CID 435764: Integer handling issues (NO_EFFECT) > > >>> This less-than-zero comparison of an unsigned value is never true. > > >>> "(1 ? 0U : ((1 ? 0U : ans) + 256U)) - 1U < 0U". > > 137 if (INT_MULTIPLY_OVERFLOW (ans, 256)) > > 138 return -2; > > 139 ans *= 256; > > 140 > > 141 if (INT_ADD_OVERFLOW (ans, ((unsigned) der[punt]))) > > 142 return -2; > > > > Here are the related macros from gnulib: > > > > #define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v)) > > > > #define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v)) > > > > #define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) > > > > #define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) > > > > #define _GL_SIGNED_INT_MAXIMUM(e) \ > > (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1) > > > > #define _GL_INT_MINIMUM(e) \ > > (EXPR_SIGNED (e) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (e) \ > > : _GL_INT_CONVERT (e, 0)) > > > > #define _GL_INT_MAXIMUM(e) \ > > (EXPR_SIGNED (e) \ > > ? _GL_SIGNED_INT_MAXIMUM (e) \ > > : _GL_INT_NEGATE_CONVERT (e, 1)) > > > > #define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \ > > ((b) < 0 \ > > ? ((a) < 0 \ > > ? (a) < (max) / (b) \ > > : (b) == -1 \ > > ? 0 \ > > : (min) / (b) < (a)) \ > > : (b) == 0 \ > > ? 0 \ > > : ((a) < 0 \ > > ? (a) < (min) / (b) \ > > : (max) / (b) < (a))) > > > > # define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ > > (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \ > > || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) > > > > #define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \ > > op_result_overflow (a, b, \ > > _GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \ > > _GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b))) > > > > #define INT_MULTIPLY_OVERFLOW(a, b) \ > > _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW) > > > > The statement in question is expanded 'EXPR_SIGNED (_GL_INT_CONVERT (ans, > > 256))' > > from either '_GL_INT_MINIMUM' or '_GL_INT_MAXIMUM'. > > > > 'EXPR_SIGNED (_GL_INT_CONVERT (ans, 256))' > > => 'EXPR_SIGNED ((1 ? 0 : (ans)) + (256))' > > => '(_GL_INT_NEGATE_CONVERT (((1 ? 0 : (ans)) + (256)), 1) < 0)' > > => '((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1))' > > > > '_GL_INT_CONVERT(e, v)' returns a value with the common real type of 'e' > > and 'v' and > > the value of 'v'. Since the common type of 'unsigned int ans' and '256' is > > 'unsigned int', '_GL_INT_CONVERT (ans, 256)' is '256U'. > > > > 'EXPR_SIGNED' is designed to check if the given expression is signed. Thus, > > 'EXPR_SIGNED (256U)' is expected to be false. > > > > The combination of 'EXPR_SIGNED(e)' and '_GL_INT_CONVERT(e, v)' is used to > > test if > > the common type of the given two variables is signed, and those macros > > dutifully > > reflect the fact: the common type of 'ans' and '256' is unsigned. > > Can we ignore this Coverity issue? Why? > > > ________________________________________________________________________________________________________ > > *** CID 435763: Integer handling issues (CONSTANT_EXPRESSION_RESULT) > > /grub-core/lib/libtasn1/lib/decoding.c: 137 in asn1_get_length_der() > > 131 punt = 1; > > 132 if (k) > > 133 { /* definite length method */ > > 134 ans = 0; > > 135 while (punt <= k && punt < der_len) > > 136 { > > >>> CID 435763: Integer handling issues (CONSTANT_EXPRESSION_RESULT) > > >>> "ans < (((1 ? 0 : ((1 ? 0 : ans) + 256)) - 1 < 0) ? ~((((1 ? 0 : > > >>> ((1 ? 0 : ans) + 256)) + 1 << 30UL /* sizeof (+((1 ? 0 : ans) + 256)) * > > >>> 8 - 2 */) - 1) * 2 + 1) : ((1 ? 0 : ((1 ? 0 : ans) + 256)) + 0)) / 256" > > >>> is always false regardless of the values of its operands. This occurs > > >>> as the second operand of "?:". > > 137 if (INT_MULTIPLY_OVERFLOW (ans, 256)) > > 138 return -2; > > 139 ans *= 256; > > 140 > > 141 if (INT_ADD_OVERFLOW (ans, ((unsigned) der[punt]))) > > 142 return -2; > > > > Here are the related macros from gnulib: > > > > #define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v)) > > > > #define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v)) > > > > #define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) > > > > #define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) > > > > #define _GL_SIGNED_INT_MAXIMUM(e) \ > > (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1) > > > > #define _GL_INT_MINIMUM(e) \ > > (EXPR_SIGNED (e) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (e) \ > > : _GL_INT_CONVERT (e, 0)) > > > > #define _GL_INT_MAXIMUM(e) \ > > (EXPR_SIGNED (e) \ > > ? _GL_SIGNED_INT_MAXIMUM (e) \ > > : _GL_INT_NEGATE_CONVERT (e, 1)) > > > > #define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \ > > ((b) < 0 \ > > ? ((a) < 0 \ > > ? (a) < (max) / (b) \ > > : (b) == -1 \ > > ? 0 \ > > : (min) / (b) < (a)) \ > > : (b) == 0 \ > > ? 0 \ > > : ((a) < 0 \ > > ? (a) < (min) / (b) \ > > : (max) / (b) < (a))) > > > > # define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ > > (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \ > > || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) > > > > #define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \ > > op_result_overflow (a, b, \ > > _GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \ > > _GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b))) > > > > #define INT_MULTIPLY_OVERFLOW(a, b) \ > > _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW) > > > > The statement in question is the expanded '(a) < (min) / (b)' from > > INT_MULTIPLY_RANGE_OVERFLOW. > > > > '(a) < (min) / (b)' > > => '(a) < (_GL_INT_MINIMUM (_GL_INT_CONVERT (a, b))) / (b)' > > => '(ans) < (_GL_INT_MINIMUM (_GL_INT_CONVERT (ans, 256))) / (256)' > > => '(ans) < \ > > (EXPR_SIGNED (_GL_INT_CONVERT (ans, 256)) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (_GL_INT_CONVERT (ans, 256)) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \ > > / (256)' > > => '(ans) < \ > > (_GL_INT_NEGATE_CONVERT (_GL_INT_CONVERT (ans, 256), 1) < 0) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (_GL_INT_CONVERT (ans, 256)) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \ > > / (256)' > > => '(ans) < \ > > (((1 ? 0 : (_GL_INT_CONVERT (ans, 256))) - (1)) < 0) \ > > ? ~ _GL_SIGNED_INT_MAXIMUM (_GL_INT_CONVERT (ans, 256)) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \ > > / (256)' > > => '(ans) < \ > > (((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1)) < 0) \ > > ? ~ (((_GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 1) << (TYPE_WIDTH > > (+ (_GL_INT_CONVERT (ans, 256))) - 2)) - 1) * 2 + 1) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \ > > / (256)' > > => '(ans) < \ > > (((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1)) < 0) \ > > ? ~ ((((1 ? 0 : (_GL_INT_CONVERT (ans, 256))) + (1)) << (TYPE_WIDTH > > (+ (_GL_INT_CONVERT (ans, 256))) - 2)) - 1) * 2 + 1) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \ > > / (256)' > > => '(ans) < \ > > (((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1)) < 0) \ > > ? ~ ((((1 ? 0 : ((1 ? 0 : (ans)) + (256))) + (1)) << (TYPE_WIDTH (+ > > (_GL_INT_CONVERT (ans, 256))) - 2)) - 1) * 2 + 1) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \ > > / (256)' > > => '(ans) < \ > > (((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1)) < 0) \ > > ? ~ ((((1 ? 0 : ((1 ? 0 : (ans)) + (256))) + (1)) << ((sizeof (+ > > (_GL_INT_CONVERT (ans, 256))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \ > > / (256)' > > => '(ans) < \ > > (((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1)) < 0) \ > > ? ~ ((((1 ? 0 : ((1 ? 0 : (ans)) + (256))) + (1)) << ((sizeof (+ ((1 > > ? 0 : (ans)) + (1))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \ > > : _GL_INT_CONVERT (_GL_INT_CONVERT (ans, 256), 0)) \ > > / (256)' > > => '(ans) < \ > > (((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1)) < 0) \ > > ? ~ ((((1 ? 0 : ((1 ? 0 : (ans)) + (256))) + (1)) << ((sizeof (+ ((1 > > ? 0 : (ans)) + (1))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \ > > : ((1 ? 0 : (_GL_INT_CONVERT (ans, 256))) + (0)) ) \ > > / (256)' > > => '(ans) < \ > > (((1 ? 0 : ((1 ? 0 : (ans)) + (256))) - (1)) < 0) \ > > ? ~ ((((1 ? 0 : ((1 ? 0 : (ans)) + (256))) + (1)) << ((sizeof (+ ((1 > > ? 0 : (ans)) + (1))) * CHAR_BIT) - 2)) - 1) * 2 + 1) \ > > : ((1 ? 0 : ((1 ? 0 : (ans)) + (256))) + (0)) ) \ > > / (256)' > > > > > > '_GL_INT_CONVERT(e, v)' returns a value with the common real type of 'e' > > and 'v' and > > the value of 'v'. Since the common type of 'unsigned int ans' and '256' is > > 'unsigned int', '_GL_INT_CONVERT (ans, 256)' is '256U'. > > > > '_GL_INT_MINIMUM (256U)' returns the minimum value of 'unsigned int', i.e. > > 0. > > > > '(ans) < (_GL_INT_MINIMUM (_GL_INT_CONVERT (ans, 256))) / (256)' => '(ans) > > < 0 / (256)' => '(ans) < 0' > > > > For 'unsigned int ans', the result is always false. > > > > However, in 'INT_MULTIPLY_RANGE_OVERFLOW', 'a' is 'unsigned int ans' and > > 'b' is '256'. > > We can skip the statements for 'b < 0' and 'b == 0' and reduce the macro to > > > > (a) < 0 \ > > ? (a) < (min) / (b) \ > > : (max) / (b) < (a))) \ > > > > Since '(ans) < 0' is false for 'unsigned int ans', the statement in > > question, > > '(a) < (min) / (b)', is always skipped. Thus, the result of the statement > > doesn't > > matter. > > Same questions as for CID 435774... > > Daniel _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel