From: Greg Kroah-Hartman Date: Thu, 13 Aug 2026 00:53:55 +0000 (+0900) Subject: 5.10-stable patches X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=23d1dfcad04065826671d4a8821790b2ff139abb;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: alsa-usb-audio-fix-oob-write-on-type-ii-inbound-urbs.patch input-evdev-sanitize-event-type-index-when-fetching-event-masks.patch net-usb-ipheth-fix-carrier_work-uaf-on-disconnect.patch usb-atm-cxacru-properly-kill-rcv_urb-on-error-in-cxacru_cm.patch usb-gadget-f_ncm-use-unsigned-int-for-ndp_index.patch vt-add-permission-check-for-kdskbmeta-ioctl.patch vt-stabilize-tty-reference-in-kbd_keycode-with-tty_port_tty_get.patch --- diff --git a/queue-5.10/alsa-usb-audio-fix-oob-write-on-type-ii-inbound-urbs.patch b/queue-5.10/alsa-usb-audio-fix-oob-write-on-type-ii-inbound-urbs.patch new file mode 100644 index 0000000000..0a2b6aa09c --- /dev/null +++ b/queue-5.10/alsa-usb-audio-fix-oob-write-on-type-ii-inbound-urbs.patch @@ -0,0 +1,109 @@ +From 69ee44e1a23be62318189dc4b37fa4ad94053269 Mon Sep 17 00:00:00 2001 +From: Baul Lee +Date: Wed, 5 Aug 2026 10:34:41 +0900 +Subject: ALSA: usb-audio: fix OOB write on Type II inbound URBs + +From: Baul Lee + +commit 69ee44e1a23be62318189dc4b37fa4ad94053269 upstream. + +data_ep_set_params() sizes each URB transfer buffer before it adds the +Format Type II transfer delimiter: + + u->packets = urb_packs; + u->buffer_size = maxsize * u->packets; + + if (fmt->fmt_type == UAC_FORMAT_TYPE_II) + u->packets++; /* for transfer delimiter */ + u->urb = usb_alloc_urb(u->packets, GFP_KERNEL); + +buffer_size is computed from the pre-increment packet count and never +recomputed, so for a Type II endpoint the buffer is one packet short of +the packet count the URB is built with. + +prepare_inbound_urb() then lays out one iso frame per packet and never +consults buffer_size: + + offs = 0; + for (i = 0; i < urb_ctx->packets; i++) { + urb->iso_frame_desc[i].offset = offs; + urb->iso_frame_desc[i].length = ep->curpacksize; + offs += ep->curpacksize; + } + + urb->transfer_buffer_length = offs; + urb->number_of_packets = urb_ctx->packets; + +The last descriptor therefore points one packet past the end of the +transfer buffer, where the host controller writes device data on every +inbound transfer. prepare_silent_urb() and prepare_playback_urb() bound +their fill loops by ctx->buffer_size, so only capture is affected. + +fmt_type comes from the device's audio streaming descriptors, so any +device advertising a Type II capture format hits this once userspace sets +hw_params on the stream. + +KASAN on 7.2.0-rc5 (arm64) with a dummy_hcd/raw-gadget device, one report +per inbound transfer: + + BUG: KASAN: slab-out-of-bounds in dummy_timer + Write of size 64 at addr ffff0000186171c0 by task cons02/166 + __asan_memcpy + dummy_timer + hrtimer_run_softirq + Allocated by task 166: + usb_alloc_coherent + snd_usb_endpoint_set_params + The buggy address is located 0 bytes to the right of + allocated 64-byte region [ffff000018617180, ffff0000186171c0) + +Compute buffer_size after the delimiter packet has been accounted for, +and bound the fill loop by buffer_size, as prepare_silent_urb() already +does on the outbound side. This grows every Type II URB allocation by +one maxsize packet. + +Discovered by XBOW, triaged by Baul Lee + +Fixes: 8fdff6a319e7 ("ALSA: snd-usb: implement new endpoint streaming model") +Reported-by: Federico Kirschbaum +Reported-by: Baul Lee +Cc: stable@vger.kernel.org +Signed-off-by: Baul Lee +Link: https://patch.msgid.link/20260805013441.38245-1-baul.lee@xbow.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/endpoint.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/sound/usb/endpoint.c ++++ b/sound/usb/endpoint.c +@@ -301,13 +301,15 @@ static inline void prepare_inbound_urb(s + case SND_USB_ENDPOINT_TYPE_DATA: + offs = 0; + for (i = 0; i < urb_ctx->packets; i++) { ++ if (offs + ep->curpacksize > urb_ctx->buffer_size) ++ break; + urb->iso_frame_desc[i].offset = offs; + urb->iso_frame_desc[i].length = ep->curpacksize; + offs += ep->curpacksize; + } + + urb->transfer_buffer_length = offs; +- urb->number_of_packets = urb_ctx->packets; ++ urb->number_of_packets = i; + break; + + case SND_USB_ENDPOINT_TYPE_SYNC: +@@ -961,10 +963,10 @@ static int data_ep_set_params(struct snd + u->index = i; + u->ep = ep; + u->packets = urb_packs; +- u->buffer_size = maxsize * u->packets; + + if (fmt->fmt_type == UAC_FORMAT_TYPE_II) + u->packets++; /* for transfer delimiter */ ++ u->buffer_size = maxsize * u->packets; + u->urb = usb_alloc_urb(u->packets, GFP_KERNEL); + if (!u->urb) + goto out_of_memory; diff --git a/queue-5.10/input-evdev-sanitize-event-type-index-when-fetching-event-masks.patch b/queue-5.10/input-evdev-sanitize-event-type-index-when-fetching-event-masks.patch new file mode 100644 index 0000000000..0db8369d50 --- /dev/null +++ b/queue-5.10/input-evdev-sanitize-event-type-index-when-fetching-event-masks.patch @@ -0,0 +1,59 @@ +From 3abd29c61d2ef37c4102cf755b18be53bb9dbea6 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Mon, 3 Aug 2026 18:41:49 -0700 +Subject: Input: evdev - sanitize event type index when fetching event masks + +From: Dmitry Torokhov + +commit 3abd29c61d2ef37c4102cf755b18be53bb9dbea6 upstream. + +The user-supplied event type index passed to EVIOCGMASK / EVIOCSMASK +ioctls is used to index the static counts array in evdev_get_mask_cnt() +and client evmasks array in evdev_get_mask(). + +While the event type is architecturally bounded by EV_CNT, speculative +execution may mispredict bounds checks and perform out-of-bounds loads. + +Sanitize the event type index in evdev_get_mask_cnt() branchlessly using +array_index_mask_nospec(). This clamps the index to 0 for safe array +access and forces the returned count to 0 speculatively when the index +is out of bounds. + +We do not need additional array_index_nospec() calls in evdev_get_mask() +because evdev_get_mask_cnt() speculatively forces the count (and +resulting xfer_size) to 0 for out-of-bounds types, preventing any +speculative memory access to client evmasks array. + +Reported-by: "Wagenaar, C.C.J. (Chris)" +Cc: stable@vger.kernel.org +Assisted-by: Antigravity:gemini-3.6-flash +Acked-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/anFCAfvxwXB5eJF1@google.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/evdev.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/input/evdev.c ++++ b/drivers/input/evdev.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include + #include "input-compat.h" +@@ -67,8 +68,10 @@ static size_t evdev_get_mask_cnt(unsigne + [EV_SND] = SND_CNT, + [EV_FF] = FF_CNT, + }; ++ unsigned long mask = array_index_mask_nospec(type, EV_CNT); + +- return (type < EV_CNT) ? counts[type] : 0; ++ /* Returns 0 for out-of-bounds types, including speculatively */ ++ return counts[type & mask] & mask; + } + + /* requires the buffer lock to be held */ diff --git a/queue-5.10/net-usb-ipheth-fix-carrier_work-uaf-on-disconnect.patch b/queue-5.10/net-usb-ipheth-fix-carrier_work-uaf-on-disconnect.patch new file mode 100644 index 0000000000..33cfe1dd81 --- /dev/null +++ b/queue-5.10/net-usb-ipheth-fix-carrier_work-uaf-on-disconnect.patch @@ -0,0 +1,104 @@ +From fde39b8a521780391fb4e5bda2c0aa4928947f12 Mon Sep 17 00:00:00 2001 +From: Doruk Tan Ozturk +Date: Sun, 2 Aug 2026 14:06:02 +0200 +Subject: net: usb: ipheth: fix carrier_work UAF on disconnect + +From: Doruk Tan Ozturk + +commit fde39b8a521780391fb4e5bda2c0aa4928947f12 upstream. + +ipheth_sndbulk_callback() re-arms the carrier-check work on any +non-zero URB status: + + else + schedule_delayed_work(&dev->carrier_work, 0); + +Nothing ties that to the interface being up, so the work can be armed +again after ipheth_close() has already drained it, and stay armed +until the netdev whose private area embeds it is freed. + +On unplug with a TX URB in flight, ipheth_disconnect() drains the work +through unregister_netdev() -> ipheth_close() -> +cancel_delayed_work_sync() and only then calls ipheth_kill_urbs(). +usb_kill_urb() completes the in-flight TX URB with -ENOENT, so +ipheth_sndbulk_callback() runs after the drain and re-arms +carrier_work. + +The same completion also re-arms the work if the interface is only +brought down while a TX URB is in flight, and +ipheth_carrier_check_work() then keeps re-queueing itself once a +second. unregister_netdev() does not call ipheth_close() for an +already-down interface, so nothing drains it on the later unplug +either. + +In both cases free_netdev() frees the netdev while carrier_work is +still pending, and ipheth_carrier_check_work() dereferences freed +memory. + +Tie the work to the interface state instead of chasing the completion: +disable it in ipheth_close() and enable it in ipheth_open(), so a +schedule_delayed_work() from the URB completion is a no-op whenever +the interface is not up. disable_delayed_work_sync() also waits for a +running instance, so it fully replaces the cancel_delayed_work_sync() +it takes the place of. The work starts out disabled in ipheth_probe() +so the enable/disable counts balance from the first open. + +Reproduced under KASAN on linux-next (next-20260731) with dummy_hcd and +raw-gadget standing in for the device, driving the second path above (the +interface is already down, so unregister_netdev() does not call +ipheth_close()): 15 of 15 unpatched boots report a slab-use-after-free in +__run_timers(), freed by ipheth_disconnect() and re-armed from +ipheth_sndbulk_callback() via queue_delayed_work_on(). The +same trigger on a kernel differing only by this patch reports 0 of 15, +and the carrier check still functions across open/close cycles. + +The reproducer needs an attached USB device that stops draining bulk OUT, +plus a link down and unplug, driven as root. It is not a privilege +boundary crossing and no exploit primitive was developed. + +Found by 0sec (https://0sec.ai). + +Fixes: bb1b40c7cb86 ("usbnet: ipheth: prevent TX queue timeouts when device not ready") +Cc: stable@vger.kernel.org +Signed-off-by: Doruk Tan Ozturk +Link: https://patch.msgid.link/20260802120602.42595-1-doruk@0sec.ai +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/ipheth.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/net/usb/ipheth.c ++++ b/drivers/net/usb/ipheth.c +@@ -346,6 +346,7 @@ static int ipheth_open(struct net_device + if (retval) + return retval; + ++ enable_delayed_work(&dev->carrier_work); + schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT); + return retval; + } +@@ -355,7 +356,11 @@ static int ipheth_close(struct net_devic + struct ipheth_device *dev = netdev_priv(net); + + netif_stop_queue(net); +- cancel_delayed_work_sync(&dev->carrier_work); ++ /* A TX URB can still complete with an error after this point and ++ * try to re-arm the carrier work. Disable it instead of cancelling ++ * it, so that such a schedule_delayed_work() is a no-op. ++ */ ++ disable_delayed_work_sync(&dev->carrier_work); + return 0; + } + +@@ -483,6 +488,10 @@ static int ipheth_probe(struct usb_inter + goto err_get_macaddr; + + INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work); ++ /* Armed only between ipheth_open() and ipheth_close(). Start out ++ * disabled so the enable/disable counts balance from the first open. ++ */ ++ disable_delayed_work(&dev->carrier_work); + + retval = ipheth_alloc_urbs(dev); + if (retval) { diff --git a/queue-5.10/series b/queue-5.10/series index f30f30fb9c..6ed63c2621 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -340,3 +340,10 @@ sctp-extract-sctp_v4_err_handle-function-from-sctp_v.patch tls-don-t-abort-the-connection-on-signal-interrupted.patch spi-spi-fsl-dspi-avoid-setup_accel-logic-for-dma-tra.patch alsa-usb-audio-evaluate-packsize-caps-at-the-right-p.patch +input-evdev-sanitize-event-type-index-when-fetching-event-masks.patch +alsa-usb-audio-fix-oob-write-on-type-ii-inbound-urbs.patch +usb-atm-cxacru-properly-kill-rcv_urb-on-error-in-cxacru_cm.patch +usb-gadget-f_ncm-use-unsigned-int-for-ndp_index.patch +net-usb-ipheth-fix-carrier_work-uaf-on-disconnect.patch +vt-add-permission-check-for-kdskbmeta-ioctl.patch +vt-stabilize-tty-reference-in-kbd_keycode-with-tty_port_tty_get.patch diff --git a/queue-5.10/usb-atm-cxacru-properly-kill-rcv_urb-on-error-in-cxacru_cm.patch b/queue-5.10/usb-atm-cxacru-properly-kill-rcv_urb-on-error-in-cxacru_cm.patch new file mode 100644 index 0000000000..e30008c890 --- /dev/null +++ b/queue-5.10/usb-atm-cxacru-properly-kill-rcv_urb-on-error-in-cxacru_cm.patch @@ -0,0 +1,66 @@ +From c2f811314be351d86b6ab41e9297ae80d8da6f86 Mon Sep 17 00:00:00 2001 +From: Aleksandr Nogikh +Date: Fri, 31 Jul 2026 10:15:20 +0000 +Subject: usb: atm: cxacru: properly kill rcv_urb on error in cxacru_cm() + +From: Aleksandr Nogikh + +commit c2f811314be351d86b6ab41e9297ae80d8da6f86 upstream. + +If cxacru_cm() encounters an error while submitting or waiting for snd_urb, +it aborts and returns the error without killing the already submitted +rcv_urb. This leaves the rcv_urb active. + +When this happens during initialization (e.g., in cxacru_atm_start()), the +driver may ignore the error and proceed to call cxacru_poll_status(), which +invokes cxacru_cm() again. Attempting to submit the still-active rcv_urb +triggers a warning in usb_submit_urb(): + +cxacru 1-1:1.0: send of cm 0x84 failed (-104) +ATM dev 0: cxacru_atm_start: CHIP_ADSL_LINE_START returned -104 +------------[ cut here ]------------ +URB ffff88812658d200 submitted while active +WARNING: drivers/usb/core/urb.c:379 at usb_submit_urb+0x79/0x18b0 +drivers/usb/core/urb.c:379 +... +Call Trace: + + cxacru_cm+0x21a/0xf10 drivers/usb/atm/cxacru.c:631 + cxacru_cm_get_array drivers/usb/atm/cxacru.c:722 [inline] + cxacru_poll_status+0x178/0x1110 drivers/usb/atm/cxacru.c:828 + cxacru_atm_start+0x185/0x360 drivers/usb/atm/cxacru.c:814 + usbatm_atm_init+0x144/0x3a0 drivers/usb/atm/usbatm.c:927 + usbatm_usb_probe+0x15cb/0x1db0 drivers/usb/atm/usbatm.c:1178 + cxacru_usb_probe+0x17f/0x220 drivers/usb/atm/cxacru.c:1370 +... + +To fix this, ensure that rcv_urb is properly killed if cxacru_cm() aborts +early. We can safely call usb_kill_urb() on rcv_urb in the error path, as +it is safe to call even if the URB is not active (e.g., if it failed to +submit in the first place, or if it already completed). + +Fixes: 1b0e61465234 ("[PATCH] USB ATM: driver for the Conexant AccessRunner chipset cxacru") +Cc: stable +Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot +Reported-by: syzbot+c9dff578c3a41775176a@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=c9dff578c3a41775176a +Link: https://syzkaller.appspot.com/ai_job?id=75fec6f2-c8a6-43b1-b184-4d26baba86cc +Signed-off-by: Aleksandr Nogikh +Link: https://patch.msgid.link/91edfa4c-a63d-400c-9f00-31f3e1f98c00@mail.kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/atm/cxacru.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/atm/cxacru.c ++++ b/drivers/usb/atm/cxacru.c +@@ -700,6 +700,8 @@ static int cxacru_cm(struct cxacru_data + ret = offd; + usb_dbg(instance->usbatm, "cm %#x\n", cm); + fail: ++ if (ret < 0) ++ usb_kill_urb(instance->rcv_urb); + mutex_unlock(&instance->cm_serialize); + err: + return ret; diff --git a/queue-5.10/usb-gadget-f_ncm-use-unsigned-int-for-ndp_index.patch b/queue-5.10/usb-gadget-f_ncm-use-unsigned-int-for-ndp_index.patch new file mode 100644 index 0000000000..4c38310b8c --- /dev/null +++ b/queue-5.10/usb-gadget-f_ncm-use-unsigned-int-for-ndp_index.patch @@ -0,0 +1,42 @@ +From 6b1c8a9403a26cb0fed7a648916c74dc236da591 Mon Sep 17 00:00:00 2001 +From: Sonali Pradhan +Date: Mon, 20 Jul 2026 16:56:54 +0000 +Subject: usb: gadget: f_ncm: Use unsigned int for ndp_index + +From: Sonali Pradhan + +commit 6b1c8a9403a26cb0fed7a648916c74dc236da591 upstream. + +The variable ndp_index is declared as a signed integer, but it stores +the return value of get_ncm(), which is unsigned. + +A malicious host can supply a large offset that overflows the signed +ndp_index, making it negative. Because ndp_index is compared against +unsigned bounds, this negative value bypasses sanity checks and leads +to an out-of-bounds read when calculating the address of the NDP +block (ntb_ptr + ndp_index). + +Fix this by changing ndp_index to unsigned int to ensure consistent +unsigned comparisons throughout the function. + +Fixes: 370af734dfaf ("usb: gadget: NCM: RX function support multiple NDPs") +Cc: stable +Signed-off-by: Sonali Pradhan +Link: https://patch.msgid.link/20260720165654.2224591-1-sonalipradhan@google.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_ncm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/f_ncm.c ++++ b/drivers/usb/gadget/function/f_ncm.c +@@ -1183,7 +1183,7 @@ static int ncm_unwrap_ntb(struct gether + unsigned char *ntb_ptr = skb->data; + __le16 *tmp; + unsigned index, index2; +- int ndp_index; ++ unsigned int ndp_index; + unsigned dg_len, dg_len2; + unsigned ndp_len; + unsigned block_len; diff --git a/queue-5.10/vt-add-permission-check-for-kdskbmeta-ioctl.patch b/queue-5.10/vt-add-permission-check-for-kdskbmeta-ioctl.patch new file mode 100644 index 0000000000..ed4284e599 --- /dev/null +++ b/queue-5.10/vt-add-permission-check-for-kdskbmeta-ioctl.patch @@ -0,0 +1,34 @@ +From a7ad0034453ba4c353f9b8f810ee2569de33d283 Mon Sep 17 00:00:00 2001 +From: Joshua Rogers +Date: Fri, 31 Jul 2026 09:56:17 +0200 +Subject: vt: add permission check for KDSKBMETA ioctl + +From: Joshua Rogers + +commit a7ad0034453ba4c353f9b8f810ee2569de33d283 upstream. + +KDSKBMETA modifies keyboard meta mode but lacks the !perm check that all +other keyboard setter ioctls in vt_k_ioctl() enforce, allowing a process +to change meta mode on a non-controlling console without authorization. + +Assisted-by: AISLE:Snapshot +Cc: stable +Signed-off-by: Joshua Rogers +Link: https://patch.msgid.link/20260731-tty-vt-stuff-v1-2-be99b9da8e30@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/vt/vt_ioctl.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/tty/vt/vt_ioctl.c ++++ b/drivers/tty/vt/vt_ioctl.c +@@ -408,6 +408,8 @@ static int vt_k_ioctl(struct tty_struct + /* this could be folded into KDSKBMODE, but for compatibility + reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */ + case KDSKBMETA: ++ if (!perm) ++ return -EPERM; + return vt_do_kdskbmeta(console, arg); + + case KDGKBMETA: diff --git a/queue-5.10/vt-stabilize-tty-reference-in-kbd_keycode-with-tty_port_tty_get.patch b/queue-5.10/vt-stabilize-tty-reference-in-kbd_keycode-with-tty_port_tty_get.patch new file mode 100644 index 0000000000..2e240e73f7 --- /dev/null +++ b/queue-5.10/vt-stabilize-tty-reference-in-kbd_keycode-with-tty_port_tty_get.patch @@ -0,0 +1,48 @@ +From e25d47a526939ad44b75f778b8a7500562b84fc1 Mon Sep 17 00:00:00 2001 +From: Joshua Rogers +Date: Fri, 31 Jul 2026 09:56:16 +0200 +Subject: vt: stabilize tty reference in kbd_keycode with tty_port_tty_get + +From: Joshua Rogers + +commit e25d47a526939ad44b75f778b8a7500562b84fc1 upstream. + +kbd_keycode() reads vc->port.tty without acquiring a tty reference, +racing against con_shutdown() which clears port.tty under a different +lock. Use tty_port_tty_get()/tty_kref_put() to hold a proper reference +for the duration the tty pointer is needed. + +Assisted-by: AISLE:Snapshot +Signed-off-by: Joshua Rogers +Cc: stable +Link: https://patch.msgid.link/20260731-tty-vt-stuff-v1-1-be99b9da8e30@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/vt/keyboard.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/tty/vt/keyboard.c ++++ b/drivers/tty/vt/keyboard.c +@@ -1367,7 +1367,7 @@ static void kbd_keycode(unsigned int key + struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down }; + int rc; + +- tty = vc->port.tty; ++ tty = tty_port_tty_get(&vc->port); + + if (tty && (!tty->driver_data)) { + /* No driver data? Strange. Okay we fix it then. */ +@@ -1430,9 +1430,12 @@ static void kbd_keycode(unsigned int key + * characters get aren't echoed locally. This makes key repeat + * usable with slow applications and under heavy loads. + */ ++ tty_kref_put(tty); + return; + } + ++ tty_kref_put(tty); ++ + param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate; + param.ledstate = kbd->ledflagstate; + key_map = key_maps[shift_final];