On 05/11/2020 12:32, Wilken Gottwalt wrote: > On Thu, 5 Nov 2020 11:50:19 +0000 > Colin King <colin.king@xxxxxxxxxxxxx> wrote: > >> From: Colin Ian King <colin.king@xxxxxxxxxxxxx> >> >> The shifting of the u8 integer data[3] by 24 bits to the left will >> be promoted to a 32 bit signed int and then sign-extended to a >> long. In the event that the top bit of data[3] is set then all >> then all the upper 32 bits of a 64 bit long end up as also being >> set because of the sign-extension. Fix this by casting data[3] to >> a long before the shift. >> >> Addresses-Coverity: ("Unintended sign extension") >> Fixes: ce15cd2cee8b ("hwmon: add Corsair PSU HID controller driver") >> Signed-off-by: Colin Ian King <colin.king@xxxxxxxxxxxxx> >> --- >> drivers/hwmon/corsair-psu.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/hwmon/corsair-psu.c b/drivers/hwmon/corsair-psu.c >> index e92d0376e7ac..5d19a888231a 100644 >> --- a/drivers/hwmon/corsair-psu.c >> +++ b/drivers/hwmon/corsair-psu.c >> @@ -241,7 +241,7 @@ static int corsairpsu_get_value(struct corsairpsu_data *priv, u8 cmd, u8 >> rail, l >> * the LINEAR11 conversion are the watts values which are about 1200 for the strongest >> psu >> * supported (HX1200i) >> */ >> - tmp = (data[3] << 24) + (data[2] << 16) + (data[1] << 8) + data[0]; >> + tmp = ((long)data[3] << 24) + (data[2] << 16) + (data[1] << 8) + data[0]; >> switch (cmd) { >> case PSU_CMD_IN_VOLTS: >> case PSU_CMD_IN_AMPS: > > Yeah, this could happen if the uptime value in the micro-controller gets bigger > than 68 years (in seconds), and it is the only value which actually uses more > than 2 bytes for the representation. So what about architectures which are 32 bit > wide and where a long has 32 bits? I guess this simple cast is not enough. For 32 bits (unsigned) the 4 u8 values in data represents ~136 years no matter if we use a 32 or 64 bit long for tmp. The cast to long is signed, so yes, that's ~68 years in seconds. So perhaps corsairpsu_get_value() should be passing a unsigned long for the *val arg and tmp should be unsigned long too? > > greetings, > Wilken >