grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v20 00/33] Automatic Disk Unlock with TPM2


From: Daniel Kiper
Subject: Re: [PATCH v20 00/33] Automatic Disk Unlock with TPM2
Date: Wed, 23 Oct 2024 15:52:43 +0200

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 <OKir@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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]