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]
Message-ID: <d2399574-ec64-7765-b6ef-1e792a7e0d5c@rasmusvillemoes.dk>
Date:   Tue, 30 Aug 2022 11:41:31 +0200
From:   Rasmus Villemoes <linux@...musvillemoes.dk>
To:     Bart Van Assche <bvanassche@....org>,
        Kees Cook <keescook@...omium.org>
Cc:     linux-kernel@...r.kernel.org,
        Andrew Morton <akpm@...ux-foundation.org>,
        Arnd Bergmann <arnd@...db.de>,
        Dan Williams <dan.j.williams@...el.com>,
        Eric Dumazet <edumazet@...gle.com>,
        Ingo Molnar <mingo@...hat.com>,
        Isabella Basso <isabbasso@...eup.net>,
        "Jason A. Donenfeld" <Jason@...c4.com>,
        Josh Poimboeuf <jpoimboe@...nel.org>,
        Luc Van Oostenryck <luc.vanoostenryck@...il.com>,
        Masami Hiramatsu <mhiramat@...nel.org>,
        Nathan Chancellor <nathan@...nel.org>,
        Peter Zijlstra <peterz@...radead.org>,
        Sander Vanheule <sander@...nheule.net>,
        Steven Rostedt <rostedt@...dmis.org>,
        Vlastimil Babka <vbabka@...e.cz>,
        Yury Norov <yury.norov@...il.com>
Subject: Re: [PATCH 1/2] testing/selftests: Add tests for the is_signed_type()
 macro

On 26/08/2022 18.21, Bart Van Assche wrote:
> Although not documented, is_signed_type() must support the 'bool' and
> pointer types next to scalar and enumeration types. Add a selftest that
> verifies that this macro handles all supported types correctly.
> 

> +static void is_signed_type_test(struct kunit *test)
> +{
> +	KUNIT_EXPECT_EQ(test, is_signed_type(bool), false);
> +	KUNIT_EXPECT_EQ(test, is_signed_type(signed char), true);
> +	KUNIT_EXPECT_EQ(test, is_signed_type(unsigned char), false);

Nice. You could consider adding

#ifdef __UNSIGNED_CHAR__
KUNIT_EXPECT_EQ(test, is_signed_type(char), false);
#else
KUNIT_EXPECT_EQ(test, is_signed_type(char), true);
#endif

The kernel depends on the compiler providing __UNSIGNED_CHAR__ in two
places (one in ext4, one in printf test suite).

> +	KUNIT_EXPECT_EQ(test, is_signed_type(int), true);
> +	KUNIT_EXPECT_EQ(test, is_signed_type(unsigned int), false);
> +	KUNIT_EXPECT_EQ(test, is_signed_type(long), true);
> +	KUNIT_EXPECT_EQ(test, is_signed_type(unsigned long), false);
> +	KUNIT_EXPECT_EQ(test, is_signed_type(long long), true);
> +	KUNIT_EXPECT_EQ(test, is_signed_type(unsigned long long), false);
> +	KUNIT_EXPECT_EQ(test, is_signed_type(enum unsigned_enum), false);
> +	KUNIT_EXPECT_EQ(test, is_signed_type(enum signed_enum), true);

Yeah. But enum types are one of the weirdest aspects of C. Taking your
example and expanding with a positive value that doesn't fit an int:

#include <stdio.h>

#define is_signed_type(t) ((t)-1 < (t)1)

#define typeinfo(t) printf("%-24s signed %d, size %zu\n", #t,
is_signed_type(t), sizeof(t))

enum unsigned_enum {
	constant_a = 3,
	constant_d = 3000000000,
};

enum signed_enum {
	constant_b = -1,
	constant_c = 2,
};

int main(int argc, char *argv[])
{
	enum unsigned_enum a = constant_a;
	enum unsigned_enum d = constant_d;
	enum signed_enum b = constant_b;
	enum signed_enum c = constant_c;

	typeinfo(enum unsigned_enum);
	typeinfo(enum signed_enum);
	typeinfo(typeof(constant_a));
	typeinfo(typeof(constant_b));
	typeinfo(typeof(constant_c));
	typeinfo(typeof(constant_d));

	typeinfo(typeof(a));
	typeinfo(typeof(b));
	typeinfo(typeof(c));
	typeinfo(typeof(d));

	return 0;
}

This gives me

enum unsigned_enum       signed 0, size 4
enum signed_enum         signed 1, size 4
typeof(constant_a)       signed 1, size 4
typeof(constant_b)       signed 1, size 4
typeof(constant_c)       signed 1, size 4
typeof(constant_d)       signed 0, size 4
typeof(a)                signed 0, size 4
typeof(b)                signed 1, size 4
typeof(c)                signed 1, size 4
typeof(d)                signed 0, size 4

That is, typeof(constant_a) is not the same type (different signedness)
as enum unsigned_enum! While both constant_d (due to its size) and
variables declared as 'enum unsigned_enum' do indeed have that
underlying unsigned type.

At least gcc and clang agree on this weirdness, but I haven't been able
to find a spec mandating this. Anyway, this was just an aside.

Acked-by: Rasmus Villemoes <linux@...musvillemoes.dk>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ