diff --git a/CVE.md b/CVE.md new file mode 100644 index 00000000000..8cab40f9041 --- /dev/null +++ b/CVE.md @@ -0,0 +1,72 @@ +| ID | STATUS/COMMIT | +|------------------|------------------------------------------| +| CVE-2010-5321 | no patch available | +| CVE-2014-9410 | not affected | +| CVE-2015-0568 | not affected | +| CVE-2015-0569 | not affected | +| CVE-2015-0570 | not affected | +| CVE-2015-0571 | not affected | +| CVE-2015-0572 | not affected | +| CVE-2015-0573 | not affected | +| CVE-2015-1350 | not affected | +| CVE-2015-2877 | no patch available | +| CVE-2016-2059 | not affected | +| CVE-2016-2061 | not affected | +| CVE-2016-2062 | not affected | +| CVE-2016-2063 | not affected | +| CVE-2016-2064 | not affected | +| CVE-2016-2065 | not affected | +| CVE-2016-2066 | not affected | +| CVE-2016-2067 | not affected | +| CVE-2016-2068 | not affected | +| CVE-2016-5340 | not affected | +| CVE-2016-5342 | not affected | +| CVE-2016-5343 | not affected | +| CVE-2016-5344 | not affected | +| CVE-2016-5870 | not affected | +| CVE-2017-1000251 | not affected | +| CVE-2017-1000405 | not affected | +| CVE-2017-1000407 | not affected | +| CVE-2017-1000410 | 06e7e776ca4d36547e503279aeff996cbb292c16 | +| CVE-2017-12193 | not affected | +| CVE-2017-15102 | 2fae9e5a7babada041e2e161699ade2447a01989 | +| CVE-2017-15115 | df80cd9b28b9ebaa284a41df611dbf3a2d05ca74 | +| CVE-2017-15116 | not affected | +| CVE-2017-15127 | not affected | +| CVE-2017-15129 | not affected | +| CVE-2017-15868 | 71bb99a02b32b4cc4265118e85f6035ca72923f0 | +| CVE-2017-16939 | open | +| CVE-2017-16994 | 373c4557d2aa362702c4c2d41288fb1e54990b7c | +| CVE-2017-17052 | 2b7e8665b4ff51c034c55df3cff76518d1a9ee3a | +| CVE-2017-17053 | not affected | +| CVE-2017-17805 | ecaaab5649781c5a0effdaf298a925063020500e | +| CVE-2017-17806 | af3ff8045bbf3e32f1a448542e73abb4c8ceb6f1 | +| CVE-2017-17807 | 4dca6ea1d9432052afb06baf2e3ae78188a4410b | +| CVE-2017-18075 | not affected | +| CVE-2017-18079 | 340d394a789518018f834ff70f7534fc463d3226 | +| CVE-2017-18174 | not affected | +| CVE-2017-18193 | not affected | +| CVE-2017-18203 | b9a41d21dceadf8104812626ef85dc56ee8a60ed | +| CVE-2017-18204 | 28f5a8a7c033cbf3e32277f4cc9c6afd74f05300 | +| CVE-2017-18208 | 6ea8d958a2c95a1d514015d4e29ba21a8c0a1a91 | +| CVE-2017-18216 | 853bc26a7ea39e354b9f8889ae7ad1492ffa28d2 | +| CVE-2017-18218 | not affected | +| CVE-2017-18224 | not affected | +| CVE-2017-18241 | d4fdf8ba0e5808ba9ad6b44337783bd9935e0982 | +| CVE-2017-18255 | 1572e45a924f254d9570093abde46430c3172e3d | +| CVE-2017-18257 | b86e33075ed1909d8002745b56ecf73b833db143 | +| CVE-2017-18261 | not affected | +| CVE-2017-18270 | open | +| CVE-2017-5972 | not affected | +| CVE-2018-10021 | 318aaf34f1179b39fa9c30fa0f3288b645beee39 | +| CVE-2018-10074 | dd83c161fbcc5d8be637ab159c0de015cbff5ba4 | +| CVE-2018-10087 | not affected | +| CVE-2018-10124 | 4ea77014af0d6205b05503d1c7aac6eace11d473 | +| CVE-2018-10675 | 73223e4e2e3867ebf033a5a8eb2e5df0158ccc99 | +| CVE-2018-10940 | not affected | +| CVE-2018-11232 | not affected | +| CVE-2018-1130 | 67f93df79aeefc3add4e4b31a752600f834236e2 | +| CVE-2018-11508 | not affected | +| CVE-2018-6927 | fbe0e839d1e22d88810f3ee3e2f1479be4c0aa4a | +| CVE-2018-7480 | not affected | +| CVE-2018-8781 | 3b82a4db8eaccce735dffd50b4d4e1578099b8e8 | diff --git a/arch/arm/configs/kminilte_00_defconfig b/arch/arm/configs/kminilte_00_defconfig index db066d1181f..892f77855c0 100755 --- a/arch/arm/configs/kminilte_00_defconfig +++ b/arch/arm/configs/kminilte_00_defconfig @@ -40,7 +40,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_CROSS_COMPILE="" CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCALVERSION_AUTO=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_LZMA=y CONFIG_HAVE_KERNEL_XZ=y diff --git a/arch/x86/crypto/salsa20_glue.c b/arch/x86/crypto/salsa20_glue.c index bccb76d8098..b36ade32aad 100644 --- a/arch/x86/crypto/salsa20_glue.c +++ b/arch/x86/crypto/salsa20_glue.c @@ -64,13 +64,6 @@ static int encrypt(struct blkcipher_desc *desc, salsa20_ivsetup(ctx, walk.iv); - if (likely(walk.nbytes == nbytes)) - { - salsa20_encrypt_bytes(ctx, walk.src.virt.addr, - walk.dst.virt.addr, nbytes); - return blkcipher_walk_done(desc, &walk, 0); - } - while (walk.nbytes >= 64) { salsa20_encrypt_bytes(ctx, walk.src.virt.addr, walk.dst.virt.addr, diff --git a/crypto/hmac.c b/crypto/hmac.c index 8d9544cf816..e736186b0a3 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -197,11 +197,15 @@ static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb) salg = shash_attr_alg(tb[1], 0, 0); if (IS_ERR(salg)) return PTR_ERR(salg); + alg = &salg->base; + /* The underlying hash algorithm must be unkeyed */ err = -EINVAL; + if (crypto_shash_alg_has_setkey(salg)) + goto out_put_alg; + ds = salg->digestsize; ss = salg->statesize; - alg = &salg->base; if (ds > alg->cra_blocksize || ss < alg->cra_blocksize) goto out_put_alg; diff --git a/crypto/salsa20_generic.c b/crypto/salsa20_generic.c index eac10c11685..7b176bd6386 100644 --- a/crypto/salsa20_generic.c +++ b/crypto/salsa20_generic.c @@ -188,13 +188,6 @@ static int encrypt(struct blkcipher_desc *desc, salsa20_ivsetup(ctx, walk.iv); - if (likely(walk.nbytes == nbytes)) - { - salsa20_encrypt_bytes(ctx, walk.dst.virt.addr, - walk.src.virt.addr, nbytes); - return blkcipher_walk_done(desc, &walk, 0); - } - while (walk.nbytes >= 64) { salsa20_encrypt_bytes(ctx, walk.dst.virt.addr, walk.src.virt.addr, diff --git a/crypto/shash.c b/crypto/shash.c index e49e79f472a..2e71dac1f58 100644 --- a/crypto/shash.c +++ b/crypto/shash.c @@ -24,11 +24,12 @@ static const struct crypto_type crypto_shash_type; -static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, - unsigned int keylen) +int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, + unsigned int keylen) { return -ENOSYS; } +EXPORT_SYMBOL_GPL(shash_no_setkey); static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key, unsigned int keylen) diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index f02d223d394..6f46c6003c3 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -247,10 +247,15 @@ static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) { unsigned long start = vma->vm_start; unsigned long size = vma->vm_end - vma->vm_start; - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + unsigned long offset; unsigned long page, pos; - if (offset + size > info->fix.smem_len) + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) + return -EINVAL; + + offset = vma->vm_pgoff << PAGE_SHIFT; + + if (offset > info->fix.smem_len || size > info->fix.smem_len - offset) return -EINVAL; pos = (unsigned long)info->fix.smem_start + offset; diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 178e75d6bb0..75ced2ff155 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -390,8 +390,10 @@ static int i8042_start(struct serio *serio) { struct i8042_port *port = serio->port_data; + spin_lock_irq(&i8042_lock); port->exists = true; - mb(); + spin_unlock_irq(&i8042_lock); + return 0; } @@ -404,16 +406,20 @@ static void i8042_stop(struct serio *serio) { struct i8042_port *port = serio->port_data; + spin_lock_irq(&i8042_lock); port->exists = false; + port->serio = NULL; + spin_unlock_irq(&i8042_lock); /* + * We need to make sure that interrupt handler finishes using + * our serio port before we return from this function. * We synchronize with both AUX and KBD IRQs because there is * a (very unlikely) chance that AUX IRQ is raised for KBD port * and vice versa. */ synchronize_irq(I8042_AUX_IRQ); synchronize_irq(I8042_KBD_IRQ); - port->serio = NULL; } /* @@ -530,7 +536,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) spin_unlock_irqrestore(&i8042_lock, flags); - if (likely(port->exists && !filtered)) + if (likely(serio && !filtered)) serio_interrupt(serio, data, dfl); out: diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 3bfbccc3f0a..1cf0e087927 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -2691,11 +2691,15 @@ struct mapped_device *dm_get_from_kobject(struct kobject *kobj) md = container_of(kobj, struct mapped_device, kobj_holder.kobj); - if (test_bit(DMF_FREEING, &md->flags) || - dm_deleting_md(md)) - return NULL; - + spin_lock(&_minor_lock); + if (test_bit(DMF_FREEING, &md->flags) || dm_deleting_md(md)) { + md = NULL; + goto out; + } dm_get(md); +out: + spin_unlock(&_minor_lock); + return md; } diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index f0b9b7bf188..e50fe3aad7a 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -250,6 +250,7 @@ int sas_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) { struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host); + struct domain_device *dev = cmd_to_domain_dev(cmd); struct sas_task *task = TO_SAS_TASK(cmd); /* At this point, we only get called following an actual abort @@ -258,6 +259,14 @@ static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) */ sas_end_task(cmd, task); + if (dev_is_sata(dev)) { + /* defer commands to libata so that libata EH can + * handle ata qcs correctly + */ + list_move_tail(&cmd->eh_entry, &sas_ha->eh_ata_q); + return; + } + /* now finish the command and move it on to the error * handler done list, this also takes it off the * error handler pending list. @@ -265,22 +274,6 @@ static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q); } -static void sas_eh_defer_cmd(struct scsi_cmnd *cmd) -{ - struct domain_device *dev = cmd_to_domain_dev(cmd); - struct sas_ha_struct *ha = dev->port->ha; - struct sas_task *task = TO_SAS_TASK(cmd); - - if (!dev_is_sata(dev)) { - sas_eh_finish_cmd(cmd); - return; - } - - /* report the timeout to libata */ - sas_end_task(cmd, task); - list_move_tail(&cmd->eh_entry, &ha->eh_ata_q); -} - static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd) { struct scsi_cmnd *cmd, *n; @@ -288,7 +281,7 @@ static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd list_for_each_entry_safe(cmd, n, error_q, eh_entry) { if (cmd->device->sdev_target == my_cmd->device->sdev_target && cmd->device->lun == my_cmd->device->lun) - sas_eh_defer_cmd(cmd); + sas_eh_finish_cmd(cmd); } } @@ -581,12 +574,12 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head * case TASK_IS_DONE: SAS_DPRINTK("%s: task 0x%p is done\n", __func__, task); - sas_eh_defer_cmd(cmd); + sas_eh_finish_cmd(cmd); continue; case TASK_IS_ABORTED: SAS_DPRINTK("%s: task 0x%p is aborted\n", __func__, task); - sas_eh_defer_cmd(cmd); + sas_eh_finish_cmd(cmd); continue; case TASK_IS_AT_LU: SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task); @@ -597,7 +590,7 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head * "recovered\n", SAS_ADDR(task->dev), cmd->device->lun); - sas_eh_defer_cmd(cmd); + sas_eh_finish_cmd(cmd); sas_scsi_clear_queue_lu(work_q, cmd); goto Again; } diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 57522204276..c444d68e3fb 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -951,24 +951,6 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device dev->interrupt_in_interval = interrupt_in_interval ? interrupt_in_interval : dev->interrupt_in_endpoint->bInterval; dev->interrupt_out_interval = interrupt_out_interval ? interrupt_out_interval : dev->interrupt_out_endpoint->bInterval; - /* we can register the device now, as it is ready */ - usb_set_intfdata (interface, dev); - - retval = usb_register_dev (interface, &tower_class); - - if (retval) { - /* something prevented us from registering this driver */ - err ("Not able to get a minor for this device."); - usb_set_intfdata (interface, NULL); - goto error; - } - dev->minor = interface->minor; - - /* let the user know what node this device is now attached to */ - dev_info(&interface->dev, "LEGO USB Tower #%d now attached to major " - "%d minor %d\n", (dev->minor - LEGO_USB_TOWER_MINOR_BASE), - USB_MAJOR, dev->minor); - /* get the firmware version and log it */ result = usb_control_msg (udev, usb_rcvctrlpipe(udev, 0), @@ -989,6 +971,23 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device get_version_reply.minor, le16_to_cpu(get_version_reply.build_no)); + /* we can register the device now, as it is ready */ + usb_set_intfdata (interface, dev); + + retval = usb_register_dev (interface, &tower_class); + + if (retval) { + /* something prevented us from registering this driver */ + err ("Not able to get a minor for this device."); + usb_set_intfdata (interface, NULL); + goto error; + } + dev->minor = interface->minor; + + /* let the user know what node this device is now attached to */ + dev_info(&interface->dev, "LEGO USB Tower #%d now attached to major " + "%d minor %d\n", (dev->minor - LEGO_USB_TOWER_MINOR_BASE), + USB_MAJOR, dev->minor); exit: dbg(2, "%s: leave, return value 0x%.8lx (dev)", __func__, (long) dev); diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index c192e5737c3..15ac4a89a31 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -722,7 +722,7 @@ static int __get_data_block(struct inode *inode, sector_t iblock, if (!ret) { map_bh(bh, inode->i_sb, map.m_pblk); bh->b_state = (bh->b_state & ~F2FS_MAP_FLAGS) | map.m_flags; - bh->b_size = map.m_len << inode->i_blkbits; + bh->b_size = (u64)map.m_len << inode->i_blkbits; } return ret; } diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 9ea731ab6ed..022f2c6cde4 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -488,6 +488,9 @@ int create_flush_cmd_control(struct f2fs_sb_info *sbi) init_waitqueue_head(&fcc->flush_wait_queue); init_llist_head(&fcc->issue_list); SM_I(sbi)->cmd_control_info = fcc; + if (!test_opt(sbi, FLUSH_MERGE)) + return err; + fcc->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi, "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev)); if (IS_ERR(fcc->f2fs_issue_flush)) { @@ -2386,7 +2389,7 @@ int build_segment_manager(struct f2fs_sb_info *sbi) INIT_LIST_HEAD(&sm_info->sit_entry_set); - if (test_opt(sbi, FLUSH_MERGE) && !f2fs_readonly(sbi->sb)) { + if (!f2fs_readonly(sbi->sb)) { err = create_flush_cmd_control(sbi); if (err) return err; diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c index bb240647ca5..a27c6fd2d21 100644 --- a/fs/ocfs2/cluster/nodemanager.c +++ b/fs/ocfs2/cluster/nodemanager.c @@ -41,6 +41,9 @@ char *o2nm_fence_method_desc[O2NM_FENCE_METHODS] = { "panic", /* O2NM_FENCE_PANIC */ }; +static inline void o2nm_lock_subsystem(void); +static inline void o2nm_unlock_subsystem(void); + struct o2nm_node *o2nm_get_node_by_num(u8 node_num) { struct o2nm_node *node = NULL; @@ -182,7 +185,10 @@ static struct o2nm_cluster *to_o2nm_cluster_from_node(struct o2nm_node *node) { /* through the first node_set .parent * mycluster/nodes/mynode == o2nm_cluster->o2nm_node_group->o2nm_node */ - return to_o2nm_cluster(node->nd_item.ci_parent->ci_parent); + if (node->nd_item.ci_parent) + return to_o2nm_cluster(node->nd_item.ci_parent->ci_parent); + else + return NULL; } enum { @@ -195,7 +201,8 @@ enum { static ssize_t o2nm_node_num_write(struct o2nm_node *node, const char *page, size_t count) { - struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node); + struct o2nm_node *node = to_o2nm_node(item); + struct o2nm_cluster *cluster; unsigned long tmp; char *p = (char *)page; @@ -214,6 +221,13 @@ static ssize_t o2nm_node_num_write(struct o2nm_node *node, const char *page, !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes)) return -EINVAL; /* XXX */ + o2nm_lock_subsystem(); + cluster = to_o2nm_cluster_from_node(node); + if (!cluster) { + o2nm_unlock_subsystem(); + return -EINVAL; + } + write_lock(&cluster->cl_nodes_lock); if (cluster->cl_nodes[tmp]) p = NULL; @@ -223,6 +237,8 @@ static ssize_t o2nm_node_num_write(struct o2nm_node *node, const char *page, set_bit(tmp, cluster->cl_nodes_bitmap); } write_unlock(&cluster->cl_nodes_lock); + o2nm_unlock_subsystem(); + if (p == NULL) return -EEXIST; @@ -262,7 +278,8 @@ static ssize_t o2nm_node_ipv4_address_write(struct o2nm_node *node, const char *page, size_t count) { - struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node); + struct o2nm_node *node = to_o2nm_node(item); + struct o2nm_cluster *cluster; int ret, i; struct rb_node **p, *parent; unsigned int octets[4]; @@ -279,6 +296,13 @@ static ssize_t o2nm_node_ipv4_address_write(struct o2nm_node *node, be32_add_cpu(&ipv4_addr, octets[i] << (i * 8)); } + o2nm_lock_subsystem(); + cluster = to_o2nm_cluster_from_node(node); + if (!cluster) { + o2nm_unlock_subsystem(); + return -EINVAL; + } + ret = 0; write_lock(&cluster->cl_nodes_lock); if (o2nm_node_ip_tree_lookup(cluster, ipv4_addr, &p, &parent)) @@ -288,6 +312,8 @@ static ssize_t o2nm_node_ipv4_address_write(struct o2nm_node *node, rb_insert_color(&node->nd_ip_node, &cluster->cl_node_ip_tree); } write_unlock(&cluster->cl_nodes_lock); + o2nm_unlock_subsystem(); + if (ret) return ret; @@ -304,7 +330,8 @@ static ssize_t o2nm_node_local_read(struct o2nm_node *node, char *page) static ssize_t o2nm_node_local_write(struct o2nm_node *node, const char *page, size_t count) { - struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node); + struct o2nm_node *node = to_o2nm_node(item); + struct o2nm_cluster *cluster; unsigned long tmp; char *p = (char *)page; ssize_t ret; @@ -322,17 +349,26 @@ static ssize_t o2nm_node_local_write(struct o2nm_node *node, const char *page, !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes)) return -EINVAL; /* XXX */ + o2nm_lock_subsystem(); + cluster = to_o2nm_cluster_from_node(node); + if (!cluster) { + ret = -EINVAL; + goto out; + } + /* the only failure case is trying to set a new local node * when a different one is already set */ if (tmp && tmp == cluster->cl_has_local && - cluster->cl_local_node != node->nd_num) - return -EBUSY; + cluster->cl_local_node != node->nd_num) { + ret = -EBUSY; + goto out; + } /* bring up the rx thread if we're setting the new local node. */ if (tmp && !cluster->cl_has_local) { ret = o2net_start_listening(node); if (ret) - return ret; + goto out; } if (!tmp && cluster->cl_has_local && @@ -347,7 +383,11 @@ static ssize_t o2nm_node_local_write(struct o2nm_node *node, const char *page, cluster->cl_local_node = node->nd_num; } - return count; + ret = count; + +out: + o2nm_unlock_subsystem(); + return ret; } struct o2nm_node_attribute { @@ -890,6 +930,16 @@ static struct o2nm_cluster_group o2nm_cluster_group = { }, }; +static inline void o2nm_lock_subsystem(void) +{ + mutex_lock(&o2nm_cluster_group.cs_subsys.su_mutex); +} + +static inline void o2nm_unlock_subsystem(void) +{ + mutex_unlock(&o2nm_cluster_group.cs_subsys.su_mutex); +} + int o2nm_depend_item(struct config_item *item) { return configfs_depend_item(&o2nm_cluster_group.cs_subsys, item); diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index dc799343e82..9f0a308adf7 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1135,6 +1135,13 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) dquot_initialize(inode); size_change = S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_SIZE; if (size_change) { + /* + * Here we should wait dio to finish before inode lock + * to avoid a deadlock between ocfs2_setattr() and + * ocfs2_dio_end_io_write() + */ + inode_dio_wait(inode); + status = ocfs2_rw_lock(inode, 1); if (status < 0) { mlog_errno(status); @@ -1154,8 +1161,6 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) if (status) goto bail_unlock; - inode_dio_wait(inode); - if (i_size_read(inode) > attr->ia_size) { if (ocfs2_should_order_data(inode)) { status = ocfs2_begin_ordered_truncate(inode, diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index 821eae8cbd8..0af57a99c6a 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h @@ -70,6 +70,14 @@ int ahash_register_instance(struct crypto_template *tmpl, struct ahash_instance *inst); void ahash_free_instance(struct crypto_instance *inst); +int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, + unsigned int keylen); + +static inline bool crypto_shash_alg_has_setkey(struct shash_alg *alg) +{ + return alg->setkey != shash_no_setkey; +} + int crypto_init_ahash_spawn(struct crypto_ahash_spawn *spawn, struct hash_alg_common *alg, struct crypto_instance *inst); diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 9b242c6bf55..abef3c02d2d 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -845,6 +845,7 @@ extern bool disable_ertm; int l2cap_init_sockets(void); void l2cap_cleanup_sockets(void); +bool l2cap_is_socket(struct socket *sock); void __l2cap_connect_rsp_defer(struct l2cap_chan *chan); int __l2cap_wait_ack(struct sock *sk); diff --git a/kernel/events/core.c b/kernel/events/core.c index ca01aaa372a..a881a5bd55f 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -177,7 +177,7 @@ int perf_proc_update_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - int ret = proc_dointvec(table, write, buffer, lenp, ppos); + int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); if (ret || !write) return ret; diff --git a/kernel/exit.c b/kernel/exit.c index f6ecc38f96b..d52e844a77f 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1849,6 +1849,10 @@ SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr, __WNOTHREAD|__WCLONE|__WALL)) return -EINVAL; + /* -INT_MIN is not defined */ + if (upid == INT_MIN) + return -ESRCH; + if (upid == -1) type = PIDTYPE_MAX; else if (upid < 0) { diff --git a/kernel/fork.c b/kernel/fork.c index 6df9920954c..55820396fec 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -532,7 +532,8 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p) mm->cached_hole_size = ~0UL; mm_init_aio(mm); mm_init_owner(mm, p); - + RCU_INIT_POINTER(mm->exe_file, NULL); + if (likely(!mm_alloc_pgd(mm))) { mm->def_flags = 0; mmu_notifier_mm_init(mm); diff --git a/kernel/futex.c b/kernel/futex.c index 6b320c2ad6f..cad012e10c8 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -1258,7 +1258,8 @@ void requeue_futex(struct futex_q *q, struct futex_hash_bucket *hb1, * @key: the key of the requeue target futex * @hb: the hash_bucket of the requeue target futex * - * During futex_requeue, with requeue_pi=1, it is possible to acquire the + * During + , with requeue_pi=1, it is possible to acquire the * target futex if it is uncontended or via a lock steal. Set the futex_q key * to the requeue target futex so the waiter can detect the wakeup on the right * futex, but remove it from the hb and NULL the rt_waiter so it can detect @@ -1378,6 +1379,9 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, struct plist_head *head1; struct futex_q *this, *next; + if (nr_wake < 0 || nr_requeue < 0) + return -EINVAL; + if (requeue_pi) { /* * Requeue PI only works on two distinct uaddrs. This diff --git a/kernel/signal.c b/kernel/signal.c index 803a573581b..7a2cfd783ad 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1448,6 +1448,10 @@ static int kill_something_info(int sig, struct siginfo *info, pid_t pid) return ret; } + /* -INT_MIN is undefined. Exclude this case to avoid a UBSAN warning */ + if (pid == INT_MIN) + return -ESRCH; + read_lock(&tasklist_lock); if (pid != -1) { ret = __kill_pgrp_info(sig, info, diff --git a/mm/madvise.c b/mm/madvise.c index b075d1d1f6c..d7fd5553b7a 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -135,6 +135,7 @@ static long madvise_willneed(struct vm_area_struct * vma, { struct file *file = vma->vm_file; + *prev = vma; if (!file) return -EBADF; @@ -143,7 +144,6 @@ static long madvise_willneed(struct vm_area_struct * vma, return 0; } - *prev = vma; start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; if (end > vma->vm_end) end = vma->vm_end; diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 82c62421a20..bba47aa7552 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -887,11 +887,6 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask, *policy |= (pol->flags & MPOL_MODE_FLAGS); } - if (vma) { - up_read(¤t->mm->mmap_sem); - vma = NULL; - } - err = 0; if (nmask) { if (mpol_store_user_nodemask(pol)) { diff --git a/mm/pagewalk.c b/mm/pagewalk.c index 1090e772a26..4d89655ed41 100644 --- a/mm/pagewalk.c +++ b/mm/pagewalk.c @@ -118,8 +118,11 @@ static int walk_hugetlb_range(struct vm_area_struct *vma, do { next = hugetlb_entry_end(h, addr, end); pte = huge_pte_offset(walk->mm, addr & hmask); - if (pte && walk->hugetlb_entry) + if (pte) err = walk->hugetlb_entry(pte, hmask, addr, next, walk); + else if (walk->pte_hole) + err = walk->pte_hole(addr, next, walk); + if (err) return err; } while (addr = next, addr != end); diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index a779ec70332..d2e4c8f18b8 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -558,6 +558,9 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) BT_DBG(""); + if (!l2cap_is_socket(sock)) + return -EBADFD; + baswap((void *) dst, &bt_sk(sock->sk)->dst); baswap((void *) src, &bt_sk(sock->sk)->src); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 552bdbe0b70..47173948ed9 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2266,9 +2266,10 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) break; case L2CAP_CONF_EFS: - remote_efs = 1; - if (olen == sizeof(efs)) + if (olen == sizeof(efs)) { + remote_efs = 1; memcpy(&efs, (void *) val, olen); + } break; case L2CAP_CONF_EWS: @@ -2492,16 +2493,17 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi break; case L2CAP_CONF_EFS: - if (olen == sizeof(efs)) + if (olen == sizeof(efs)) { memcpy(&efs, (void *)val, olen); - if (chan->local_stype != L2CAP_SERV_NOTRAFIC && - efs.stype != L2CAP_SERV_NOTRAFIC && - efs.stype != chan->local_stype) - return -ECONNREFUSED; + if (chan->local_stype != L2CAP_SERV_NOTRAFIC && + efs.stype != L2CAP_SERV_NOTRAFIC && + efs.stype != chan->local_stype) + return -ECONNREFUSED; - l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, - sizeof(efs), (unsigned long) &efs); + l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, + sizeof(efs), (unsigned long) &efs); + } break; } } diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 4a26348444b..951ba7603b0 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -39,6 +39,12 @@ static const struct proto_ops l2cap_sock_ops; static void l2cap_sock_init(struct sock *sk, struct sock *parent); static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio); +bool l2cap_is_socket(struct socket *sock) +{ + return sock && sock->ops == &l2cap_sock_ops; +} +EXPORT_SYMBOL(l2cap_is_socket); + static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) { struct sock *sk = sock->sk; diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 7065c0ae1e7..b22978748bc 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -780,6 +780,11 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if (skb == NULL) goto out_release; + if (sk->sk_state == DCCP_CLOSED) { + rc = -ENOTCONN; + goto out_discard; + } + skb_reserve(skb, sk->sk_prot->max_header); rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); if (rc != 0) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index bc7b5de4972..573cac2b3c1 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4232,6 +4232,10 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) struct sctp_af *af; int err = 0; + /* Do not peel off from one netns to another one. */ + if (!net_eq(current->nsproxy->net_ns, sock_net(sk))) + return -EINVAL; + if (!asoc) return -EINVAL; diff --git a/security/keys/request_key.c b/security/keys/request_key.c index cc3790315d2..0f1c5fa3537 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -267,11 +267,12 @@ static int construct_key(struct key *key, const void *callout_info, * The keyring selected is returned with an extra reference upon it which the * caller must release. */ -static void construct_get_dest_keyring(struct key **_dest_keyring) +static int construct_get_dest_keyring(struct key **_dest_keyring) { struct request_key_auth *rka; const struct cred *cred = current_cred(); struct key *dest_keyring = *_dest_keyring, *authkey; + int ret; kenter("%p", dest_keyring); @@ -280,6 +281,8 @@ static void construct_get_dest_keyring(struct key **_dest_keyring) /* the caller supplied one */ key_get(dest_keyring); } else { + bool do_perm_check = true; + /* use a default keyring; falling through the cases until we * find one that we actually have */ switch (cred->jit_keyring) { @@ -294,8 +297,10 @@ static void construct_get_dest_keyring(struct key **_dest_keyring) dest_keyring = key_get(rka->dest_keyring); up_read(&authkey->sem); - if (dest_keyring) + if (dest_keyring) { + do_perm_check = false; break; + } } case KEY_REQKEY_DEFL_THREAD_KEYRING: @@ -330,11 +335,29 @@ static void construct_get_dest_keyring(struct key **_dest_keyring) default: BUG(); } + + /* + * Require Write permission on the keyring. This is essential + * because the default keyring may be the session keyring, and + * joining a keyring only requires Search permission. + * + * However, this check is skipped for the "requestor keyring" so + * that /sbin/request-key can itself use request_key() to add + * keys to the original requestor's destination keyring. + */ + if (dest_keyring && do_perm_check) { + ret = key_permission(make_key_ref(dest_keyring, 1), + KEY_WRITE); + if (ret) { + key_put(dest_keyring); + return ret; + } + } } *_dest_keyring = dest_keyring; kleave(" [dk %d]", key_serial(dest_keyring)); - return; + return 0; } /* @@ -449,11 +472,15 @@ static struct key *construct_key_and_link(struct key_type *type, kenter(""); - user = key_user_lookup(current_fsuid(), current_user_ns()); - if (!user) - return ERR_PTR(-ENOMEM); + ret = construct_get_dest_keyring(&dest_keyring); + if (ret) + goto error; - construct_get_dest_keyring(&dest_keyring); + user = key_user_lookup(current_fsuid(), current_user_ns()); + if (!user) { + ret = -ENOMEM; + goto error_put_dest_keyring; + } ret = construct_alloc_key(type, description, dest_keyring, flags, user, &key); @@ -469,7 +496,7 @@ static struct key *construct_key_and_link(struct key_type *type, } else if (ret == -EINPROGRESS) { ret = 0; } else { - goto couldnt_alloc_key; + goto error_put_dest_keyring; } key_put(dest_keyring); @@ -479,8 +506,9 @@ static struct key *construct_key_and_link(struct key_type *type, construction_failed: key_negate_and_link(key, key_negative_timeout, NULL, NULL); key_put(key); -couldnt_alloc_key: +error_put_dest_keyring: key_put(dest_keyring); +error: kleave(" = %d", ret); return ERR_PTR(ret); }