lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 23 Apr 2012 16:22:06 +0300
From:	Alexey Dobriyan <adobriyan@...il.com>
To:	akpm@...ux-foundation.org
Cc:	linux-kernel@...r.kernel.org
Subject: [PATCH v2] Add kabs()

There is abs() and abs64().
They have following unwanted or suprising properties:
1) They return signed value
	in math norms et al are unsigned

2) In finest Unix tradition they do not work reliably.
   Quoting abs(3).
	"Trying to take the absolute value of the most negative integer is not defined."

3) They expand type needlessly

4) There are 2 of them with different names
	with gcc extensions __builtin_choose_expr(),
	__builtin_types_compatible_p() we can mimic type dispatch as found
	in modern programming languages.

Enter kabs().

kabs() has the following nice properties which should have been there
from day 1.

kabs() return unsigned value.
kabs() works for all integer types and return correct result.
sizeof(kabs(x)) == sizeof(x)

Mention kabs() in checkpatch.pl so people would gradually convert.
abs() and abs64() will eventually dissapear.

Signed-off-by: Alexey Dobriyan <adobriyan@...il.com>
---

 This one will actually compile.

 include/linux/kernel.h |   29 +++++++++++++++++++++++++++++
 scripts/checkpatch.pl  |    6 ++++++
 2 files changed, 35 insertions(+)

--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -188,6 +188,35 @@ extern int _cond_resched(void);
 		(__x < 0) ? -__x : __x;		\
 	})
 
+#define kabs(x)								\
+({									\
+	typeof(x) _x = (x);						\
+									\
+	/*								\
+	 * "char", "signed char", "unsigned char" aren't compatible	\
+	 * regardless of -f{un,}signed-char.				\
+	 */								\
+	__builtin_choose_expr(						\
+		__builtin_types_compatible_p(typeof(_x), signed char),	\
+		(unsigned char)({ _x < 0 ? -_x : _x; }),		\
+	__builtin_choose_expr(						\
+		__builtin_types_compatible_p(typeof(_x), char),		\
+		(unsigned char)({ _x < 0 ? -_x : _x; }),		\
+	__builtin_choose_expr(						\
+		__builtin_types_compatible_p(typeof(_x), short),	\
+		(unsigned short)({ _x < 0 ? -_x : _x; }),		\
+	__builtin_choose_expr(						\
+		__builtin_types_compatible_p(typeof(_x), int),		\
+		(unsigned int)({ _x < 0 ? -_x : _x; }),			\
+	__builtin_choose_expr(						\
+		__builtin_types_compatible_p(typeof(_x), long),		\
+		(unsigned long)({ _x < 0 ? -_x : _x; }),		\
+	__builtin_choose_expr(						\
+		__builtin_types_compatible_p(typeof(_x), long long),	\
+		(unsigned long long)({ _x < 0 ? -_x : _x; }),		\
+	_x))))));							\
+})
+
 #ifdef CONFIG_PROVE_LOCKING
 void might_fault(void);
 #else
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -3347,6 +3347,12 @@ sub process {
 			     "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr);
 		}
 
+# check for abs(), abs64()
+		if ($line =~ /\b(abs64|abs)\s*\(/) {
+			WARN("CONSIDER_KABS",
+			     "$1 is obsolete, use kabs\n" . $herecurr);
+		}
+
 # check for use of yield()
 		if ($line =~ /\byield\s*\(\s*\)/) {
 			WARN("YIELD",
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ