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

Runtime should be hardened against integer overflow #7492

Closed
vicuna opened this issue Feb 23, 2017 · 10 comments
Closed

Runtime should be hardened against integer overflow #7492

vicuna opened this issue Feb 23, 2017 · 10 comments

Comments

@vicuna
Copy link

vicuna commented Feb 23, 2017

Original bug ID: 7492
Reporter: @murmour
Status: acknowledged (set by @dra27 on 2017-02-23T09:20:07Z)
Resolution: open
Priority: normal
Severity: minor
Version: 4.06.0 +dev/beta1/beta2/rc1
Category: runtime system and C interface
Monitored by: @gasche @yallop @yakobowski

Bug description

There are numerous places inside the runtime where integer multiplication or addition is performed without an overflow check. In many of those situations, overflow is practically impossible because the operands are known to be small enough (e.g. a small integer is multiplied by a sizeof(type)), but sometimes it's far from obvious, and so exists the danger of triggering undefined behaviour.

The said above applies to stdlib C stubs as well.

One common source of potential errors involves memory allocation. The malignant pattern is "caml_stat_alloc(x * y)", which can be hardened by making it into "caml_stat_calloc(x, y)". Calloc is supposed to perform an overflow check, and does so in many implementations, although it's unclear whether it is required to do so by the standard. So far, calloc is only used in a couple of places inside the whole runtime. Perhaps it would be beneficial to use it in place of all occurrences of "caml_stat_alloc(x * y)"?

Recently, as part of #71, the implementation of caml_stat_calloc was changed so that it no longer makes use of the system-provided calloc. The new implementation performs no overflow checks at all. If calloc is to be used more commonly in the runtime, caml_stat_calloc must be augmented with a proper overflow check.

Checking for overflow in a portable way is non-trivial in C. Fortunately, we already have a battle-tested routine for safe multiplication -- caml_ba_multov in bigarray_stubs.c. I did quite a bit of research, and AFAIK this approach to overflow detection strikes the best balance of portability and performance. The only faster solution involves non-standard type uint128_t that is not available in Visual Studio and older versions of GCC.

How about moving caml_ba_multov into misc.h (as a differently named #define) so that it could be used elsewhere (e.g. in caml_stat_calloc)?

More danger comes from so called tainted sources -- that is, external sources of untrusted data. Examples of tainted sources are: user input, compiler parameters, environment variables, arguments to C stubs.

For example, these primitives from otherlibs/graph take integers from the user and perform multiplication without an overflow check, which may lead to dangerous consequences:
caml_gr_new_image
caml_gr_fill_arc_nat
caml_gr_draw_arc_nat
caml_gr_create_image

If there were a standard overflow check routine (in misc.h or elsewhere), it could be used to harden such functions.

@vicuna
Copy link
Author

vicuna commented Feb 23, 2017

Comment author: @gasche

(Fore more context, the specific comment in #71 that prompted this issue is

#71 (comment)

)

@vicuna
Copy link
Author

vicuna commented Feb 23, 2017

Comment author: @dra27

@murmour - is this an improvement you might (be able to) consider doing a patch for? We can hope to take less than 2.5 years to merge this time...!

@vicuna
Copy link
Author

vicuna commented Feb 23, 2017

Comment author: @mshinwell

The lack of overflow checking on the calloc function appears to be a regression in #71, and as I wrote on that pull request, I think we should probably fix that before merging.

@vicuna
Copy link
Author

vicuna commented Feb 23, 2017

Comment author: @xavierleroy

I agree with the point made here and will think about adding some safe arithmetic functions to the OCaml runtime.

Regarding implementation of those functions, recent GCC and Clang have builtins, otherwise portable code like the one currently in bigarrays is no big deal.

The one remark I disagree with is that "malloc(x * y)" should always be replaced by "calloc(x, y)". The latter zeroes out the resulting memory, which is not needed (assuming the original malloc-based code was correct) and comes at a cost.

@vicuna
Copy link
Author

vicuna commented Feb 23, 2017

Comment author: @xavierleroy

See proposal at #1060

@vicuna
Copy link
Author

vicuna commented Feb 23, 2017

Comment author: @murmour

The one remark I disagree with is that "malloc(x * y)" should always be replaced by "calloc(x, y)". The latter zeroes out the resulting memory, which is not needed (assuming the original malloc-based code was correct) and comes at a cost.

True. How about adding caml_stat_alloc_array that would only check for overflow, without zeroing out memory?

@vicuna
Copy link
Author

vicuna commented Feb 23, 2017

Comment author: @murmour

@murmour - is this an improvement you might (be able to) consider doing a patch for? We can hope to take less than 2.5 years to merge this time...!

Sure. Persistence and pedantry are my biggest talents, especially when it comes to incredibly boring multi-year efforts. I am the hero who can never be bored with the mundane. ;-)

@github-actions
Copy link

github-actions bot commented May 9, 2020

This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.

@github-actions github-actions bot added the Stale label May 9, 2020
@lpw25
Copy link
Contributor

lpw25 commented May 10, 2020

I think this was addressed in #1060

@lpw25 lpw25 closed this as completed May 10, 2020
@skypexu
Copy link

skypexu commented Mar 6, 2023

it seems only rust can check overflow

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

No branches or pull requests

3 participants