内核中的整数溢出——可能吗?
integer overflow in kernel -- possible?
我必须在内核中进行整数运算,特别是我需要将 size_t
对象递增一些增量,这种情况经常发生。所以我想知道我是否需要防止内核中可能出现的整数溢出,如果需要,内核是否为此提供了宏或 API?
integer overflow in kernel — possible?
是的。没关系,用户 space 或内核——这就是 CPU 的工作方式。
I'm wondering if I need to guard against possible integer overflows in the kernel
如果您认为它可能发生 并且 它在您的情况下是不可接受的 - 那么是的。对于有符号整数,它甚至可以导致 undefined behavior.
does the kernel provide macros or APIs for this
不,内核中没有现成的函数来处理整数溢出。嗯,还有一些GCC wrappers for overflow detection... But be sure not to use it. Otherwise Linus Torvalds will come and yell at you, like here :)
无论如何,当您确实需要时,手动检测整数溢出非常容易。看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.
size_t
不溢出;它是一种无符号类型,具有明确定义的 "wraparound" 语义。增加 size_t
的最高值会导致
零。
在size_t
的特定情况下,在对size_t
的简单操作中,比如将两个大小加在一起,通常只检查结果操作数是否大于两个中的一个就足够了源操作数。如果(size3 = size1 + size2) < size1)
,你有一个包装。
如果使用无符号类型作为围绕 "wheel" 的时钟值,则存在用于正确执行 "time before" 计算的宏。例如,我们希望时间 0xFFFFFFFE
被视为过去的几个时间单位 w.r.t。时间0x00000003
。如果您在内核中使用 "jiffies" 时间,那么您可以使用 time_before
内联函数,以及该系列中的其他函数。 (请注意,有 "classic jiffies"(我的术语)表示为 long
和 64 位 jiffies 表示为 u64
,具有单独的功能,例如 time_before
与 time_before64
)。
但是是否有一些通用的宏可以通过溢出检查来进行数学计算?随意梳理内核树(我方便时使用的 3.18.31),它看起来不是那样的。 include
子树上的 grep -i overflow
没有得出任何结果,在 fs
等代码区域中的类似搜索揭示了 ad hoc 本地编码的使用溢出检查。真的很遗憾;你会认为 "if I add these two int
values together, is there a problem" 的问题很常见,以至于会有一个解决方案,每个人都可以使用 addv(x_int, y_int, &overflow_flag)
或其他任何东西。
我必须在内核中进行整数运算,特别是我需要将 size_t
对象递增一些增量,这种情况经常发生。所以我想知道我是否需要防止内核中可能出现的整数溢出,如果需要,内核是否为此提供了宏或 API?
integer overflow in kernel — possible?
是的。没关系,用户 space 或内核——这就是 CPU 的工作方式。
I'm wondering if I need to guard against possible integer overflows in the kernel
如果您认为它可能发生 并且 它在您的情况下是不可接受的 - 那么是的。对于有符号整数,它甚至可以导致 undefined behavior.
does the kernel provide macros or APIs for this
不,内核中没有现成的函数来处理整数溢出。嗯,还有一些GCC wrappers for overflow detection... But be sure not to use it. Otherwise Linus Torvalds will come and yell at you, like here :)
无论如何,当您确实需要时,手动检测整数溢出非常容易。看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.
size_t
不溢出;它是一种无符号类型,具有明确定义的 "wraparound" 语义。增加 size_t
的最高值会导致
零。
在size_t
的特定情况下,在对size_t
的简单操作中,比如将两个大小加在一起,通常只检查结果操作数是否大于两个中的一个就足够了源操作数。如果(size3 = size1 + size2) < size1)
,你有一个包装。
如果使用无符号类型作为围绕 "wheel" 的时钟值,则存在用于正确执行 "time before" 计算的宏。例如,我们希望时间 0xFFFFFFFE
被视为过去的几个时间单位 w.r.t。时间0x00000003
。如果您在内核中使用 "jiffies" 时间,那么您可以使用 time_before
内联函数,以及该系列中的其他函数。 (请注意,有 "classic jiffies"(我的术语)表示为 long
和 64 位 jiffies 表示为 u64
,具有单独的功能,例如 time_before
与 time_before64
)。
但是是否有一些通用的宏可以通过溢出检查来进行数学计算?随意梳理内核树(我方便时使用的 3.18.31),它看起来不是那样的。 include
子树上的 grep -i overflow
没有得出任何结果,在 fs
等代码区域中的类似搜索揭示了 ad hoc 本地编码的使用溢出检查。真的很遗憾;你会认为 "if I add these two int
values together, is there a problem" 的问题很常见,以至于会有一个解决方案,每个人都可以使用 addv(x_int, y_int, &overflow_flag)
或其他任何东西。