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. > ________________________________________________________________________________________________________ > *** 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 > > ________________________________________________________________________________________________________ > *** 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