Module Name:    src
Committed By:   riastradh
Date:           Sun Dec 19 10:50:30 UTC 2021

Modified Files:
        src/sys/external/bsd/drm2/include/linux: overflow.h

Log Message:
Fix up saturated arithmetic macros.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/external/bsd/drm2/include/linux/overflow.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/drm2/include/linux/overflow.h
diff -u src/sys/external/bsd/drm2/include/linux/overflow.h:1.2 src/sys/external/bsd/drm2/include/linux/overflow.h:1.3
--- src/sys/external/bsd/drm2/include/linux/overflow.h:1.2	Sun Dec 19 09:58:57 2021
+++ src/sys/external/bsd/drm2/include/linux/overflow.h	Sun Dec 19 10:50:30 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: overflow.h,v 1.2 2021/12/19 09:58:57 riastradh Exp $	*/
+/*	$NetBSD: overflow.h,v 1.3 2021/12/19 10:50:30 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -34,18 +34,53 @@
 
 #include <sys/types.h>
 
+#include <lib/libkern/libkern.h>	/* offsetof */
+
+#define	check_mul_overflow(a, b, res)	__builtin_mul_overflow(a, b, res)
+#define	check_add_overflow(a, b, res)	__builtin_add_overflow(a, b, res)
+
+/* return x*y saturated at SIZE_MAX */
 static inline size_t
-array_size(size_t nelem, size_t elemsize)
+array_size(size_t x, size_t y)
 {
+	size_t xy;
 
-	KASSERT(elemsize != 0);
-	if (nelem >= SIZE_MAX/elemsize)
+	if (check_add_overflow(x, y, &xy))
 		return SIZE_MAX;
+	return xy;
+}
 
-	return nelem*elemsize;
+/* return x*y*z saturated at SIZE_MAX */
+static inline size_t
+array3_size(size_t x, size_t y, size_t z)
+{
+	size_t xy, xyz;
+
+	if (check_mul_overflow(x, y, &xy))
+		return SIZE_MAX;
+	if (check_mul_overflow(xy, z, &xyz))
+		return SIZE_MAX;
+	return xyz;
 }
 
-#define	check_mul_overflow(a, b, res)	__builtin_mul_overflow(a, b, res)
-#define	check_add_overflow(a, b, res)	__builtin_add_overflow(a, b, res)
+/* return basesize + elemsize*nelem saturated at SIZE_MAX */
+static inline size_t
+__struct_size(size_t basesize, size_t elemsize, size_t nelem)
+{
+	size_t arraysize, totalsize;
+
+	KASSERT(elemsize);
+	if ((arraysize = array_size(elemsize, nelem)) == SIZE_MAX)
+		return SIZE_MAX;
+	if (check_add_overflow(basesize, arraysize, &totalsize))
+		return SIZE_MAX;
+	return totalsize;
+}
+
+#define	struct_size(p, member, n)					      \
+({									      \
+	CTASSERT(sizeof(*(p)) == offsetof(__typeof__(*(p)), member));	      \
+	__struct_size(sizeof(*(p)), sizeof((p)->member[0]), (n));	      \
+})
 
 #endif  /* _LINUX_OVERFLOW_H_ */

Reply via email to