sysctl: fix int -> unsigned long assignments in INT_MIN case
The following if (val < 0) *lvalp = (unsigned long)-val; is incorrect because the compiler is free to assume -val to be positive and use a sign-extend instruction for extending the bit pattern. This is a problem if val == INT_MIN: # echo -2147483648 >/proc/sys/dev/scsi/logging_level # cat /proc/sys/dev/scsi/logging_level -18446744071562067968 Cast to unsigned long before negation - that way we first sign-extend and then negate an unsigned, which is well defined. With this: # cat /proc/sys/dev/scsi/logging_level -2147483648 Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Cc: Mikulas Patocka <mikulas@twibright.com> Cc: Robert Xiao <nneonneo@gmail.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Kees Cook <keescook@chromium.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
1303a27c9c
commit
9a5bc726d5
@ -1995,7 +1995,7 @@ static int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp,
|
||||
int val = *valp;
|
||||
if (val < 0) {
|
||||
*negp = true;
|
||||
*lvalp = (unsigned long)-val;
|
||||
*lvalp = -(unsigned long)val;
|
||||
} else {
|
||||
*negp = false;
|
||||
*lvalp = (unsigned long)val;
|
||||
@ -2201,7 +2201,7 @@ static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *lvalp,
|
||||
int val = *valp;
|
||||
if (val < 0) {
|
||||
*negp = true;
|
||||
*lvalp = (unsigned long)-val;
|
||||
*lvalp = -(unsigned long)val;
|
||||
} else {
|
||||
*negp = false;
|
||||
*lvalp = (unsigned long)val;
|
||||
@ -2436,7 +2436,7 @@ static int do_proc_dointvec_jiffies_conv(bool *negp, unsigned long *lvalp,
|
||||
unsigned long lval;
|
||||
if (val < 0) {
|
||||
*negp = true;
|
||||
lval = (unsigned long)-val;
|
||||
lval = -(unsigned long)val;
|
||||
} else {
|
||||
*negp = false;
|
||||
lval = (unsigned long)val;
|
||||
@ -2459,7 +2459,7 @@ static int do_proc_dointvec_userhz_jiffies_conv(bool *negp, unsigned long *lvalp
|
||||
unsigned long lval;
|
||||
if (val < 0) {
|
||||
*negp = true;
|
||||
lval = (unsigned long)-val;
|
||||
lval = -(unsigned long)val;
|
||||
} else {
|
||||
*negp = false;
|
||||
lval = (unsigned long)val;
|
||||
@ -2484,7 +2484,7 @@ static int do_proc_dointvec_ms_jiffies_conv(bool *negp, unsigned long *lvalp,
|
||||
unsigned long lval;
|
||||
if (val < 0) {
|
||||
*negp = true;
|
||||
lval = (unsigned long)-val;
|
||||
lval = -(unsigned long)val;
|
||||
} else {
|
||||
*negp = false;
|
||||
lval = (unsigned long)val;
|
||||
|
Loading…
Reference in New Issue
Block a user