From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933205AbdJ3Vgd (ORCPT ); Mon, 30 Oct 2017 17:36:33 -0400 Received: from mail-wr0-f196.google.com ([209.85.128.196]:52779 "EHLO mail-wr0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753256AbdJ3Vgb (ORCPT ); Mon, 30 Oct 2017 17:36:31 -0400 X-Google-Smtp-Source: ABhQp+RRvGj2HlLZD1YxcT/f9DY6txM/lx5HumegDbd2mpRMh3w3H2WbpVrO9XFQWDeFMVLzJPoAPA== From: Rasmus Villemoes To: Thomas Gleixner Cc: Rasmus Villemoes , linux-kernel@vger.kernel.org Subject: [PATCH] genirq: __setup_irq(): fix type of literal 1 in shift Date: Mon, 30 Oct 2017 22:35:47 +0100 Message-Id: <20171030213548.16831-1-linux@rasmusvillemoes.dk> X-Mailer: git-send-email 2.11.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org If we ever get a value >= 31 from ffz(), we'd be invoking UB; in the > 31 case, probably assigning the same thread_mask to to multiple irqactions (at least on x86_64, where the shift count is implicitly truncated to 5 bits). In practice, I think the bug is mostly harmless, since when we first get ffz == 31, the RHS is - ignoring UB - (int)(0x80000000), and sign-extension means that the 32nd irqaction just ends up eating the top 33 bits of thread_mask, so all subsequent __setup_irq calls would just end up hitting the -EBUSY branch. (AFAICT, no code seems to rely on ->thread_mask being a single bit; it's all whole-sale |= and &=). However, a sufficiently aggressive optimizer may use the UB of 1<<31 to decide that doesn't happen, and hence elide the sign-extension code, so that subsequent calls can indeed get ffz > 31. In any case, this is the right thing to do. Signed-off-by: Rasmus Villemoes --- kernel/irq/manage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 4bff6a10ae8e..a1a448e1760d 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -1305,7 +1305,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) * thread_mask assigned. See the loop above which or's * all existing action->thread_mask bits. */ - new->thread_mask = 1 << ffz(thread_mask); + new->thread_mask = 1UL << ffz(thread_mask); } else if (new->handler == irq_default_primary_handler && !(desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)) { -- 2.11.0