diff options
Diffstat (limited to 'include/linux/overflow.h')
-rw-r--r-- | include/linux/overflow.h | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/include/linux/overflow.h b/include/linux/overflow.h index c8890ec358a7..8712ff70995f 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h | |||
@@ -202,4 +202,77 @@ | |||
202 | 202 | ||
203 | #endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */ | 203 | #endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */ |
204 | 204 | ||
205 | /** | ||
206 | * array_size() - Calculate size of 2-dimensional array. | ||
207 | * | ||
208 | * @a: dimension one | ||
209 | * @b: dimension two | ||
210 | * | ||
211 | * Calculates size of 2-dimensional array: @a * @b. | ||
212 | * | ||
213 | * Returns: number of bytes needed to represent the array or SIZE_MAX on | ||
214 | * overflow. | ||
215 | */ | ||
216 | static inline __must_check size_t array_size(size_t a, size_t b) | ||
217 | { | ||
218 | size_t bytes; | ||
219 | |||
220 | if (check_mul_overflow(a, b, &bytes)) | ||
221 | return SIZE_MAX; | ||
222 | |||
223 | return bytes; | ||
224 | } | ||
225 | |||
226 | /** | ||
227 | * array3_size() - Calculate size of 3-dimensional array. | ||
228 | * | ||
229 | * @a: dimension one | ||
230 | * @b: dimension two | ||
231 | * @c: dimension three | ||
232 | * | ||
233 | * Calculates size of 3-dimensional array: @a * @b * @c. | ||
234 | * | ||
235 | * Returns: number of bytes needed to represent the array or SIZE_MAX on | ||
236 | * overflow. | ||
237 | */ | ||
238 | static inline __must_check size_t array3_size(size_t a, size_t b, size_t c) | ||
239 | { | ||
240 | size_t bytes; | ||
241 | |||
242 | if (check_mul_overflow(a, b, &bytes)) | ||
243 | return SIZE_MAX; | ||
244 | if (check_mul_overflow(bytes, c, &bytes)) | ||
245 | return SIZE_MAX; | ||
246 | |||
247 | return bytes; | ||
248 | } | ||
249 | |||
250 | static inline __must_check size_t __ab_c_size(size_t n, size_t size, size_t c) | ||
251 | { | ||
252 | size_t bytes; | ||
253 | |||
254 | if (check_mul_overflow(n, size, &bytes)) | ||
255 | return SIZE_MAX; | ||
256 | if (check_add_overflow(bytes, c, &bytes)) | ||
257 | return SIZE_MAX; | ||
258 | |||
259 | return bytes; | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * struct_size() - Calculate size of structure with trailing array. | ||
264 | * @p: Pointer to the structure. | ||
265 | * @member: Name of the array member. | ||
266 | * @n: Number of elements in the array. | ||
267 | * | ||
268 | * Calculates size of memory needed for structure @p followed by an | ||
269 | * array of @n @member elements. | ||
270 | * | ||
271 | * Return: number of bytes needed or SIZE_MAX on overflow. | ||
272 | */ | ||
273 | #define struct_size(p, member, n) \ | ||
274 | __ab_c_size(n, \ | ||
275 | sizeof(*(p)->member) + __must_be_array((p)->member),\ | ||
276 | sizeof(*(p))) | ||
277 | |||
205 | #endif /* __LINUX_OVERFLOW_H */ | 278 | #endif /* __LINUX_OVERFLOW_H */ |