Bug 9580

Summary: Dereferencing NULL pointer on kernel/irq/manage.c
Product: IO/Storage Reporter: Marcio Buss (marciobuss)
Component: OtherAssignee: io_other
Status: CLOSED CODE_FIX    
Severity: normal CC: mingo, protasnb, tglx
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 2.6.23 Subsystem:
Regression: --- Bisected commit-id:

Description Marcio Buss 2007-12-15 16:56:21 UTC
There's a potential null pointer dereference on kernel/irq/manage.c.
The error can be tracked down as follows:

(1) assume the "if" statement at line 334 is true
(2) let the first conjunct "desc->chip" on the "if" statement at line
    335 be false, which means "desc->chip" points-to null and
    also signifies that the "if" statement evaluates to false.
(3) the else statement starting at line 338 executes, which
    means "printk" prints "unknown" as its last word
(4) let the "if" statement on line 353 be true
(5) now "desc->chip" is dereferenced at line 356 although it is null.
Comment 1 Natalie Protasevich 2008-05-04 23:39:21 UTC
You mean the code below (the line numbers have changed). Statement (1) applies that chip cannot be NULL. Then "if (desc->chip" seems extraneous in (2) and (3). I wonder if it's just being over-careful, the check shouldn't be needed here.

        if (!shared) {
(1)             irq_chip_set_defaults(desc->chip);

#if defined(CONFIG_IRQ_PER_CPU)
                if (new->flags & IRQF_PERCPU)
                        desc->status |= IRQ_PER_CPU;
#endif

                /* Setup the type (level, edge polarity) if configured: */
                if (new->flags & IRQF_TRIGGER_MASK) {
 (2)                    if (desc->chip && desc->chip->set_type)
                                desc->chip->set_type(irq,
                                                new->flags & IRQF_TRIGGER_MASK);
                        else
                                /*
                                 * IRQF_TRIGGER_* but the PIC does not support
                                 * multiple flow-types?
                                 */
                                printk(KERN_WARNING "No IRQF_TRIGGER set_type "
                                       "function for IRQ %d (%s)\n", irq,
  (3)                                   desc->chip ? desc->chip->name :
                                       "unknown");
                } else
                        compat_irq_chip_set_default_handler(desc);
 
                desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING |
                                  IRQ_INPROGRESS | IRQ_SPURIOUS_DISABLED);

                if (!(desc->status & IRQ_NOAUTOEN)) {
                        desc->depth = 0;
                        desc->status &= ~IRQ_DISABLED;
                        if (desc->chip->startup)
                                desc->chip->startup(irq);
                        else
Comment 2 Thomas Gleixner 2008-05-05 00:25:35 UTC
Yes, it's overcautious. We initialize all members of the irq_desc array with &no_irq_chip. Thanks for the pointer, will clean it up.
Comment 3 Thomas Gleixner 2008-09-04 10:33:01 UTC
Fixed by commit: 48627d8d23c34106c1365563604739a50343edaf