At this point it is highly unlikely this 1999 device still has users,
but it still comes up in the context of maxv's USB-fuzzing (and any device
could pretend to be a urio(4)), so it's best to get rid of it.
Renamed all major entries to obsolete, as was done in previous removals.
This still requires an update to sanitizers, but they're located in
"external", perhaps it should be first committed upstream?
Proposed on tech-kern a month ago.
Sometimes they get desynchronized, but we know the last packet is a
17-byte packet, so if we get one early then stop here.
Tested by macallan on an iBook and a PowerBook. This code path
shouldn't break anything on MacBooks because they have different
total numbers of sensors so this branch won't be reached.
This is a driver for a "nonsense machine" made by the art group Maywa-Denki
in 2008. It was disabled by default.
Unfortunately even so it draws development attention (flaws found in the
code, MP-ification needs) and it is best not to continue to maintain this
driver.
Proposed without objections on tech-kern.
crafting the former the device can leak stack data. By crafting the latter
the device can overwrite the stack. The combination of the two means the
device can ROP the kernel and obtain code execution (demonstrated with an
actual exploit over vHCI).
Truncate the lengths to the size of the buffers, and also drop sc_ilen
since it is unused. Patch tested with vHCI+kASan.
iic_acquire_bus() / iic_release_bus(). "acquire" and "release" hooks
no longer need to be provided by back-end controller drivers (only if
they need special handling, e.g. powering on the i2c controller).
This results in the removal of a bunch of rendundant code from each
back-end controller driver.
Assert that we are not in hard interrupt context in iic_acquire_bus(),
iic_exec(), and iic_release_bus().
return NULL, so check for this.
I got NULL pointer dereference here with a device showing:
[ 303.732632] ugen0: autoconfiguration error: setting configuration index 0 failed
Can't null it until after if_detach prevents further use.
While here, fix conditionals in usbnet_tick_task to use the unp_dying
flag, not the nullness of mii (or of ifp, which never null because
it's an embedded member).
not all control messages that can be received result in buf being
initialized, we might get a spurious different control message
seen in practice when swapping modes a few times on a urndis device
urndis0: SAMSUNG ...
autoconfiguration error: urndis0: invalid address
panic: kernel diagnostic assertion "p != NULL" failed: file "/cvs/src/sys/kern/subr_kmem.c", line 263
cpu0: Begin traceback...
vpanic() at netbsd:vpanic+0x178
kern_assert() at netbsd:kern_assert+0x48
kmem_intr_free() at netbsd:kmem_intr_free+0xca
urndis_attach() at netbsd:urndis_attach+0x4c2
and all the structures that include it.
this should not change anything while avoiding packed vs alignment
warnings from GCC 8, and potentially pessimised code generation
due to the packed marker (there are no misaligned members, just
that the per-device parts may end unaligned.)
all consumers of these members are done from the properly aligned
packet members directly, or, as a union with a 64 byte member,
also properly aligned. codegen didn't appear to change, except
for the definition of sizeof(struct driver_[rt]x_radiotap_header)
in debug info, which is not directly used anywhere.
- Don't process packets if the USB device is detached. Contrary to the
other HCIs, vHCI has no timeout, so we never collect the pending
packets, and must drop them synchronously.
- Fix refcounting bug in vhci_device_ctrl_abort.
- Implement vhci_activate.
- Add a few KASSERTs.
fails we call usbd_remove_device(), which tries to free ud_pipe0, but it
was already freed.
While here, add two sanity checks, to prevent possible surprises.
device. Also, fail safely if we didn't recognize the RF chip, to prevent
kernel crashes at attach time. Note that other panics are there, maybe
they also should be removed.
Found with vHCI.
- Insert at the tail and not the head. I just noticed that the packets
were in inverted order in the fifos when attaching a virtual urtw0.
- Remove VHCI_DEBUG, which I mistakenly left enabled in rev1.
from userland via /dev/vhci. Using this, it becomes possible to test and
fuzz the USB stack and all the USB drivers without having the associated
hardware.
The vHCI device has four ports independently addressable.
For each xfer on each port, we create two packets: a setup packet (which
indicates mostly the type of request) and a data packet (which contains
the raw data). These packets are processed by read and write operations
on /dev/vhci: userland poll-reads it to fetch usb_device_request_t
structures, and dispatches the requests depending on bRequest and
bmRequestType.
A few ioctls are available:
VHCI_IOC_GET_INFO - Get the current status
VHCI_IOC_SET_PORT - Choose a vHCI port
VHCI_IOC_USB_ATTACH - Attach a USB device on the current port
VHCI_IOC_USB_DETACH - Detach the USB device on the current port
vHCI has already allowed me to automatically find several bugs in the USB
stack and its drivers.
- turn off usbnetdebug default
- log for all entry/exit points of usbnet_pipe_intr()
- in usbnet_start_locked() track whether any packet has been
transmitted for setting the timer. avoids spurious
"watchdog timeouts"
- in usbnet_stop() use callout_halt() vs callout_halt, and
also stop the usb task. fixes crash of usbtask after the
phy has detached.
- add a little more defensive checking in the tick task, and
add some high-log-level logs.
- in usbnet_detach() move the call to usbnet_stop_ifp() above
the calls to callout/usbtask stopping.
- set ec_mii and unp_pri to NULL when freeing their data
remove locking in usbnet_tick(). assume that all locking
needs are handled inside usbnet_tick_task(), which runs in
the usbtask thread. ensure that usbnet private is valid
before using it.
also check NULL private pointer in usbnet_isdying().
all the other cases should never happen.
been allocated and that unp_attached is true before trying
to access anything else.
fixes a detach problem noticed by maxv when, eg, the call
to usbd_set_config_no() fails and attach bails early.
request size buffer. reimplement usbd_do_request_flags() in
terms of this. use this for fetching string descriptors.
fixes a very strange problem where an axe(4) attaching (either
has ugen(4) or axe(4)) would ask for 2 bytes, usb_mem.c would
allocate a 2 byte fragment, perform the operation, and sometime
shortly afterwards (usually by the time the next allocation
is made for this fragment), would become corrupted (usually
two bytes were written with 0x0304.)
(initial request of 4 bytes also avoids the problem on this
device. it really seems like a HC problem -- host should not
allow the device to write more than req.wLength! nor should
it allow this write to happen after completion.)
avoid an (almost) always double-log in usbd_transfer().
- add USBNETHIST_CALLARGSN and use it in many places
- add more history logs
- add a log if watchdog abort leaves uncd_tx_cnt non zero
- add a unique (32-bit) number for a each usbnet device and
use it for logging
- explicitly check for full tx ring in usbnet_start_locked()
and return early, which avoids setting the 5 second timer
and triggering a watchdog
- reset uncd_tx_prod and uncd_tx_cnt to zero in stop
USBHIST_CALLARGS() calls. this reduces the number of
kernel history lines consumed by these callers, and
for the +LOGN versions, add useful log info to a
message that just says "called!".
reduces the line spam which means the total info in a
full log is significantly increased.
- MII read/write reg return int instead of usbd_status (requested by skrll)
- usbnet_attach_ifp(9) changes arg, two mii-specific flags are placed by a
pointer to new struct usbnet_mii. if not NULL, then attach an MII to this
interface like previous have_mii parameter. use this to allow ure(4) to
properly pass PHY location to mii_attach().
welcome netbsd 9.99.10.
that do this (axe, axen, mue, smsc, ure.) it made mii scanning
only work for phy 0, and aue needs it for at least one device.
fix smsc to return usbd_status not -1 on failure. XXX smsc was
writing to '*val' even in error cases, it does not now.
remove a double call to IFQ_SET_READY() (noticed by chuq).
avoid unlock+instant relock by using usbnet_lock_mii_un_locked().
add USBNETHIST_CALLARGS() frontend to USBHIST_CALLARGS().
use both in read/write reg, instead of aprint.
use %jx and (uintptr_t) and fix the 32 bit debug build.
- drivers that want to use if_input() will also set _if_input. for
now, avoid attaching a per-cpu queue for them. use if_initialize()
and if_register().
- when stopping pipes, don't give up after the first failure, but
keep the first failure error for return and keep going
- if 0 a KASSERT() in usbnet_init_rx_tx(). there's a path via
if_mcast_op() that can have the ifnet unlocked today..
- in usbnet_watchdog(), abort the pipe instead of faking tx
completion. avoids issues with devices with more than one tx
descriptor, as well as avoiding triggering usb asserts.
with these, upl(4) port to usbnet(9) now works. (would be a version
bump, but upl(4) and the unported umb(4) are the only consumers that
would care.)
- move KUE_RXFILT_PROMISC setting into kue_setiff() from kue_init()
to avoid multiple setting KUE_CMD_SET_PKT_FILTER reg multiple times
- software-only constructs moved from if_kuereg.h into if_kue.c
- kue is the first (umb(4) will need it to, i think) to have its own
autoconf detach routine remain
- un_tx_xfer_flags is 0 here, not USBD_FORCE_SHORT_XFER
- fix a potential data exposure (but probably not without a USB
protocol tap). kue needs the transfers to be 64-byte aligned, and
while i doubt it sends more than the frame provided, were sending
random kernel data (whatever was the 0-63 bytes to alignment) to
the device.
diffstat says:
2 files changed, 189 insertions(+), 739 deletions(-)
add buflen param to usbnet_newbuf(). use this to skip allocating
an mbuf cluster for small packets (ported from kue(4).)
remove usbnet_rx_start_pipes()'s always usbnet_rxeof argument.
in the usbnet_chain if needed. remove it
- usbnet media status change already set link to false, don't repeat
this in every driver
- don't clear link in stop, nothing was re-enabling it for non-MII
- add optional uno_tick_cb(struct usbnet *un) that is called from the
usbnet tick timer
- remove wrong debug sysctl prototype
rx_loop and timer are kernel versions changes, but hopefully this is
the last one for usbnet. working with 3 more drivers now (cue, mue
and url), leaving only aue, kue, upl and umb undone (aue may work
with previously supported devices, mine doesn't work with our driver,
kue and upl have patches for testing and umb is undone.)
bump version.
introduce USBNET_MODULE() that encompasses almost all the module
specific code for usbnet modules. they still need to include
the relevant ioconf.c, but everything else is now just, eg,
USBNET_MODULE(axen)
trip kmem_free() lossage because struct usbnet is at the
start of the softc.
for now, enforce this as part of the ABI.
catch up urndis with tx_prepare checking buffer length,
and also add an assert to usbnet_start_locked() to match.
than can fit in the buffer. done at the driver and not usbnet
layer because the driver knows how much beyond the mbuf data needs
to be sent (headers and trailers.)
axen(4) had a KASSERT() for this condition, but there's no
invariant here we can check so it's best as an error return.
XXX: only tested on these drivers, needs to be copied to udav, smsc
and urndis after testing as well as the not commited conversions.
In r1.3 of src/sys/dev/hid/hidms.c, tpcalib is used for any hidms
device reporting absolute coordinates. So ums devices reporting
absolute coordinates also need to initialize tcpalib - do it for
all ums devices. An uninitialized tcpalib stops a mouse with
absolute coordinates from "moving".
OK: ryoon@
- move a large number of members internal to usbnet.c's new
"struct usbnet_private".
- provide accessors for a few of these
- move struct usbnet_cdata into usbnet.c as well, but move
bufsz, list count, and xfer flags back out into struct usbnet,
and have them set as part of the setup efore usbnet_attach()
- split the intr pipe parts into their own structure
- move all the main usbnet*lock* code into usbnet.c too
usbnet_attach() goes down to 2 args, and the inputs needed are
now the full contents of 'struct usbnet' besides the driver
owned 'un_flags' and usbnet owned 'un_pri'.
welcome netbsd 9.99.6.
except umb(4) as patch available, with urndis probably working
(need to test the latest change before being commited.)
still need testers for: aue, cue, kue, mue, upl and url.
no umb patch yet.
- move rx/tx xfer flags into usbnet_cdata
- move the callbacks into usbnet_ops structure
- move rx/tx xfer flags arguments from usbnet_init_rx_tx()
and move them all into usbnet_attach() arguments
- s/miibus/mii/ in some places for consistency
other clean up:
- create wrapper functions for callbacks, move knowledge about
special handling (OK to be missing, error eating) there.
- use cdata pointer if already available
- provide some more macros (will be real functions later) for
accessing usbnet members, use existing ones more
bump kernel version.
1) In usbd_find_idesc(), make sure the tables we're reading fit in the
allocated buffer, otherwise small overflow (seen on KASAN, with
bLength=1).
2) Modify usbd_find_edesc(), to fix the same issues as 1).
ok mrg@
- avoid an KASSERT() in usbnet_rx_tx_init() when called early
- move the pmf and usb driver event calls out of the mii specific code,
now suspend is able to work on them again.
urndis port to usbnet works with additional ipv6 lossage that
may indicate it doesn't work (not commited yet.)
the list of routines that need to be called for setting up sysctl
variables. This worked great for all code included in the kernel
itself, but didn't deal with modules that want to create their own
sysctl data. So, we ended up with a lot of #ifdef _MODULE blocks
so modules could explicitly call their setup functions when loaded
as non-built-in modules.
So today, we complete the task that was started so many years ago.
When modules are loaded, after we've called xxx_modcmd(INIT...) we
check if the module contains its own __link_set_sysctl_funcs, and
if so we call the functions listed. We add a struct sysctllog member
to the struct module so we can call sysctl_teardown() when the module
gets unloaded. (The sequence of events ensures that the sysctl stuff
doesn't get created until the rest of the module's init code does any
required memory allocation.)
So, no more need to explicitly call the sysctl setup routines when
built as a loadable module.
- usbnet_enqueue() can set mbuf flags and csum_data
- usbnet_input() for non-ethernet based devices (upl, umb)
- allow a complete override for ioctl()
- remove converted list -- we have compiling and/or working patches for
all the devices except for umb(4), will be merged as testing happens
hopefully this is the last ABI change, though it may end up being
extended for additional smsc(4) support.
hello for real netbsd 9.99.3!
new comment:
* if un_intr_buf is not NULL, use usbd_open_pipe_intr() not
* usbd_open_pipe() for USBNET_ENDPT_INTR, with this buffer,
* size, and interval.
the standard handling is in usbnet.c, with a callback to deal with
the interrupt it self. not fully tested, designed for if_aue.c
and a few others not yet converted.
- make usbhist for usbnet.c work, thanks paulg
- usbnet_init_rx_tx() clears out all allocations upon failure now
- add usbnet_ec() to get a pointer to the struct ethercom
- add usbnet_{lock,unlock,owned}*() to lock/unlock the various locks
and *owned*() for asserting
welcome 9.99.3!
- change the read/write register callbacks to have the same phy/reg
order as the MII code.
- add "mii_flags" param to usbnet_attach_ifp(). axe(4) wants it.
also:
- add usbnet debug code, sysctl node support
- remove commented DPRINTF()s accidentally left in place
- add usbnet_softc()
- reorder some attach code to be consistent
- re-add USBD_FORCE_SHORT_XFER for axen rx chain
ride 9.99.2 bump.
small overflow.
2) Make sure the total length of the bos descriptor did not change in
the meantime, otherwise severe memory corruption.
3) Make sure we have a complete hid descriptor header, otherwise
small overflow.
4) Error out if the report descriptor is zero-sized, otherwise panic.
ok skrll@ mrg@
USB ethernet drivers.
usbnet.h introduces a new set of APIs to provide common solutions
for these driver features:
- USB endpoint pipe handling
- rx and tx chain handling
- generic handlers or support for several struct ifnet callbacks
- MII bus locking
- interrupt handling
- partial autoconf handling: much of attach, and detach/activate
can use common versions directly.
currently, only axen(4) and cdce(4) are converted. the reductions
in these drivers are quite significant: if_cdce.c is reduced from
1000 lines to 320 lines, and if_axen is reduced from 1902 lines
to 1021 lines.
add a "usbnet" module and make the if_axen module depend upon it.
itself, error out. Otherwise there is a small overflow (seen on KASAN,
with bLength=255).
2) Make sure we have a config descriptor header, otherwise there are small
overflows (seen on KASAN, with wTotalLength=1).
3) Once we have the complete config descriptor, make sure its size didn't
change in the meantime. Otherwise there could be severe overflows.
4) Make sure we have a bos descriptor header, otherwise overflow, same
as 2).
ok mrg@ skrll@
(which were in turn partly based upon smsc(4) changes):
- mark network interface MPSAFE, and use MPSAFE calls
- convert to local tick task doing watchdog timeout
- add global, tx and rx locks
- add ratelimited tx error message
- split many functions into locked/unlocked version
- use more const
- fix some comments
- remove spl
- don't bother with OACTIVE and do it all internally (axe_tx_cnt)
additional changes here:
- use axe_stop() to abort pipes in detach
fixes a crash potential i only saw when almost finished debugging
these changes..
since i've personally tested. most in the "drivers testing" i think
are working now since it's been a few releases and we've had minor
bug reports in them fixed, this list was rarely updated.
- convert IFF_ALLMULTI to ETHER_F_ALLMULTI, using ETHER_LOCK()
- remove IFF_OACTIVE use, and simply check the ring count in start
- assert/take more locks
- XXX: IFF_RUNNING is not properly protected (all driver problem)
- fix axen_timer setting so it actually runs
- document a locking issue in stop callback:
stop is called with the softc lock held, but the lock order
in all other places is ifnet -> softc -> rx -> tx, so taking
ifnet lock when softc lock is held would be problematic
- in rxeof check for stopping/dying more often. i managed to
trigger a pagefault in cdce_rxeof() when yanking an active
device as it attempted to usbd_setup_xfer() on closed pipes.
- add missing USBD_MPSAFE and cdce_stopping resetting for cdce(4)
between this and other recent clean ups increase performance of
these drivers mostly. some numbers (in mbit/sec):
old: new:
driver in out in+out in out in+out
---- -- --- ------ -- --- ------
cdce 39 32 44 38 33 54
axen 44 34 45 48 37 42
ure 36 34 35 36 38 38
i'm not sure why axen drops a little with in+out. cdce is
helped quite a lot, and ure a little. it is disappointing that
ure does not outperform cdce -- it's the same actual hardware,
and the device-specific (ure) should outperform the generic
cdce driver...
- introduce locking ala smsc(4)/axen(4) style
- convert to mpsafe interfaces
- add tick task to cdce(4) to deal with missing watchdog, and
actually make the watchdog do something
- convert DELAY() to usbd_delay_ms() in cdce(4) and don't increase
the time in a potentially unbounded way
- remove spl calls
tested with network cable and usb adapter pullouts, reboots and
many many GBs of data transferred in either direction under load.
it introduced a problem when there wasn't a reasonaly constant
stream of incoming packets, and i had a 'nttcp' running against
my test machine constantly, avoiding the bug.
i'm fairly postive i tested it, as i tested enabing mpsafe version
on top of this successfully. however, something happened mid-ssh
with a kernel with mpsafe and my session hung, and since then i've
been unable to boot kernels with the previous revision applied.
being used.
adapt locking to the modern world. some what inspired by if_smsc.c:
- add locks for softc, rx and tx
- add safe detach support
- safe detach vs mii lock requires 2 methods to lock the MII lock,
- check axen_dying and new axen_stopping more often
- consolidate checks to reduce the number of error paths that need
to release a resource
- move axen_watchdog() out of if_timer into the tick task to
prepare for MPSAFEification
TODO:
- remove spl usage
- enable mpsafe
special thanks to skrll and mlelstv for clearing up various
confusion and providing examples.
- use const, __func__, more
- axen_mii_lock is a normal mutex not rwlock, and make sure it's
properly cleaned up for failed attach
- check axen_dying in axen_miibus_statchg()
- rename axen_ax88179_eeprom() to axen_get_eaddr() and move the code
here into the support the current method.
- adjust some comments
- Fix athn_usb_free_tx_list(). usc->usc_tx_bcn->xfer is freed in the above
for () loop, so remove the if block. OK'd by skrll.
- Add missing athn_usb_free_tx_msg().
- Add missing athn_usb_stop().