[Bug 217401] Deadlock in if_clone.c

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Mon Feb 27 16:51:27 UTC 2017


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=217401

            Bug ID: 217401
           Summary: Deadlock in if_clone.c
           Product: Base System
           Version: 10.3-STABLE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Many People
          Priority: ---
         Component: kern
          Assignee: freebsd-bugs at FreeBSD.org
          Reporter: FreeBSD-prs at Vitsch.nl

The code in if_clone.c uses the unit number allocator subsystem to keep track
of free unit numbers when allocating interfaces. This can get out of sync with
reality since interfaces can be renamed after creation. When this happens, the
retry loop in if_alloc_unit() can deadlock a system.

The following set of commands will deadlock FreeBSD:
  ifconfig bridge create
  ifconfig bridge create
  ifconfig bridge1 name bridge3
  ifconfig bridge create
  ifconfig bridge create
  ifconfig bridge create
  # (deadlock at this point)

The deadlock happens when alloc_unr_specific() returns an unused unit number,
but the later call to ifunit(name) sees that the unit is already in use.
In this case, the code will increase '*unit' and loop back to 'retry:'. If this
increased '*unit' number is already allocated, the return value of the next
call to alloc_unr_specific() will override '*unit' and leave it at -1.
The code will then increase '*unit' again and loop back to 'retry:' again with
'*unit' now set to 0. If unit number 0 also already exists, we'll be caught in
an infinite loop.

The attached patch fixes the deadlock by simply not destroying the value of
'*unit' before incrementing it in the 'retry' path.
(This is a slight variant of kern/162789. The same use case that triggered that
bug now also triggers this deadlock.)

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-bugs mailing list