Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NCC-2016-003 - Conversion to ‘std::size_t’ from ‘long int’ #1240

Closed
rcseacord opened this issue Aug 12, 2016 · 14 comments · Fixed by #4060
Closed

NCC-2016-003 - Conversion to ‘std::size_t’ from ‘long int’ #1240

rcseacord opened this issue Aug 12, 2016 · 14 comments · Fixed by #4060
Assignees
Labels
C-audit Category: Issues and tasks related to audit findings C-cleanup Category: PRs that clean code up or issues documenting cleanup. I-SECURITY Problems and improvements related to security. portability spring_cleaning Z-libsnark Historic: libsnark

Comments

@rcseacord
Copy link
Contributor

rcseacord commented Aug 12, 2016

the loop interator i should be declared as size_t in three locations:

src/algebra/curves/alt_bn128/alt_bn128_pairing.cpp:327:38: warning: conversion to ‘long int’ from ‘size_t {aka long unsigned int}’ may change the sign of the result [-Wsign-conversion]
     for (long i = loop_count.max_bits(); i >= 0; --i)
                   ~~~~~~~~~~~~~~~~~~~^~
src/algebra/curves/alt_bn128/alt_bn128_pairing.cpp:329:47: warning: conversion to ‘std::size_t {aka long unsigned int}’ from ‘long int’ may change the sign of the result [-Wsign-conversion]
         const bool bit = loop_count.test_bit(i);
                                               ^
src/algebra/curves/alt_bn128/alt_bn128_pairing.cpp: In function ‘libsnark::alt_bn128_Fq12 libsnark::alt_bn128_ate_miller_loop(const libsnark::alt_bn128_ate_G1_precomp&, const libsnark::alt_bn128_ate_G2_precomp&)’:
src/algebra/curves/alt_bn128/alt_bn128_pairing.cpp:381:38: warning: conversion to ‘long int’ from ‘size_t {aka long unsigned int}’ may change the sign of the result [-Wsign-conversion]
     for (long i = loop_count.max_bits(); i >= 0; --i)
                   ~~~~~~~~~~~~~~~~~~~^~
src/algebra/curves/alt_bn128/alt_bn128_pairing.cpp:383:47: warning: conversion to ‘std::size_t {aka long unsigned int}’ from ‘long int’ may change the sign of the result [-Wsign-conversion]
         const bool bit = loop_count.test_bit(i);
                                               ^
src/algebra/curves/alt_bn128/alt_bn128_pairing.cpp: In function ‘libsnark::alt_bn128_Fq12 libsnark::alt_bn128_ate_double_miller_loop(const libsnark::alt_bn128_ate_G1_precomp&, const libsnark::alt_bn128_ate_G2_precomp&, const libsnark::alt_bn128_ate_G1_precomp&, const libsnark::alt_bn128_ate_G2_precomp&)’:
src/algebra/curves/alt_bn128/alt_bn128_pairing.cpp:435:38: warning: conversion to ‘long int’ from ‘size_t {aka long unsigned int}’ may change the sign of the result [-Wsign-conversion]
     for (long i = loop_count.max_bits(); i >= 0; --i)
                   ~~~~~~~~~~~~~~~~~~~^~
src/algebra/curves/alt_bn128/alt_bn128_pairing.cpp:437:47: warning: conversion to ‘std::size_t {aka long unsigned int}’ from ‘long int’ may change the sign of the result [-Wsign-conversion]
         const bool bit = loop_count.test_bit(i);

Repair in 3 locations:

-    for (long i = loop_count.max_bits(); i >= 0; --i)
+    for (size_t i = loop_count.max_bits(); i >= std:size_t{0}; --i)

Similar problems:

src/algebra/fields/field_utils.tcc:175:29: warning: conversion to ‘long int’ from ‘std::vector<libsnark::Fp2_model<4l, ((const libsnark::bigint<4l>&)(& libsnark::alt_bn128_modulus_q))> >::size_type {aka long unsigned int}’ may change the sign of the result [-Wsign-conversion]
     for (long i = vec.size()-1; i >= 0; --i)

src/algebra/fields/field_utils.tcc:177:34: warning: conversion to ‘std::vector<libsnark::Fp2_model<4l, ((const libsnark::bigint<4l>&)(& libsnark::alt_bn128_modulus_q))> >::size_type {aka long unsigned int}’ from ‘long int’ may change the sign of the result [-Wsign-conversion]
         const FieldT old_el = vec[i];
                               ~~~^
src/algebra/fields/field_utils.tcc:178:12: warning: conversion to ‘std::vector<libsnark::Fp2_model<4l, ((const libsnark::bigint<4l>&)(& libsnark::alt_bn128_modulus_q))> >::size_type {aka long unsigned int}’ from ‘long int’ may change the sign of the result [-Wsign-conversion]
         vec[i] = acc_inverse * prod[i];
         ~~~^
src/algebra/fields/field_utils.tcc:178:36: warning: conversion to ‘std::vector<libsnark::Fp2_model<4l, ((const libsnark::bigint<4l>&)(& libsnark::alt_bn128_modulus_q))> >::size_type {aka long unsigned int}’ from ‘long int’ may change the sign of the result [-Wsign-conversion]
         vec[i] = acc_inverse * prod[i];
                                ~~~~^

Repair:

-   for (long i = vec.size()-1; i >= 0; --i)
+    for (size_t i = vec.size()-1; i >= size_t{0}; --i)
@daira daira added Z-libsnark Historic: libsnark C-cleanup Category: PRs that clean code up or issues documenting cleanup. needs prioritization labels Aug 12, 2016
@nathan-at-least nathan-at-least added I-SECURITY Problems and improvements related to security. NCC finding labels Sep 6, 2016
@nathan-at-least nathan-at-least changed the title Conversion to ‘std::size_t’ from ‘long int’ NCC-2016-003 - Conversion to ‘std::size_t’ from ‘long int’ Sep 6, 2016
@nathan-at-least
Copy link
Contributor

Is this a. either very easy, or b. notable risk of compromise (on any architecture)? If so, let's put it in the 1.0 target, otherwise, after 1.0.

paging @daira and @ebfull for their libsnark & security expertise here.

@coinspect
Copy link

Changing the type of a counter from signed to 'std::size_t' can introduce dangerous bugs or memory corruption vulnerabilities in some cases. For example the code above crashes if vec.size() is zero. Before changing the type, check if < 0 or while >= 0 is being used as a boundary check.

for (size_t i = vec.size()-1; i >= size_t{0}; --i) 

@ebfull
Copy link
Contributor

ebfull commented Oct 8, 2016

None of these are exploitable, so we can bump this to 1.0.1. (We'll want to patch them upstream.)

@ebfull ebfull removed their assignment Oct 8, 2016
@nathan-at-least
Copy link
Contributor

@daira: Please review for exploitability. If you agree it's not an exposed attack surface, postpone this to 1.0.1.

@daira
Copy link
Contributor

daira commented Oct 18, 2016

This is definitely not exploitable.

@daira daira modified the milestones: 1.0.1 stabilization, 1.0.0-rc2 Oct 18, 2016
@daira
Copy link
Contributor

daira commented Jan 28, 2017

Note that the proposed repair is wrong because size_t is unsigned, so will always be >= 0 even at the intended end of the loop.

@radix42
Copy link
Contributor

radix42 commented Jan 28, 2017

Portability note: to get libsnark to work on a native (non-Cygwin) build on 64 bit Windows, in MANY places we had to change instances of size_t to int64_t (size_t is 32 bits wide on windows, always, as is long), and there are a few places in the zcash code itself where the same was true.

In libsnark issue 66 we're changing ALL integer types to C++11 types that have an explicit bit width that does not vary due to platform: banishing long, unsigned long and size_t (as myself and @joshuayabut have had to do to get libsnark and zcash working on Windows in the pruned subset of libsnark we forked from zcash/libsnark).

@tromer
Copy link
Contributor

tromer commented Jan 28, 2017

Why would you need to change size_t?

When long or unsigned long are used for data (e.g., limbs of bigints), it's clear why you need to fix the big length.

But size_t is supposed to be used for values which are array sizes, loop indices, byte counts and the like; it's not supposed to matter whether these are 32 bits or 64 bits (as long as they don't overflow).

@radix42
Copy link
Contributor

radix42 commented Jan 28, 2017

yes I know its not SUPPOSED to matter, but here we are....I can revert one of the ones we had to change and paste how it blows up for you sometime, but I can assure you it is indeed the case (I'll do that at some point for libsnark 66 but I'm too tired right now to fuss with it)

@radix42
Copy link
Contributor

radix42 commented Jan 28, 2017

Here's a spot in my Mac port where a similar change from size_t to uint64_t was needed where that change SHOULDN'T have been needed (@joshuayabut just recently figured out why):

#1800

See the code changes in the "Files" tab and the long error output you get when you revert just that change. The size_t changes needed for libsnark on windows do the same thing.

@radix42
Copy link
Contributor

radix42 commented Jan 28, 2017

and yes its maddening and no its not supposed to do that

@tromer
Copy link
Contributor

tromer commented Jan 28, 2017

Ah. The code that actually uses size_t is fine, but conversion to other integer types, or matching against other integer types in overloading, are broken. Makes sense.

Still, it converting size_t to uint64_t loses painstakingly-tracked information about these values (the fact that they are sizes/indices rather than data). That's a shame.

If the size_t portability problems are indeed all compile/link problems (so can be reliably found), and there's a reasonable number of them (no more than a few dozen), then how about keeping the size_t and adding explicit casts to uint64_t where needed to resolve the errors?

@radix42
Copy link
Contributor

radix42 commented Jan 28, 2017

that sounds reasonable...in one case in the Mac port @joshuayabut was able to revert one of the size_t->unit64_t changes that'd been made by fooling with where it was blowing up by adding an explicit template somewhere...I'd need to go digging through git logs to find what that was

@tromer
Copy link
Contributor

tromer commented Jan 28, 2017

FYI, @rcseacord of NCC submitted a libsnark pull request which changes long to size_t, assert to assert_except, and a few other things: scipr-lab/libsnark#53

It was NAKed for the reasons discussed in that PR's review comments (which partially overlap with the above, #2043 and scipr-lab/libsnark#64).

@nathan-at-least nathan-at-least removed this from the 1.0.[Soon] stabilization milestone May 25, 2017
@daira daira mentioned this issue Jun 26, 2019
zkbot added a commit that referenced this issue Aug 12, 2019
Remove libsnark

To-do:

- [x] Fix RPC tests.
- [ ] Remove now-dead codepaths.
- [ ] Add notable changes.

Closes #743. Closes #750. Closes #894. Closes #903.
Closes #1125. Closes #1136. Closes #1240. Closes #1264.
Closes #1516. Closes #1517. Closes #1651. Closes #2064.
Closes #2158. Closes #3478. Closes #3652. Closes #3744.
zkbot added a commit that referenced this issue Aug 22, 2019
Remove libsnark

To-do:

- [x] Fix RPC tests.
- [ ] Remove now-dead codepaths.
- [ ] Add notable changes.

Closes #521.
Closes #743. Closes #750. Closes #894. Closes #903.
Closes #1125. Closes #1136. Closes #1240. Closes #1264.
Closes #1516. Closes #1517. Closes #1651. Closes #2064.
Closes #2158. Closes #3478. Closes #3652. Closes #3744.
@zkbot zkbot closed this as completed in 961c0d5 Sep 26, 2019
@Eirik0 Eirik0 modified the milestone: v2.1.0 Oct 10, 2019
@str4d str4d added the C-audit Category: Issues and tasks related to audit findings label Aug 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-audit Category: Issues and tasks related to audit findings C-cleanup Category: PRs that clean code up or issues documenting cleanup. I-SECURITY Problems and improvements related to security. portability spring_cleaning Z-libsnark Historic: libsnark
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants