Skip to content

Use variable-length array instead of malloc/free. - #32

Closed
ryancdotorg wants to merge 1 commit into
libtom:developfrom
ryancdotorg:ryancdotorg/var_len_array
Closed

ryancdotorg wants to merge 1 commit into
libtom:developfrom
ryancdotorg:ryancdotorg/var_len_array

Conversation

@ryancdotorg

Copy link
Copy Markdown
Contributor

The only use of malloc/free in tomfastmath is in src/numtheory/fp_prime_random_ex.c, and the size required can be calculated from the function arguments, so we can just use a variable-length automatic array instead.

Variable-length automatic arrays are a C99 feature, and TFM already doesn’t compile as C90, so we might as well take advantage of it.

This is a smaller part of a patchset to allow tomsfastmath to be compiled without stdlib, e.g. for freestanding webassembly.

The only use of `malloc`/`free` in tomfastmath is in
src/numtheory/fp_prime_random_ex.c, and the size required can be
calculated from the function arguments, so we can just use
a variable-length automatic array instead.

Variable-length automatic arrays are a C99 feature, and TFM already doesn’t
compile as C90, so we might as well take advantage of it.
@levitte

levitte commented Sep 16, 2024

Copy link
Copy Markdown
Collaborator

There's also #4, which while being quite old at this point, also does away with memory allocation by having a fixed size buffer.

@ryancdotorg

ryancdotorg commented Sep 16, 2024 via email

Copy link
Copy Markdown
Contributor Author

@levitte

levitte commented Sep 16, 2024

Copy link
Copy Markdown
Collaborator

In the end, nothing stops both from being merged 😉

@sjaeckel sjaeckel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the dynamic allocation does not really make sense here.

I don't like VLA's, so I'd propose to use a stack based buffer of maximum size instead.

unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb;
int res, err, bsize, maskOR_msb_offset;
/* calc the byte size */
unsigned char tmp[(size>>3)+(size&7?1:0)];

@sjaeckel sjaeckel Sep 17, 2024 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
unsigned char tmp[(size>>3)+(size&7?1:0)];
unsigned char tmp[sizeof(a->dp)];

Why not simply allocate a statically sized stack array of max size?

This would also require something like the following, after calculating bsize.

if (bsize > sizeof(tmp))
   return MP_VAL;

@levitte

levitte commented Sep 17, 2024

Copy link
Copy Markdown
Collaborator

Would the use of VLAs diminish the risk of stack overflows?

Ref: libtom/libtomcrypt#461 (comment)

@sjaeckel

Copy link
Copy Markdown
Member

Would the use of VLAs diminish the risk of stack overflows?

FMU the use of VLAs as done here increases the risk of a stack overflow, since there's no upper boundary of size implemented.

Calling this version of the API like this: fp_prime_random_ex(&foo, bar, 8192*1024*8, baz, qux, quux) would already overflow the stack of most linux systems. Does it make sense? No. Is it possible and therefore a potential problem? IMO yes.

The upper boundary of size is effectively the max size of an fp_int, so supporting bigger sizes does not make sense. Even if this would be fixed with a check I'm not sure if there would be any advantage of a VLA approach here over a fixed size array.

With a VLA here the stack usage would indeed be minimized in all cases where size is smaller than the max size, but that's not something that is usually done when modelling this problem, right? In that model one usually expects that numbers are huge and it still shouldn't fail unexpectedly, e.g. by overflowing the stack.

@sjaeckel

Copy link
Copy Markdown
Member

Ref: libtom/libtomcrypt#461 (comment)

TBH I never checked the max. stack depth of tfm in detail and I just thought that this could become a problem if you increase the fp_int size too much. Now that I did the numbers that's maybe also not really the case...

To be able to work with RSA16384 keys one has to set #define FP_MAX_SIZE ((16384*2)+(8*DIGIT_BIT)), which increases the stack usage of each fp_int to more than 4KiB. This would allow >2k of those fp_int's with the default stack size, which can't be reached by calling TFM API's alone. TFM has no recursive functions AFAICT and what I saw when checking the more complex APIs was far below this number.

One thing I'm not sure of is if (8*DIGIT_BIT) is enough for such big sizes. IIRC that's some scratch space for comba or montgomery and I'm not deep enough in the math theory to tell if that number should grow with the total size or if that's just some scratch area that can be fixed size. The documentation says that it should be 4 digits, but the implementation was changed in tfm 0.06 to 8 digits... Maybe someone else can tell us more on that? I'm preventive mentioning @czurnieden here, in case nobody else pops up :)

@levitte

levitte commented Sep 17, 2024

Copy link
Copy Markdown
Collaborator

Okie, I understand re VLA. For the rest, I'll try to make time to look at that scratch space to see what's what

@levitte

levitte commented Sep 18, 2024

Copy link
Copy Markdown
Collaborator

Considering all the commentary here, I rebooted #4 → #39. Please have a look at that. @ryancdotorg, I would your commentary there.

@ryancdotorg

Copy link
Copy Markdown
Contributor Author

I'll try to understand it on Sunday, but TBH it's been a while since I touched it, so I'm not sure how much help I can provide. I'm happy with any solution that avoids malloc.

@levitte

levitte commented Sep 19, 2024

Copy link
Copy Markdown
Collaborator

I'll try to understand it on Sunday, but TBH it's been a while since I touched it, so I'm not sure how much help I can provide. I'm happy with any solution that avoids malloc.

@sjaeckel merged #39 now, so you at least got rid of malloc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants