2

I have to do integer arithmetic in kernel, specifically I need to increment a size_t object by some delta, and this will happen quite often. So I'm wondering if I need to guard against possible integer overflows in the kernel, and if so, does the kernel provide macros or APIs for this?

Viktor Dahl
  • 1,942
  • 3
  • 25
  • 36
Mark
  • 6,052
  • 8
  • 61
  • 129
  • 2
    `size_t` is unsigned, and unsigned overflow is well-defined, so from the language perspective you are in the clear - overflowing a `size_t` doesn't have bad consequences *by itself*. Of course the result will wrap around, so the logic of your code must be able to deal with it. – Matteo Italia Mar 29 '17 at 20:12

2 Answers2

3

size_t doesn't overflow; it is an unsigned type, with well-defined "wraparound" semantics. Incrementing the highest value of a size_t results in zero.

In the specific case of size_t, in simple operations on size_t, like adding two sizes together, it is usually enough to just check whether the resulting operand is larger than one of the two source operands. If (size3 = size1 + size2) < size1), you have a wrap.

If an unsigned type is used as a clock value which goes around a "wheel", there are macros for doing "time before" calculations correctly. For instance, we want the time 0xFFFFFFFE to be treated as being a few time units in the past w.r.t. the time 0x00000003. If you're using the "jiffies" time in the kernel, then you can use the time_before inline function, and others in that family. (Note that there are "classic jiffies" (my term) represented as long and 64 bit jiffies represented as u64, with separate functions like time_before versus time_before64).

But are there some general macros for doing math with overflow checks? Casually combing through a kernel tree (3.18.31 that I have at my convenience), it doesn't appear that way. grep -i overflow on the include subtree doesn't come up with anything and similar searches in code areas like fs reveal the use of ad hoc locally coded overflow checks. It's a shame, really; you'd think the problem of "if I add these two int values together, is there a problem" is common enough that there would be a solution in place that everyone can just use like some addv(x_int, y_int, &overflow_flag) or whatever.

Kaz
  • 55,781
  • 9
  • 100
  • 149
1

integer overflow in kernel — possible?

Yes. It doesn't matter, user space or kernel -- it's just how CPU works.

I'm wondering if I need to guard against possible integer overflows in the kernel

If you think that it can happen and it's not acceptable in your case -- then yes. For signed integers it can even lead to undefined behavior.

does the kernel provide macros or APIs for this

No, there are no ready-to-use functions in kernel for dealing with integer overflows. Well, there are some GCC wrappers for overflow detection... But be sure not to use it. Otherwise Linus Torvalds will come and yell at you, like here :)

Anyway, it's quite easy to detect integer overflows manually, when you really need that. Look here for example. In your case, size_t is unsigned, so you only need to ensure that it doesn't wrap or handle wrapped value: details.

Community
  • 1
  • 1
Sam Protsenko
  • 14,045
  • 4
  • 59
  • 75