From: Stephen Warren <swarren@xxxxxxxxxx> commit daa35bd95634a2a2d72d1049c93576a02711cb1a upstream When the gadget serial device has no associated TTY, do not pass any received data into the TTY layer for processing; simply drop it instead. This prevents the TTY layer from calling back into the gadget serial driver, which will then crash in e.g. gs_write_room() due to lack of gadget serial device to TTY association (i.e. a NULL pointer dereference). Signed-off-by: Stephen Warren <swarren@xxxxxxxxxx> Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx> Signed-off-by: Krzysztof Kozlowski <krzk@xxxxxxxxxx> --- This is necessary for v4.4+ to fix: [ 134.015750] Unable to handle kernel NULL pointer dereference at virtual address 000000a8 [ 134.023988] pgd = 80004000 [ 134.026749] [000000a8] *pgd=00000000 [ 134.030417] Internal error: Oops: 17 [#1] ARM [ 134.034826] Modules linked in: ctr ccm usb_f_acm u_serial ath9k_htc ath9k_common ath9k_hw ath mac80211 cfg80211 libcomposite configfs [ 134.047166] CPU: 0 PID: 51 Comm: kworker/u2:1 Not tainted 4.9.133 #60 [ 134.053664] Hardware name: Freescale Vybrid VF5xx/VF6xx (Device Tree) [ 134.060195] Workqueue: events_unbound flush_to_ldisc [ 134.065244] task: 86a42140 task.stack: 86a9a000 [ 134.069872] PC is at gs_flush_chars+0x18/0x30 [u_serial] [ 134.075261] LR is at n_tty_receive_buf_common+0x648/0xa54 [ 134.080726] pc : [<7f169d4c>] lr : [<803cce74>] psr: 200f0093 [ 134.080726] sp : 86a9be08 ip : 86a9be20 fp : 86a9be1c [ 134.092310] r10: 86bff600 r9 : 862240cc r8 : 00000000 [ 134.097589] r7 : 862240cc r6 : 00000000 r5 : 00000000 r4 : 200f0013 [ 134.104177] r3 : 7f169d34 r2 : 0000000a r1 : 0000003c r0 : 00000000 [ 134.110763] Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment none [ 134.118081] Control: 10c5387d Table: 85fb8059 DAC: 00000051 [ 134.123882] Process kworker/u2:1 (pid: 51, stack limit = 0x86a9a208) [ 134.130293] Stack: (0x86a9be08 to 0x86a9c000) [ 134.134717] be00: 89f0b000 00000000 86a9be8c 86a9be20 803cce74 7f169d40 [ 134.143000] be20: 86bff658 00020001 86bff73c 86a9be38 55555556 89f0b000 86a9be6c 8061f090 [ 134.151282] be40: 89f0b018 89f0d000 89f0b000 00000000 86224090 0000003c 00000000 0000003c [ 134.159567] be60: 86a9be94 0000003c 803cd280 86be5e00 8604ea40 86be5e14 00000000 86802014 [ 134.167852] be80: 86a9bea4 86a9be90 803cd29c 803cc838 00000001 80101438 86a9bebc 86a9bea8 [ 134.176135] bea0: 803d00c4 803cd28c 86224000 86be5e04 86a9bee4 86a9bec0 803d05fc 803d00a8 [ 134.184419] bec0: 86be5e04 86acf980 00000000 86808700 86802000 00000000 86a9bf1c 86a9bee8 [ 134.192703] bee0: 8012ef38 803d054c 00000088 8090cac0 86a9a000 86acf980 86802000 86acf998 [ 134.200988] bf00: 00000088 8090cac0 86a9a000 86802014 86a9bf5c 86a9bf20 8012f260 8012ee20 [ 134.209270] bf20: 86ad1dc0 8070ee70 8092c91c 86802000 00000000 00000000 86ad1dc0 86a9a000 [ 134.217554] bf40: 86acf980 8012f1f4 00000000 00000000 86a9bfac 86a9bf60 80134a78 8012f200 [ 134.225838] bf60: 00000000 00000000 86ad1dc0 86acf980 00000000 86a9bf74 86a9bf74 00000000 [ 134.234122] bf80: 86a9bf80 86a9bf80 8013b048 86ad1dc0 80134980 00000000 00000000 00000000 [ 134.242406] bfa0: 00000000 86a9bfb0 80107990 8013498c 00000000 00000000 00000000 00000000 [ 134.250688] bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 134.258970] bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000 [ 134.267228] Backtrace: [ 134.269785] [<7f169d34>] (gs_flush_chars [u_serial]) from [<803cce74>] (n_tty_receive_buf_common+0x648/0xa54) [ 134.279800] r5:00000000 r4:89f0b000 [ 134.283449] [<803cc82c>] (n_tty_receive_buf_common) from [<803cd29c>] (n_tty_receive_buf2+0x1c/0x24) [ 134.292695] r10:86802014 r9:00000000 r8:86be5e14 r7:8604ea40 r6:86be5e00 r5:803cd280 [ 134.300610] r4:0000003c [ 134.303216] [<803cd280>] (n_tty_receive_buf2) from [<803d00c4>] (tty_ldisc_receive_buf+0x28/0x64) [ 134.312201] [<803d009c>] (tty_ldisc_receive_buf) from [<803d05fc>] (flush_to_ldisc+0xbc/0xd4) [ 134.320822] r5:86be5e04 r4:86224000 [ 134.324476] [<803d0540>] (flush_to_ldisc) from [<8012ef38>] (process_one_work+0x124/0x3e0) [ 134.332851] r9:00000000 r8:86802000 r7:86808700 r6:00000000 r5:86acf980 r4:86be5e04 [ 134.340706] [<8012ee14>] (process_one_work) from [<8012f260>] (worker_thread+0x6c/0x5a8) [ 134.348905] r10:86802014 r9:86a9a000 r8:8090cac0 r7:00000088 r6:86acf998 r5:86802000 [ 134.356828] r4:86acf980 [ 134.359431] [<8012f1f4>] (worker_thread) from [<80134a78>] (kthread+0xf8/0x110) [ 134.366847] r10:00000000 r9:00000000 r8:8012f1f4 r7:86acf980 r6:86a9a000 r5:86ad1dc0 [ 134.374765] r4:00000000 [ 134.377375] [<80134980>] (kthread) from [<80107990>] (ret_from_fork+0x14/0x24) [ 134.384708] r8:00000000 r7:00000000 r6:00000000 r5:80134980 r4:86ad1dc0 [ 134.391483] Code: e24cb004 e5900168 e10f4000 f10c0080 (e59030a8) [ 134.397643] ---[ end trace 6d6c0a94eccf9fda ]--- Reproduction: 1. Set up USB serial gadget and connect to device. 2. On device: while true; do echo "abcdefgh01234567890" > /dev/ttyGS0; done 3. On PC, execute simultaneously: while true; do cat /dev/ttyACM0 >> /tmp/tmp-dl; done for i in `seq 10000` ; do echo "XXXXXXXXXXXXXX" > /dev/ttyACM0 ; done --- drivers/usb/gadget/function/u_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index f7771d86ad6c..4ea44f7122ee 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -518,7 +518,7 @@ static void gs_rx_push(unsigned long _port) } /* push data to (open) tty */ - if (req->actual) { + if (req->actual && tty) { char *packet = req->buf; unsigned size = req->actual; unsigned n; -- 2.7.4