Linux 5.10.269
Greg Kroah-Hartman
maintainerI'm announcing the release of the 5.10.269 kernel.
All users of the 5.10 kernel series must upgrade.
The updated 5.10.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-5.10.y
and can be browsed at the normal kernel.org git web browser:
https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary
thanks,
greg k-h
------------
Documentation/filesystems/fscrypt.rst | 4 + Makefile | 2 arch/arm64/kvm/arm.c | 6 + arch/s390/kvm/vsie.c | 1 drivers/accessibility/speakup/main.c | 1 drivers/base/power/main.c | 6 - drivers/crypto/atmel-tdes.c | 5 - drivers/crypto/mxs-dcp.c | 2 drivers/fpga/dfl-fme-perf.c | 2 drivers/hid/hid-input.c | 17 +++- drivers/hid/hid-magicmouse.c | 10 ++ drivers/infiniband/sw/rxe/rxe_qp.c | 3 drivers/mtd/maps/vmu-flash.c | 8 +- drivers/nvme/target/tcp.c | 13 +++ drivers/target/target_core_fabric_configfs.c | 8 ++ drivers/usb/c67x00/c67x00-sched.c | 4 - drivers/usb/core/devio.c | 2 drivers/usb/core/hub.c | 7 +- drivers/usb/gadget/function/f_tcm.c | 2 drivers/usb/misc/usbtest.c | 1 drivers/usb/serial/option.c | 20 ++++- drivers/usb/serial/spcp8x5.c | 13 --- fs/cifs/smb2ops.c | 4 - fs/ext4/fast_commit.c | 10 ++ fs/ext4/ialloc.c | 4 + fs/ext4/super.c | 40 +++++------ fs/jfs/inode.c | 2 fs/jfs/jfs_extent.c | 10 ++ fs/nilfs2/ioctl.c | 21 +++++- include/linux/hid.h | 1 include/linux/inetdevice.h | 5 + include/linux/sched.h | 8 ++ include/target/target_core_fabric.h | 2 io_uring/io-wq.c | 9 +- kernel/bpf/offload.c | 10 +- kernel/kcov.c | 93 +++++++++++++-------------- lib/Kconfig.debug | 5 - mm/swapfile.c | 7 ++ net/core/filter.c | 1 net/ipv4/igmp.c | 14 ++-- net/ipv6/ah6.c | 29 +++++--- net/ipv6/mcast.c | 8 +- net/ipv6/seg6_local.c | 7 ++ net/netfilter/ipvs/ip_vs_xmit.c | 6 - net/nfc/nci/ntf.c | 32 +++++++-- net/xfrm/espintcp.c | 9 ++ net/xfrm/xfrm_user.c | 2 security/selinux/ss/conditional.c | 12 +-- sound/usb/midi.c | 2 49 files changed, 325 insertions(+), 165 deletions(-)
Aleksandr Nogikh (1):
usb: usbtest: disable dynamic ID support
Asim Viladi Oglu Manizada (1):
xfrm: ah6: validate routing header segments_left
Bryam Vargas (1):
nfc: nci: add data_len bound checks to activation parameter extractors
Christian Borntraeger (1):
KVM: s390: vsie: zero stale crypto bits
Eric Biggers (2):
ext4: don't enable DAX on new encrypted files mm/swap: reject swapon() on filesystem-level encrypted files
Eric Dumazet (1):
ipv4: igmp: Fix potential UAF in igmp_gq_start_timer()
Florian Westphal (1):
ipvs: reload ip header after head reallocation
Greg Kroah-Hartman (1):
Linux 5.10.269
Griffin Kroah-Hartman (3):
fpga: dfl: fme: add error handling
usb: core: Add lock to usb_wakeup_notification()
usb: core: Strengthen error handling in hub_hub_status()
Guanghui Yang (1):
ext4: propagate errors from fast commit range replay
Haoxiang Li (1):
accessibility: speakup: unregister tty ldisc on later init failures
Ibrahim Hashimov (1):
nvmet-tcp: bound SGL data length before allocating command buffers
Ido Schimmel (1):
ipv6: mcast: Fix use-after-free when processing MLD queries
Jiale Yao (1):
USB: serial: option: fix slab OOB read in interrupt URB callback
Jiayuan Chen (1):
bpf: Fix use-after-free in offloaded map/prog info fill
Johan Hovold (1):
USB: serial: spcp8x5: drop broken carrier detect support
Jose Villaseñor Montfort (2):
HID: magicmouse: do not keep a stale msc->input if no input is claimed
HID: input: read battery capacity from its actual report offset
Kyle Zeng (1):
ipv6: seg6: clear IPv4 control block on IPIP decapsulation
Marouane El Moufid (1):
ALSA: usb-audio: fix OOB write in snd_usbmidi_novation_output()
Miguel Peñaranda (1):
usb: usbfs: fix use-after-free of usb_device in usbdev_release()
Oliver Upton (1):
KVM: arm64: Prevent access to vCPU events before init
Peiyang He (1):
RDMA/rxe: Fix OOB in free_rd_atomic_resources()
Ryusuke Konishi (1):
nilfs2: reject invalid block index in GC ioctl
Sabrina Dubroca (1):
xfrm: espintcp: fix UAF during close
Samuel Page (1):
nfc: nci: fix uninit-value in the RF discover/activated NTF handlers
Sasha Levin (3):
Revert "PM: sleep: Use complete() in device_pm_sleep_init()" Revert "mtd: maps: vmu-flash: fix fault in unaligned fixup" Revert "smb: client: use kvzalloc() for megabyte buffer in simple fallocate"
Sebastian Andrzej Siewior (1):
bpf: Remove tst_run from lwt_seg6local_prog_ops.
Shuangpeng Bai (2):
usb: gadget: f_tcm: keep port count until LUN teardown completes
USB: c67x00: fix use-after-free in c67x00_add_iso_urb()
Stephen Smalley (1):
selinux: switch two allocations to use kzalloc_objs()
Tetsuo Handa (1):
kcov: fix data corruption and race conditions on PREEMPT_RT
Thorsten Blum (2):
crypto: atmel-tdes - use scatterlist length before DMA mapping
crypto: mxs-dcp - fix source scatterlist length access
Vasiliy Kovalev (2):
jfs: add check read-only before truncation in jfs_truncate_nolock()
jfs: add check read-only before txBeginAnon() call
Vishnu Razdan (1):
io_uring/io-wq: fix worker accounting when canceling creation callbacks
Zhiling Zou (1):
xfrm: drop ESP-in-TCP packets with no ingress device
Zihan Xi (1):
xfrm: fix xfrm_state_construct() auth-trunc leak
Greg Kroah-Hartman
maintainerDocumentation/filesystems/fscrypt.rst +4 -0
@@ -1068,6 +1068,10 @@ astute users may notice some differences in behavior: give the length of the ciphertext, which will be slightly longer than the plaintext due to NUL-padding and an extra 2-byte overhead. +- Encrypted files cannot be used directly as swap files. To swap to + an encrypted file, set up a loopback device on top of it. + Alternatively, encrypted swap can use a dm-crypt device. + - The maximum length of an encrypted symlink is 2 bytes shorter than the maximum length of an unencrypted symlink. For example, on an EXT4 filesystem with a 4K block size, unencrypted symlinks can be up
Makefile +1 -1
@@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 -SUBLEVEL = 268 +SUBLEVEL = 269 EXTRAVERSION = NAME = Dare mighty things
arch/arm64/kvm/arm.c +6 -0
@@ -1209,6 +1209,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,case KVM_GET_VCPU_EVENTS : {struct kvm_vcpu_events events; +if (!kvm_vcpu_initialized (vcpu)) +return -ENOEXEC ; +if (kvm_arm_vcpu_get_events (vcpu, &events))return -EINVAL ;
@@ -1220,6 +1223,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,case KVM_SET_VCPU_EVENTS : {struct kvm_vcpu_events events; +if (!kvm_vcpu_initialized (vcpu)) +return -ENOEXEC ; +if (copy_from_user (&events, argp,sizeof (events)))return -EFAULT ;
arch/s390/kvm/vsie.c +1 -0
@@ -144,6 +144,7 @@ static int setup_apcb10(struct kvm_vcpu *vcpu, struct kvm_s390_apcb1 *apcb_s,if (read_guest_real (vcpu, apcb_o, &tmp,sizeof (struct kvm_s390_apcb0 )))return -EFAULT ; +memset (apcb_s,0 ,sizeof (*apcb_s)); apcb_s->apm[0 ] = apcb_h->apm[0 ] & tmp.apm[0 ]; apcb_s->aqm[0 ] = apcb_h->aqm[0 ] & tmp.aqm[0 ] &0xffff000000000000UL ; apcb_s->adm[0 ] = apcb_h->adm[0 ] & tmp.adm[0 ] &0xffff000000000000UL ;
drivers/accessibility/speakup/main.c +1 -0
@@ -2432,6 +2432,7 @@ static int __init speakup_init(void)mutex_lock (&spk_mutex);synth_release ();mutex_unlock (&spk_mutex); +spk_ttyio_unregister_ldisc ();speakup_kobj_exit (); error_kobjects:
drivers/base/power/main.c +1 -5
@@ -102,7 +102,7 @@ void device_pm_sleep_init(struct device *dev) dev->power.is_noirq_suspended = false; dev->power.is_late_suspended = false;init_completion (&dev->power.completion); -complete (&dev->power.completion); +complete_all (&dev->power.completion); dev->power.wakeup =NULL ;INIT_LIST_HEAD (&dev->power.entry); }
@@ -242,10 +242,6 @@ static void dpm_wait(struct device *dev, bool async)if (!dev)return ; -/* Devices with no PM support don't use the completion. */ -if (dev->power.no_pm) -return ; -if (async || (pm_async_enabled && dev->power.async_suspend))wait_for_completion (&dev->power.completion); }
drivers/crypto/atmel-tdes.c +2 -3
@@ -509,14 +509,13 @@ static int atmel_tdes_crypt_start(struct atmel_tdes_dev *dd)IS_ALIGNED (dd->out_sg->length, dd->ctx->block_size); fast = in && out; -if (sg_dma_len (dd->in_sg) !=sg_dma_len (dd->out_sg)) +if (dd->in_sg->length != dd->out_sg->length) fast =0 ; }if (fast) { - count =min_t (size_t, dd->total,sg_dma_len (dd->in_sg)); - count =min_t (size_t, count,sg_dma_len (dd->out_sg)); + count =min_t (size_t, dd->total, dd->in_sg->length); err =dma_map_sg (dd->dev, dd->in_sg,1 ,DMA_TO_DEVICE );if (!err) {
drivers/crypto/mxs-dcp.c +1 -1
@@ -332,7 +332,7 @@ static int mxs_dcp_aes_block_crypt(struct crypto_async_request *arq)for_each_sg (req->src, src,sg_nents (req->src), i) { src_buf =sg_virt (src); - len =sg_dma_len (src); + len = src->length; tlen += len; limit_hit = tlen > req->cryptlen;
drivers/fpga/dfl-fme-perf.c +2 -0
@@ -925,6 +925,8 @@ static int fme_perf_pmu_register(struct platform_device *pdev,PERF_PMU_CAP_NO_EXCLUDE ; name =devm_kasprintf (priv->dev,GFP_KERNEL ,"dfl_fme%d" , pdev->id); +if (!name) +return -ENOMEM ; ret =perf_pmu_register (pmu, name,-1 );if (ret)
drivers/hid/hid-input.c +13 -4
@@ -358,19 +358,27 @@ static int hidinput_query_battery_capacity(struct hid_device *dev) {u8 *buf;int ret; +/* +* The capacity field may not be the first field in the report: some +* devices (e.g. the Apple Magic Trackpad 2 over Bluetooth) precede it +* with status flags. Read it from its actual byte offset in the report +* (report_offset is in bits; the leading byte is the report id). +*/ +int offset =1 + dev->battery_report_offset /8 ; +int len = offset +1 ; - buf =kmalloc (4 ,GFP_KERNEL ); + buf =kmalloc (max (len,4 ),GFP_KERNEL );if (!buf)return -ENOMEM ; - ret =hid_hw_raw_request (dev, dev->battery_report_id, buf,4 , + ret =hid_hw_raw_request (dev, dev->battery_report_id, buf,max (len,4 ), dev->battery_report_type,HID_REQ_GET_REPORT ); -if (ret <2 ) { +if (ret < len) {kfree (buf);return -ENODATA ; } - ret =hidinput_scale_battery_capacity (dev, buf[1 ]); + ret =hidinput_scale_battery_capacity (dev, buf[offset]);kfree (buf);return ret; }
@@ -487,6 +495,7 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, dev->battery_max = max; dev->battery_report_type = report_type; dev->battery_report_id = field->report->id; + dev->battery_report_offset = field->report_offset;/* * Stylus is normally not connected to the device and thus we
drivers/hid/hid-magicmouse.c +10 -0
@@ -643,6 +643,16 @@ static int magicmouse_probe(struct hid_device *hdev,return ret; } +/* +* When hidinput_connect() fails it frees every input device it +* created, but that does not fail hid_hw_start(): the core simply +* does not claim an input. msc->input, cached in ->input_mapping +* while the report descriptor was parsed, would then be a dangling +* pointer that passes every NULL check. Trust the core's claim. +*/ +if (!(hdev->claimed &HID_CLAIMED_INPUT )) + msc->input =NULL ; +if (!msc->input) {hid_err (hdev,"magicmouse input not registered\n" ); ret = -ENOMEM ;
drivers/infiniband/sw/rxe/rxe_qp.c +1 -2
@@ -580,10 +580,9 @@ int rxe_qp_from_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask,int max_dest_rd_atomic = attr->max_dest_rd_atomic ?roundup_pow_of_two (attr->max_dest_rd_atomic) :0 ; - qp->attr.max_dest_rd_atomic = max_dest_rd_atomic; -free_rd_atomic_resources (qp); + qp->attr.max_dest_rd_atomic = max_dest_rd_atomic; err =alloc_rd_atomic_resources (qp, max_dest_rd_atomic);if (err)return err;
drivers/mtd/maps/vmu-flash.c +5 -3
@@ -610,7 +610,7 @@ static int vmu_connect(struct maple_device *mdev) basic_flash_data =be32_to_cpu (mdev->devinfo.function_data[c -1 ]); - card = kzalloc_obj(struct memcard); + card =kmalloc (sizeof (struct memcard ),GFP_KERNEL );if (!card) { error = -ENOMEM ; goto fail_nomem;
@@ -628,13 +628,15 @@ static int vmu_connect(struct maple_device *mdev)* Not sure there are actually any multi-partition devices in the * real world, but the hardware supports them, so, so will we */ - card->parts = kzalloc_objs(struct vmupart, card->partitions); + card->parts =kmalloc_array (card->partitions,sizeof (struct vmupart ), +GFP_KERNEL );if (!card->parts) { error = -ENOMEM ; goto fail_partitions; } - card->mtd = kzalloc_objs(struct mtd_info, card->partitions); + card->mtd =kmalloc_array (card->partitions,sizeof (struct mtd_info ), +GFP_KERNEL );if (!card->mtd) { error = -ENOMEM ; goto fail_mtd_info;
drivers/nvme/target/tcp.c +13 -0
@@ -382,6 +382,19 @@ static int nvmet_tcp_map_data(struct nvmet_tcp_cmd *cmd)if (!len)return 0 ; +/* +* inline_data_size only bounds the in-capsule (type 0x01) SGL +* descriptor below. A non-inline transport SGL data-block +* descriptor skips that check entirely and would otherwise reach +* sgl_alloc() with an attacker-controlled len of up to 4 GiB, +* pinning that much kernel memory for a command that may never +* complete. Bound every descriptor type here, before allocating +* anything, using the same ceiling this file already applies to +* per-PDU H2C data. +*/ +if (len >NVMET_TCP_MAXH2CDATA ) +return NVME_SC_SGL_INVALID_DATA |NVME_SC_DNR ; +if (sgl->type == ((NVME_SGL_FMT_DATA_DESC <<4 ) |NVME_SGL_FMT_OFFSET )) {if (!nvme_is_write (cmd->req.cmd))
drivers/target/target_core_fabric_configfs.c +8 -0
@@ -689,6 +689,14 @@ static void target_fabric_port_unlink( }core_dev_del_lun (se_tpg, lun); + +if (tf->tf_ops->fabric_post_unlink) { +/* +* Allow fabrics to release state that must remain valid until +* core_dev_del_lun() has drained all active LUN references. +*/ + tf->tf_ops->fabric_post_unlink (se_tpg, lun); + } }static void target_fabric_port_release (struct config_item *item)
drivers/usb/c67x00/c67x00-sched.c +2 -2
@@ -761,13 +761,13 @@ static int c67x00_add_iso_urb(struct c67x00_hcd *c67x00, struct urb *urb) ret); urb->iso_frame_desc[urbp->cnt].actual_length =0 ; urb->iso_frame_desc[urbp->cnt].status = ret; -if (urbp->cnt +1 == urb->number_of_packets) -c67x00_giveback_urb (c67x00, urb,0 ); } urbp->ep_data->next_frame =frame_add (urbp->ep_data->next_frame, urb->interval); urbp->cnt++; +if (ret && urbp->cnt == urb->number_of_packets) +c67x00_giveback_urb (c67x00, urb,0 ); }return 0 ; }
drivers/usb/core/devio.c +1 -1
@@ -1098,7 +1098,6 @@ static int usbdev_release(struct inode *inode, struct file *file)if (!ps->suspend_allowed)usb_autosuspend_device (dev);usb_unlock_device (dev); -usb_put_dev (dev);put_pid (ps->disc_pid);put_cred (ps->cred);
@@ -1107,6 +1106,7 @@ static int usbdev_release(struct inode *inode, struct file *file)free_async (as); as =async_getcompleted (ps); } +usb_put_dev (dev);kfree (ps);return 0 ;
drivers/usb/core/hub.c +6 -1
@@ -714,10 +714,12 @@ void usb_wakeup_notification(struct usb_device *hdev, {struct usb_hub *hub;struct usb_port *port_dev; +unsigned long flags;if (!hdev)return ; +spin_lock_irqsave (&device_state_lock, flags); hub =usb_hub_to_struct_hub (hdev);if (hub) { port_dev = hub->ports[portnum -1 ];
@@ -727,6 +729,7 @@ void usb_wakeup_notification(struct usb_device *hdev,set_bit (portnum, hub->wakeup_bits);kick_hub_wq (hub); } +spin_unlock_irqrestore (&device_state_lock, flags); }EXPORT_SYMBOL_GPL (usb_wakeup_notification);
@@ -952,10 +955,12 @@ static int hub_hub_status(struct usb_hub *hub,mutex_lock (&hub->status_mutex); ret =get_hub_status (hub->hdev, &hub->status->hub); -if (ret <0 ) { +if (ret < (int )sizeof (hub->status->hub)) {if (ret != -ENODEV )dev_err (hub->intfdev,"%s failed (err = %d)\n" , __func__, ret); +if (ret >=0 ) + ret = -EIO ; }else { *status =le16_to_cpu (hub->status->hub.wHubStatus); *change =le16_to_cpu (hub->status->hub.wHubChange);
drivers/usb/gadget/function/f_tcm.c +1 -1
@@ -1732,7 +1732,7 @@ static const struct target_core_fabric_ops usbg_ops = { .fabric_make_tpg = usbg_make_tpg, .fabric_drop_tpg = usbg_drop_tpg, .fabric_post_link = usbg_port_link, - .fabric_pre_unlink = usbg_port_unlink, + .fabric_post_unlink = usbg_port_unlink, .fabric_init_nodeacl = usbg_init_nodeacl, .tfc_wwn_attrs = usbg_wwn_attrs,
drivers/usb/misc/usbtest.c +1 -0
@@ -3053,6 +3053,7 @@ static struct usb_driver usbtest_driver = { .disconnect = usbtest_disconnect, .suspend = usbtest_suspend, .resume = usbtest_resume, + .no_dynamic_id = 1, };/*-------------------------------------------------------------------------*/
drivers/usb/serial/option.c +17 -3
@@ -2693,12 +2693,26 @@ static void option_instat_callback(struct urb *urb)dev_dbg (dev,"%s: NULL req_pkt\n" , __func__);return ; } + +if (urb->actual_length <sizeof (*req_pkt)) { +dev_err (dev,"%s: short packet: %u bytes\n" , __func__, + urb->actual_length); +return ; + } +if ((req_pkt->bRequestType ==0xA1 ) && (req_pkt->bRequest ==0x20 )) { +unsigned char signals;int old_dcd_state; -unsigned char signals = *((unsigned char *) - urb->transfer_buffer + -sizeof (struct usb_ctrlrequest )); + +if (urb->actual_length <sizeof (*req_pkt) +1 ) { +dev_err (dev,"%s: short interrupt transfer: %u bytes\n" , + __func__, urb->actual_length); +return ; + } + + signals = *((unsigned char *)urb->transfer_buffer + +sizeof (*req_pkt));dev_dbg (dev,"%s: signal x%x\n" , __func__, signals);
drivers/usb/serial/spcp8x5.c +0 -13
@@ -249,18 +249,6 @@ static void spcp8x5_set_work_mode(struct usb_serial_port *port, u16 value,dev_err (&port->dev,"failed to set work mode: %d\n" , ret); } -static int spcp8x5_carrier_raised (struct usb_serial_port *port) -{ -u8 msr; -int ret; - - ret =spcp8x5_get_msr (port, &msr); -if (ret || msr &MSR_STATUS_LINE_DCD ) -return 1 ; - -return 0 ; -} -static void spcp8x5_dtr_rts (struct usb_serial_port *port,int on) {struct spcp8x5_private *priv =usb_get_serial_port_data (port);
@@ -472,7 +460,6 @@ static struct usb_serial_driver spcp8x5_device = { .num_bulk_out = 1, .open = spcp8x5_open, .dtr_rts = spcp8x5_dtr_rts, - .carrier_raised = spcp8x5_carrier_raised, .set_termios = spcp8x5_set_termios, .init_termios = spcp8x5_init_termios, .tiocmget = spcp8x5_tiocmget,
fs/cifs/smb2ops.c +2 -2
@@ -3568,7 +3568,7 @@ static int smb3_simple_fallocate_range(unsigned int xid,if (rc) goto out; - buf =kvzalloc (1024 *1024 ,GFP_KERNEL ); + buf =kzalloc (1024 *1024 ,GFP_KERNEL );if (buf ==NULL ) { rc = -ENOMEM ; goto out;
@@ -3635,7 +3635,7 @@ static int smb3_simple_fallocate_range(unsigned int xid, out:kfree (out_data); -kvfree (buf); +kfree (buf);return rc; }
fs/ext4/fast_commit.c +7 -3
@@ -1678,8 +1678,10 @@ static int ext4_fc_replay_add_range(struct super_block *sb,if (ret ==0 ) {/* Range is not mapped */ path =ext4_find_extent (inode, cur,NULL ,0 ); -if (IS_ERR (path)) +if (IS_ERR (path)) { + ret =PTR_ERR (path); goto out; + }memset (&newex,0 ,sizeof (newex)); newex.ee_block =cpu_to_le32 (cur); ext4_ext_store_pblock(
@@ -1741,9 +1743,10 @@ static int ext4_fc_replay_add_range(struct super_block *sb, }ext4_ext_replay_shrink_inode (inode,i_size_read (inode) >> sb->s_blocksize_bits); + ret =0 ; out:iput (inode); -return 0 ; +return ret; }/* Replay DEL_RANGE tag */
@@ -1804,9 +1807,10 @@ ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl,ext4_ext_replay_shrink_inode (inode,i_size_read (inode) >> sb->s_blocksize_bits);ext4_mark_inode_dirty (NULL , inode); + ret =0 ; out:iput (inode); -return 0 ; +return ret; }static inline const char *tag2str (u16 tag)
fs/ext4/ialloc.c +4 -0
@@ -994,6 +994,8 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir, err =fscrypt_prepare_new_inode (dir, inode, &encrypt);if (err) goto out; +if (encrypt) + i_flags |=EXT4_ENCRYPT_FL ; } err =dquot_initialize (inode);
@@ -1307,6 +1309,8 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir, ei->i_extra_isize = sbi->s_want_extra_isize; ei->i_inline_off =0 ;if (ext4_has_feature_inline_data (sb) && +/* Encrypted inodes cannot have inline data */ + !(ei->i_flags &EXT4_ENCRYPT_FL ) && (!(ei->i_flags &EXT4_DAX_FL ) ||S_ISDIR (mode)))ext4_set_inode_state (inode,EXT4_STATE_MAY_INLINE_DATA ); ret = inode;
fs/ext4/super.c +20 -20
@@ -1494,7 +1494,13 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,if (inode->i_ino ==EXT4_ROOT_INO )return -EPERM ; -if (WARN_ON_ONCE (IS_DAX (inode) &&i_size_read (inode))) +/* +* For new encrypted inodes, S_DAX is never set in the first place. +* +* For existing inodes, this is called only on empty directories. ext4 +* never sets S_DAX on directories. +*/ +if (WARN_ON_ONCE (IS_DAX (inode)))return -EINVAL ;if (ext4_test_inode_flag (inode,EXT4_INODE_DAX ))
@@ -1513,21 +1519,18 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,*/ if (handle) { - res =ext4_xattr_set_handle (handle, inode, -EXT4_XATTR_INDEX_ENCRYPTION , -EXT4_XATTR_NAME_ENCRYPTION_CONTEXT , - ctx, len,0 ); -if (!res) { -ext4_set_inode_flag (inode,EXT4_INODE_ENCRYPT ); -ext4_clear_inode_state (inode, -EXT4_STATE_MAY_INLINE_DATA ); -/* -* Update inode->i_flags - S_ENCRYPTED will be enabled, -* S_DAX may be disabled -*/ -ext4_set_inode_flags (inode, false); - } -return res; +/* +* __ext4_new_inode() should have already set the encrypt flag +* on the inode and avoided enabling inline data. +*/ +if (WARN_ON_ONCE (!IS_ENCRYPTED (inode))) +return -EINVAL ; +if (WARN_ON_ONCE (ext4_test_inode_state (inode,EXT4_STATE_MAY_INLINE_DATA ))) +return -EINVAL ; +return ext4_xattr_set_handle (handle, inode, +EXT4_XATTR_INDEX_ENCRYPTION , +EXT4_XATTR_NAME_ENCRYPTION_CONTEXT , + ctx, len,0 ); } res =dquot_initialize (inode);
@@ -1548,10 +1551,7 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len, ctx, len, 0);if (!res) {ext4_set_inode_flag (inode,EXT4_INODE_ENCRYPT ); -/* -* Update inode->i_flags - S_ENCRYPTED will be enabled, -* S_DAX may be disabled -*/ +/* Update inode->i_flags to set S_ENCRYPTED. */ ext4_set_inode_flags (inode, false); res =ext4_mark_inode_dirty (handle, inode);if (res)
fs/jfs/inode.c +1 -1
@@ -385,7 +385,7 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length)ASSERT (length >=0 ); -if (test_cflag (COMMIT_Nolink, ip)) { +if (test_cflag (COMMIT_Nolink, ip) ||isReadOnly (ip)) {xtTruncate (0 , ip, length,COMMIT_WMAP );return ; }
fs/jfs/jfs_extent.c +10 -0
@@ -77,6 +77,11 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)int rc;int xflag; +if (isReadOnly (ip)) { +jfs_error (ip->i_sb,"read-only filesystem\n" ); +return -EIO ; + } +/* This blocks if we are low on resources */ txBeginAnon (ip->i_sb);
@@ -412,6 +417,11 @@ int extRecord(struct inode *ip, xad_t * xp) {int rc; +if (isReadOnly (ip)) { +jfs_error (ip->i_sb,"read-only filesystem\n" ); +return -EIO ; + } +txBeginAnon (ip->i_sb);mutex_lock (&JFS_IP (ip)->commit_mutex);
fs/nilfs2/ioctl.c +19 -2
@@ -544,6 +544,8 @@ static int nilfs_ioctl_get_bdescs(struct inode *inode, struct file *filp,* Return Value: On success, 0 is returned. On error, one of the following * negative error codes is returned. * +* %-EINVAL - Invalid virtual block descriptor. +* * %-EIO - I/O error. * * %-ENOMEM - Insufficient amount of memory available.
@@ -557,15 +559,30 @@ static int nilfs_ioctl_move_inode_block(struct inode *inode, struct list_head *buffers) {struct buffer_head *bh; +__u64 limit_blkidx = (__u64 )inode->i_sb->s_maxbytes >> inode->i_blkbits;int ret; -if (vdesc->vd_flags ==0 ) +/* +* vblocknr 0 is reserved as an invalid pointer. Also, limit_blkidx +* ensures that the page index converted from vd_vblocknr never +* overflows the page cache limit and respects the architecture's bmap +* key width. +*/ +if (unlikely (vdesc->vd_vblocknr ==0 || + vdesc->vd_vblocknr >= limit_blkidx)) +return -EINVAL ; + +if (vdesc->vd_flags ==0 ) { +if (unlikely (vdesc->vd_offset >= limit_blkidx)) +return -EINVAL ; + ret =nilfs_gccache_submit_read_data ( inode, vdesc->vd_offset, vdesc->vd_blocknr, vdesc->vd_vblocknr, &bh); -else + }else { ret =nilfs_gccache_submit_read_node ( inode, vdesc->vd_blocknr, vdesc->vd_vblocknr, &bh); + }if (unlikely (ret <0 )) {if (ret == -ENOENT )
include/linux/hid.h +1 -0
@@ -616,6 +616,7 @@ struct hid_device { /* device report descriptor */__s32 battery_max;__s32 battery_report_type;__s32 battery_report_id; +__s32 battery_report_offset;/* bit offset of the capacity field within its report */ enum hid_battery_status battery_status;bool battery_avoid_query;#endif
include/linux/inetdevice.h +5 -0
@@ -277,6 +277,11 @@ static inline void in_dev_put(struct in_device *idev)#define __in_dev_put (idev) refcount_dec(&(idev)->refcnt)#define in_dev_hold (idev) refcount_inc(&(idev)->refcnt) +static inline bool in_dev_hold_safe (struct in_device *idev) +{ +return refcount_inc_not_zero (&idev->refcnt); +} +#endif /* __KERNEL__ */ static __inline____be32 inet_make_mask (int logmask)
include/linux/sched.h +8 -0
@@ -1295,6 +1295,14 @@ struct task_struct {/* Collect coverage from softirq context: */ unsigned int kcov_softirq; + +/* Temporary storage for preempting remote coverage collection: */ +unsigned int kcov_saved_mode; +unsigned int kcov_saved_size; +void *kcov_saved_area; +struct kcov *kcov_saved_kcov; +int kcov_saved_sequence; +#endif #ifdef CONFIG_MEMCG
include/target/target_core_fabric.h +2 -0
@@ -94,6 +94,8 @@ struct target_core_fabric_ops { struct se_lun *);void (*fabric_pre_unlink)(struct se_portal_group *,struct se_lun *); +void (*fabric_post_unlink)(struct se_portal_group *se_tpg, +struct se_lun *lun);struct se_tpg_np *(*fabric_make_np)(struct se_portal_group *,struct config_group *,const char *);void (*fabric_drop_np)(struct se_tpg_np *);
io_uring/io-wq.c +6 -3
@@ -195,9 +195,12 @@ static void io_worker_cancel_cb(struct io_worker *worker)struct io_wq *wq = wqe->wq;atomic_dec (&acct->nr_running); -raw_spin_lock (&worker->wqe->lock); - acct->nr_workers--; -raw_spin_unlock (&worker->wqe->lock); +/* create_worker_cb() has not reserved a worker slot yet. */ +if (worker->create_work.func != create_worker_cb) { +raw_spin_lock (&worker->wqe->lock); + acct->nr_workers--; +raw_spin_unlock (&worker->wqe->lock); + }io_worker_ref_put (wq);clear_bit_unlock (0 , &worker->create_state);io_worker_release (worker);
kernel/bpf/offload.c +4 -6
@@ -277,9 +277,8 @@ static struct ns_common *bpf_prog_offload_info_fill_ns(void *private_data)if (aux->offload) { args->info->ifindex = aux->offload->netdev->ifindex; - net =dev_net (aux->offload->netdev); -get_net (net); - ns = &net->ns; + net =maybe_get_net (dev_net (aux->offload->netdev)); + ns = net ? &net->ns :NULL ; }else { args->info->ifindex =0 ; ns =NULL ;
@@ -504,9 +503,8 @@ static struct ns_common *bpf_map_offload_info_fill_ns(void *private_data)if (args->offmap->netdev) { args->info->ifindex = args->offmap->netdev->ifindex; - net =dev_net (args->offmap->netdev); -get_net (net); - ns = &net->ns; + net =maybe_get_net (dev_net (args->offmap->netdev)); + ns = net ? &net->ns :NULL ; }else { args->info->ifindex =0 ; ns =NULL ;
kernel/kcov.c +46 -47
170 lines not on this page · raw message
lib/Kconfig.debug +3 -2
@@ -1952,10 +1952,11 @@ config KCOV_INSTRUMENT_ALL config KCOV_IRQ_AREA_SIZE hex "Size of interrupt coverage collection area in words" depends on KCOV + range 0x80 0x1000000 default 0x40000 help - KCOV uses preallocated per-cpu areas to collect coverage from - soft interrupts. This specifies the size of those areas in the + KCOV uses preallocated areas to collect coverage from soft + interrupts. This specifies the size of those areas in the number of unsigned long words. menuconfig RUNTIME_TESTING_MENU
mm/swapfile.c +7 -0
@@ -3234,6 +3234,13 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) error = -EBUSY ; goto bad_swap_unlock_inode; } +if (IS_ENCRYPTED (inode)) { +pr_warn_once ( +"Filesystem-level encrypted swapfile '%s' is unsupported. Create a loop device over it, or use dm-crypt\n" , + name->name); + error = -EINVAL ; + goto bad_swap_unlock_inode; + }/* * Read the swap header.
net/core/filter.c +0 -1
@@ -9920,7 +9920,6 @@ const struct bpf_verifier_ops lwt_seg6local_verifier_ops = { };const struct bpf_prog_ops lwt_seg6local_prog_ops = { - .test_run = bpf_prog_test_run_skb, };const struct bpf_verifier_ops cg_sock_verifier_ops = {
net/ipv4/igmp.c +9 -5
@@ -232,16 +232,20 @@ static void igmp_gq_start_timer(struct in_device *in_dev)return ; in_dev->mr_gq_running =1 ; -if (!mod_timer (&in_dev->mr_gq_timer, exp)) -in_dev_hold (in_dev); +if (in_dev_hold_safe (in_dev)) { +if (mod_timer (&in_dev->mr_gq_timer, exp)) +in_dev_put (in_dev); + } }static void igmp_ifc_start_timer (struct in_device *in_dev,int delay) { -int tv =prandom_u32 () % delay; +if (in_dev_hold_safe (in_dev)) { +int tv =prandom_u32 () % delay; -if (!mod_timer (&in_dev->mr_ifc_timer, jiffies+tv+2 )) -in_dev_hold (in_dev); +if (mod_timer (&in_dev->mr_ifc_timer, jiffies + tv +2 )) +in_dev_put (in_dev); + } }static void igmp_mod_timer (struct ip_mc_list *im,int max_delay)
net/ipv6/ah6.c +18 -11
@@ -238,26 +238,28 @@ static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *des* Rearrange the destination address in @iph and the addresses in @rthdr * so that they appear in the order they will at the final destination. * See Appendix A2 of RFC 2402 for details. +* +* Return: 0 on success, -EINVAL if segments_left exceeds the number of +* addresses described by hdrlen. */ -static void ipv6_rearrange_rthdr (struct ipv6hdr *iph,struct ipv6_rt_hdr *rthdr) +static int ipv6_rearrange_rthdr (struct ipv6hdr *iph,struct ipv6_rt_hdr *rthdr) { -int segments, segments_left; +unsigned int segments, segments_left;struct in6_addr *addrs;struct in6_addr final_addr; segments_left = rthdr->segments_left;if (segments_left ==0 ) -return ; - rthdr->segments_left =0 ; +return 0 ; -/* The value of rthdr->hdrlen has been verified either by the system -* call if it is locally generated, or by ipv6_rthdr_rcv() for incoming -* packets. So we can assume that it is even and that segments is -* greater than or equal to segments_left. -* -* For the same reason we can assume that this option is of type 0. +/* Raw locally generated packets can reach AH6 without the invariant +* required by the rt0-style address rearrangement below. */ segments = rthdr->hdrlen >>1 ; +if (segments_left > segments) +return -EINVAL ; + + rthdr->segments_left =0 ; addrs = ((struct rt0_hdr *)rthdr)->addr; final_addr = addrs[segments -1 ];
@@ -267,6 +269,8 @@ static void ipv6_rearrange_rthdr(struct ipv6hdr *iph, struct ipv6_rt_hdr *rthdr) addrs[0 ] = iph->daddr; iph->daddr = final_addr; + +return 0 ; }static int ipv6_clear_mutable_options (struct ipv6hdr *iph,int len,int dir)
@@ -279,6 +283,7 @@ static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir) } exthdr = { .iph = iph };char *end = exthdr.raw + len;int nexthdr = iph->nexthdr; +int err; exthdr.iph++;
@@ -298,7 +303,9 @@ static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir)break ;case NEXTHDR_ROUTING : -ipv6_rearrange_rthdr (iph, exthdr.rth); + err =ipv6_rearrange_rthdr (iph, exthdr.rth); +if (err) +return err;break ;default :
net/ipv6/mcast.c +4 -4
@@ -1414,9 +1414,9 @@ void igmp6_event_query(struct sk_buff *skb)static void __mld_query_work (struct sk_buff *skb) {struct mld2_query *mlh2 =NULL ; -const struct in6_addr *group;unsigned long max_delay;struct inet6_dev *idev; +struct in6_addr group;struct ifmcaddr6 *ma;struct mld_msg *mld;int group_type;
@@ -1448,8 +1448,8 @@ static void __mld_query_work(struct sk_buff *skb) goto kfree_skb; mld = (struct mld_msg *)icmp6_hdr (skb); - group = &mld->mld_mca; - group_type =ipv6_addr_type (group); + group = mld->mld_mca; + group_type =ipv6_addr_type (&group);if (group_type !=IPV6_ADDR_ANY && !(group_type&IPV6_ADDR_MULTICAST ))
@@ -1501,7 +1501,7 @@ static void __mld_query_work(struct sk_buff *skb) } }else {for_each_mc_mclock (idev, ma) { -if (!ipv6_addr_equal (group, &ma->mca_addr)) +if (!ipv6_addr_equal (&group, &ma->mca_addr))continue ;if (ma->mca_flags &MAF_TIMER_RUNNING ) {/* gsquery <- gsquery && mark */
net/ipv6/seg6_local.c +7 -0
@@ -139,6 +139,13 @@ static bool decap_and_validate(struct sk_buff *skb, int proto)if (iptunnel_pull_offloads (skb))return false; +if (proto ==IPPROTO_IPIP ) { +int iif =IP6CB (skb)->iif; + +memset (IPCB (skb),0 ,sizeof (*IPCB (skb))); +IPCB (skb)->iif = iif; + } +return true; }
net/netfilter/ipvs/ip_vs_xmit.c +2 -4
@@ -718,15 +718,13 @@ int ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp, struct ip_vs_iphdr *ipvsh) { - struct iphdr *iph = ip_hdr(skb); - EnterFunction(10); -if (__ip_vs_get_out_rt (cp->ipvs, cp->af, skb,NULL , iph->daddr, +if (__ip_vs_get_out_rt (cp->ipvs, cp->af, skb,NULL ,ip_hdr (skb)->daddr,IP_VS_RT_MODE_NON_LOCAL ,NULL , ipvsh) <0 ) goto tx_error; -ip_send_check (iph); +ip_send_check (ip_hdr (skb));/* Another hack: avoid icmp_send in ip_fragment */ skb->ignore_df =1 ;
net/nfc/nci/ntf.c +26 -6
@@ -310,7 +310,7 @@ void nci_clear_target_list(struct nci_dev *ndev)static void nci_rf_discover_ntf_packet (struct nci_dev *ndev,struct sk_buff *skb) { -struct nci_rf_discover_ntf ntf; +struct nci_rf_discover_ntf ntf = {};__u8 *data = skb->data;bool add_target = true;
@@ -371,15 +371,20 @@ static void nci_rf_discover_ntf_packet(struct nci_dev *ndev, }static int nci_extract_activation_params_iso_dep (struct nci_dev *ndev, -struct nci_rf_intf_activated_ntf *ntf,__u8 *data) +struct nci_rf_intf_activated_ntf *ntf,__u8 *data, +__u8 data_len) {struct activation_params_nfca_poll_iso_dep *nfca_poll;struct activation_params_nfcb_poll_iso_dep *nfcb_poll;switch (ntf->activation_rf_tech_and_mode) {case NCI_NFC_A_PASSIVE_POLL_MODE : +if (data_len <1 ) +return NCI_STATUS_RF_PROTOCOL_ERROR ; nfca_poll = &ntf->activation_params.nfca_poll_iso_dep; nfca_poll->rats_res_len =min_t (__u8, *data++,20 ); + data_len--; + nfca_poll->rats_res_len =min_t (__u8, nfca_poll->rats_res_len, data_len);pr_debug ("rats_res_len %d\n" , nfca_poll->rats_res_len);if (nfca_poll->rats_res_len >0 ) { memcpy(nfca_poll->rats_res,
@@ -388,8 +393,12 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev,break ;case NCI_NFC_B_PASSIVE_POLL_MODE : +if (data_len <1 ) +return NCI_STATUS_RF_PROTOCOL_ERROR ; nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep; nfcb_poll->attrib_res_len =min_t (__u8, *data++,50 ); + data_len--; + nfcb_poll->attrib_res_len =min_t (__u8, nfcb_poll->attrib_res_len, data_len);pr_debug ("attrib_res_len %d\n" , nfcb_poll->attrib_res_len);if (nfcb_poll->attrib_res_len >0 ) { memcpy(nfcb_poll->attrib_res,
@@ -407,7 +416,8 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, }static int nci_extract_activation_params_nfc_dep (struct nci_dev *ndev, -struct nci_rf_intf_activated_ntf *ntf,__u8 *data) +struct nci_rf_intf_activated_ntf *ntf,__u8 *data, +__u8 data_len) {struct activation_params_poll_nfc_dep *poll;struct activation_params_listen_nfc_dep *listen;
@@ -415,9 +425,13 @@ static int nci_extract_activation_params_nfc_dep(struct nci_dev *ndev,switch (ntf->activation_rf_tech_and_mode) {case NCI_NFC_A_PASSIVE_POLL_MODE :case NCI_NFC_F_PASSIVE_POLL_MODE : +if (data_len <1 ) +return NCI_STATUS_RF_PROTOCOL_ERROR ; poll = &ntf->activation_params.poll_nfc_dep; poll->atr_res_len =min_t (__u8, *data++,NFC_ATR_RES_MAXSIZE -2 ); + data_len--; + poll->atr_res_len =min_t (__u8, poll->atr_res_len, data_len);pr_debug ("atr_res_len %d\n" , poll->atr_res_len);if (poll->atr_res_len >0 )memcpy (poll->atr_res, data, poll->atr_res_len);
@@ -425,9 +439,13 @@ static int nci_extract_activation_params_nfc_dep(struct nci_dev *ndev,case NCI_NFC_A_PASSIVE_LISTEN_MODE :case NCI_NFC_F_PASSIVE_LISTEN_MODE : +if (data_len <1 ) +return NCI_STATUS_RF_PROTOCOL_ERROR ; listen = &ntf->activation_params.listen_nfc_dep; listen->atr_req_len =min_t (__u8, *data++,NFC_ATR_REQ_MAXSIZE -2 ); + data_len--; + listen->atr_req_len =min_t (__u8, listen->atr_req_len, data_len);pr_debug ("atr_req_len %d\n" , listen->atr_req_len);if (listen->atr_req_len >0 )memcpy (listen->atr_req, data, listen->atr_req_len);
@@ -517,7 +535,7 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb) {struct nci_conn_info *conn_info; -struct nci_rf_intf_activated_ntf ntf; +struct nci_rf_intf_activated_ntf ntf = {};__u8 *data = skb->data;int err =NCI_STATUS_OK ;
@@ -603,12 +621,14 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,switch (ntf.rf_interface) {case NCI_RF_INTERFACE_ISO_DEP : err =nci_extract_activation_params_iso_dep (ndev, - &ntf, data); + &ntf, data, + ntf.activation_params_len);break ;case NCI_RF_INTERFACE_NFC_DEP : err =nci_extract_activation_params_nfc_dep (ndev, - &ntf, data); + &ntf, data, + ntf.activation_params_len);break ;case NCI_RF_INTERFACE_FRAME :
net/xfrm/espintcp.c +8 -1
@@ -38,6 +38,11 @@ static void handle_esp(struct sk_buff *skb, struct sock *sk)rcu_read_lock (); skb->dev =dev_get_by_index_rcu (sock_net (sk), skb->skb_iif); +if (!skb->dev) { +XFRM_INC_STATS (sock_net (sk),LINUX_MIB_XFRMINERROR ); +kfree_skb (skb); + goto out; + }local_bh_disable ();#if IS_ENABLED (CONFIG_IPV6 )if (sk->sk_family ==AF_INET6 )
@@ -46,6 +51,7 @@ static void handle_esp(struct sk_buff *skb, struct sock *sk)#endif xfrm4_rcv_encap (skb,IPPROTO_ESP ,0 ,TCP_ENCAP_ESPINTCP );local_bh_enable (); +out:rcu_read_unlock (); }
@@ -506,7 +512,8 @@ static void espintcp_close(struct sock *sk, long timeout)strp_stop (&ctx->strp); sk->sk_prot = &tcp_prot; -barrier (); + +synchronize_rcu ();cancel_work_sync (&ctx->work);strp_done (&ctx->strp);
net/xfrm/xfrm_user.c +1 -1
@@ -614,7 +614,7 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,if ((err =attach_auth_trunc (&x->aalg, &x->props.aalgo, attrs[XFRMA_ALG_AUTH_TRUNC ]))) goto error; -if (!x->props.aalgo) { +if (!x->aalg) {if ((err =attach_auth (&x->aalg, &x->props.aalgo, attrs[XFRMA_ALG_AUTH ]))) goto error;
security/selinux/ss/conditional.c +6 -6
@@ -166,9 +166,9 @@ void cond_policydb_destroy(struct policydb *p)int cond_init_bool_indexes (struct policydb *p) {kfree (p->bool_val_to_struct); - p->bool_val_to_struct =kmalloc_array (p->p_bools.nprim, -sizeof (*p->bool_val_to_struct), -GFP_KERNEL ); + p->bool_val_to_struct =kcalloc (p->p_bools.nprim, +sizeof (*p->bool_val_to_struct), +GFP_KERNEL );if (!p->bool_val_to_struct)return -ENOMEM ;return 0 ;
@@ -714,9 +714,9 @@ static int duplicate_policydb_bools(struct policydb *newdb,struct cond_bool_datum **cond_bool_array;int rc; - cond_bool_array =kmalloc_array (orig->p_bools.nprim, -sizeof (*orig->bool_val_to_struct), -GFP_KERNEL ); + cond_bool_array =kcalloc (orig->p_bools.nprim, +sizeof (*orig->bool_val_to_struct), +GFP_KERNEL );if (!cond_bool_array)return -ENOMEM ;
sound/usb/midi.c +2 -0
@@ -894,6 +894,8 @@ static void snd_usbmidi_novation_output(struct snd_usb_midi_out_endpoint *ep,if (!ep->ports[0 ].active)return ; +if (ep->max_transfer <3 ) +return ; transfer_buffer = urb->transfer_buffer; count = snd_rawmidi_transmit(ep->ports[0].substream, &transfer_buffer[2],