subids: Some cleanups#1586
Conversation
3b3b1ee to
5f628dd
Compare
|
I'm showing: which are probably issues? |
Yeah, I need to fix some issues I've seen in CI. I'll reply when they seem fixed. Thanks! This warning probably explains some of the CI errors. I'll check if we can enable |
e5da6df to
cffaa56
Compare
This comment was marked as resolved.
This comment was marked as resolved.
e5da6df to
9c4a856
Compare
|
@jcpunk Please pick the first 6 commits for your PR. Those are passing CI, and locally I verified they don't have any bad warnings (there are some warnings, but they are false positives). The last two commits are problematic, so don't pick them. |
|
I'll get to those in the morning. Is there a reason to remove the sign compare warning? I feel like that would help identify oddities... |
Ok.
Yes, see this GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119011. It's a nice diagnostic, if it didn't diagnose literal -1. Until GCC fixes that, we can't use it. |
...
I'm not sure what you mean by you've addressed the overflow issue. Your patches whereas when min and max are unsigned long, the test returns false. |
[...]
That was an unrelated issue.
I see it being true with both id_t and u_long: alx@devuan:~/tmp$ cat u.c
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef FOO
typedef id_t foo_t;
#else
typedef unsigned long foo_t;
#endif
int
main(void)
{
foo_t min = 0;
foo_t max = (foo_t) ULONG_MAX;
printf("min: %ju\n", (uintmax_t) min);
printf("max: %ju\n", (uintmax_t) min);
printf("max - min: %ju\n", (uintmax_t) (max - min));
printf("max - min + 1: %ju\n", (uintmax_t) (max - min + 1));
if (500 > max - min + 1) printf("yup\n");
}alx@devuan:~/tmp$ gcc -Wall -Wextra u.c
alx@devuan:~/tmp$ ./a.out
min: 0
max: 0
max - min: 18446744073709551615
max - min + 1: 0
yup
alx@devuan:~/tmp$ gcc -Wall -Wextra u.c -DFOO
alx@devuan:~/tmp$ ./a.out
min: 0
max: 0
max - min: 4294967295
max - min + 1: 0
yupBut your program allowed me to find the issue: I should move the +1 to the other side of the comparison. count - 1 > max - min
Thanks! |
126be68 to
b6a0a06
Compare
b6a0a06 to
2b405be
Compare
|
I think I've got that done |
Haaahaha :) that commit makes me laugh :) That's the kind of thing automation certainly ought to be able to warn us about/remind us of. Thanks. |
Agree. Although it won't be easy. It would trigger too many false positives. That's the reason why unsigned types are much more dangerous than signed ones, and the bad fame that signed integer overflow has in C is unmerited. At least, compilers have become quite good at diagnostic signed integer overflow. Unsigned integer wrap-around, while well-defined, is way more dangerous, precisely because by being well-defined, the compiler must assume that you did that on purpose (i.e., you wanted the wrap-around behavior). There's some work at the moment, with attributes, to differentiate between unsigned integers where you want the wrap-around, vs the ones where you want a diagnostic. @kees talked about this last summer in LSS in Denver. @uecker may also know about it.
You're welcome! I'll update the commit to document the issue better. |
The input to these functions is always an address (&x); that's guaranteed to be non-null. Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
GCC has issues with literal -1. Link: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119011> Signed-off-by: Alejandro Colomar <alx@kernel.org>
This helped find a bug, and doesn't seem to have any false positives here, so let's use it. Signed-off-by: Alejandro Colomar <alx@kernel.org>
It's the natural type for this API, and it's also more consistent with its wrappers. Let's also use literal -1 for the error code, which is safer than unsigned constants, as -1 is sign-extended to fit whatever unsigned type we're using. Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2b405be to
775435e
Compare
The test is
if (count == 0 || max < min || count - 1 > max - min) {
We tested here a couple of obvious things
- the count is nonzero.
- min >= max
But we should also make sure that the count fits within the range
[min, max]. For that, we must be very careful, to avoid unsigned
integer wrap-around. max-min can't wrap, since we already tested that
max>=min. And count-1 can't wrap, since count!=0.
A previous version of this patch wrote it as
... || count > max - min + 1)
which is bogus. When max==UINT_MAX, and min=0, then max-min==UINT_MAX,
and when doing +1, we wrap again to 0. Unsigned integer types are very
dangerous, and should be handled very carefully.
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
find_free_range() already checks this, and does it better. Signed-off-by: Alejandro Colomar <alx@kernel.org>
775435e to
7a26be1
Compare
We're lucky that we had tests. :)
|
Cc: @jcpunk
I'm preparing some cleanups for you to pick in your PR.
Revisions:
v2
v2b
v2c
v2d
v2e