Skip to content

Commit

Permalink
Merge tag 'v6.6.47' into for/openbmc/dev-6.6
Browse files Browse the repository at this point in the history
This is the 6.6.47 stable release
  • Loading branch information
amboar committed Aug 19, 2024
2 parents c005e2f + 4c1a2d4 commit 1760371
Show file tree
Hide file tree
Showing 89 changed files with 1,003 additions and 728 deletions.
2 changes: 1 addition & 1 deletion Documentation/bpf/map_lpm_trie.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ significant byte.

LPM tries may be created with a maximum prefix length that is a multiple
of 8, in the range from 8 to 2048. The key used for lookup and update
operations is a ``struct bpf_lpm_trie_key``, extended by
operations is a ``struct bpf_lpm_trie_key_u8``, extended by
``max_prefixlen/8`` bytes.

- For IPv4 addresses the data length is 4 bytes
Expand Down
9 changes: 8 additions & 1 deletion Documentation/mm/page_table_check.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,21 @@ Page table check performs extra verifications at the time when new pages become
accessible from the userspace by getting their page table entries (PTEs PMDs
etc.) added into the table.

In case of detected corruption, the kernel is crashed. There is a small
In case of most detected corruption, the kernel is crashed. There is a small
performance and memory overhead associated with the page table check. Therefore,
it is disabled by default, but can be optionally enabled on systems where the
extra hardening outweighs the performance costs. Also, because page table check
is synchronous, it can help with debugging double map memory corruption issues,
by crashing kernel at the time wrong mapping occurs instead of later which is
often the case with memory corruptions bugs.

It can also be used to do page table entry checks over various flags, dump
warnings when illegal combinations of entry flags are detected. Currently,
userfaultfd is the only user of such to sanity check wr-protect bit against
any writable flags. Illegal flag combinations will not directly cause data
corruption in this case immediately, but that will cause read-only data to
be writable, leading to corrupt when the page content is later modified.

Double mapping detection logic
==============================

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 6
PATCHLEVEL = 6
SUBLEVEL = 46
SUBLEVEL = 47
EXTRAVERSION =
NAME = Hurr durr I'ma ninja sloth

Expand Down
12 changes: 8 additions & 4 deletions arch/arm64/kvm/hyp/pgtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ static int hyp_unmap_walker(const struct kvm_pgtable_visit_ctx *ctx,

kvm_clear_pte(ctx->ptep);
dsb(ishst);
__tlbi_level(vae2is, __TLBI_VADDR(ctx->addr, 0), ctx->level);
__tlbi_level(vae2is, __TLBI_VADDR(ctx->addr, 0), 0);
} else {
if (ctx->end - ctx->addr < granule)
return -EINVAL;
Expand Down Expand Up @@ -861,9 +861,13 @@ static void stage2_unmap_put_pte(const struct kvm_pgtable_visit_ctx *ctx,
if (kvm_pte_valid(ctx->old)) {
kvm_clear_pte(ctx->ptep);

if (!stage2_unmap_defer_tlb_flush(pgt))
kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu,
ctx->addr, ctx->level);
if (kvm_pte_table(ctx->old, ctx->level)) {
kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu, ctx->addr,
0);
} else if (!stage2_unmap_defer_tlb_flush(pgt)) {
kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu, ctx->addr,
ctx->level);
}
}

mm_ops->put_page(ctx->ptep);
Expand Down
1 change: 1 addition & 0 deletions arch/loongarch/include/uapi/asm/unistd.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#define __ARCH_WANT_NEW_STAT
#define __ARCH_WANT_SYS_CLONE
#define __ARCH_WANT_SYS_CLONE3

Expand Down
18 changes: 1 addition & 17 deletions arch/x86/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,23 +387,7 @@ static inline pte_t pte_wrprotect(pte_t pte)
#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
static inline int pte_uffd_wp(pte_t pte)
{
bool wp = pte_flags(pte) & _PAGE_UFFD_WP;

#ifdef CONFIG_DEBUG_VM
/*
* Having write bit for wr-protect-marked present ptes is fatal,
* because it means the uffd-wp bit will be ignored and write will
* just go through.
*
* Use any chance of pgtable walking to verify this (e.g., when
* page swapped out or being migrated for all purposes). It means
* something is already wrong. Tell the admin even before the
* process crashes. We also nail it with wrong pgtable setup.
*/
WARN_ON_ONCE(wp && pte_write(pte));
#endif

return wp;
return pte_flags(pte) & _PAGE_UFFD_WP;
}

static inline pte_t pte_mkuffd_wp(pte_t pte)
Expand Down
15 changes: 13 additions & 2 deletions drivers/ata/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -941,8 +941,19 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
&sense_key, &asc, &ascq);
ata_scsi_set_sense(qc->dev, cmd, sense_key, asc, ascq);
} else {
/* ATA PASS-THROUGH INFORMATION AVAILABLE */
ata_scsi_set_sense(qc->dev, cmd, RECOVERED_ERROR, 0, 0x1D);
/*
* ATA PASS-THROUGH INFORMATION AVAILABLE
*
* Note: we are supposed to call ata_scsi_set_sense(), which
* respects the D_SENSE bit, instead of unconditionally
* generating the sense data in descriptor format. However,
* because hdparm, hddtemp, and udisks incorrectly assume sense
* data in descriptor format, without even looking at the
* RESPONSE CODE field in the returned sense data (to see which
* format the returned sense data is in), we are stuck with
* being bug compatible with older kernels.
*/
scsi_build_sense(cmd, 1, RECOVERED_ERROR, 0, 0x1D);
}
}

Expand Down
10 changes: 5 additions & 5 deletions drivers/isdn/mISDN/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,23 +401,23 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
}

static int data_sock_setsockopt(struct socket *sock, int level, int optname,
sockptr_t optval, unsigned int len)
sockptr_t optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
int err = 0, opt = 0;

if (*debug & DEBUG_SOCKET)
printk(KERN_DEBUG "%s(%p, %d, %x, optval, %d)\n", __func__, sock,
level, optname, len);
level, optname, optlen);

lock_sock(sk);

switch (optname) {
case MISDN_TIME_STAMP:
if (copy_from_sockptr(&opt, optval, sizeof(int))) {
err = -EFAULT;
err = copy_safe_from_sockptr(&opt, sizeof(opt),
optval, optlen);
if (err)
break;
}

if (opt)
_pms(sk)->cmask |= MISDN_TIME_STAMP;
Expand Down
35 changes: 4 additions & 31 deletions drivers/media/usb/dvb-usb/dvb-usb-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,40 +23,11 @@ static int dvb_usb_force_pid_filter_usage;
module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444);
MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID filter, if any (default: 0).");

static int dvb_usb_check_bulk_endpoint(struct dvb_usb_device *d, u8 endpoint)
{
if (endpoint) {
int ret;

ret = usb_pipe_type_check(d->udev, usb_sndbulkpipe(d->udev, endpoint));
if (ret)
return ret;
ret = usb_pipe_type_check(d->udev, usb_rcvbulkpipe(d->udev, endpoint));
if (ret)
return ret;
}
return 0;
}

static void dvb_usb_clear_halt(struct dvb_usb_device *d, u8 endpoint)
{
if (endpoint) {
usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, endpoint));
usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, endpoint));
}
}

static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
{
struct dvb_usb_adapter *adap;
int ret, n, o;

ret = dvb_usb_check_bulk_endpoint(d, d->props.generic_bulk_ctrl_endpoint);
if (ret)
return ret;
ret = dvb_usb_check_bulk_endpoint(d, d->props.generic_bulk_ctrl_endpoint_response);
if (ret)
return ret;
for (n = 0; n < d->props.num_adapters; n++) {
adap = &d->adapter[n];
adap->dev = d;
Expand Down Expand Up @@ -132,8 +103,10 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
* when reloading the driver w/o replugging the device
* sometimes a timeout occurs, this helps
*/
dvb_usb_clear_halt(d, d->props.generic_bulk_ctrl_endpoint);
dvb_usb_clear_halt(d, d->props.generic_bulk_ctrl_endpoint_response);
if (d->props.generic_bulk_ctrl_endpoint != 0) {
usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
}

return 0;

Expand Down
23 changes: 9 additions & 14 deletions drivers/net/ppp/pppoe.c
Original file line number Diff line number Diff line change
Expand Up @@ -1007,26 +1007,21 @@ static int pppoe_recvmsg(struct socket *sock, struct msghdr *m,
struct sk_buff *skb;
int error = 0;

if (sk->sk_state & PPPOX_BOUND) {
error = -EIO;
goto end;
}
if (sk->sk_state & PPPOX_BOUND)
return -EIO;

skb = skb_recv_datagram(sk, flags, &error);
if (error < 0)
goto end;
if (!skb)
return error;

if (skb) {
total_len = min_t(size_t, total_len, skb->len);
error = skb_copy_datagram_msg(skb, 0, m, total_len);
if (error == 0) {
consume_skb(skb);
return total_len;
}
total_len = min_t(size_t, total_len, skb->len);
error = skb_copy_datagram_msg(skb, 0, m, total_len);
if (error == 0) {
consume_skb(skb);
return total_len;
}

kfree_skb(skb);
end:
return error;
}

Expand Down
7 changes: 7 additions & 0 deletions drivers/nvme/host/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2931,6 +2931,13 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev)
return NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND;
}

/*
* NVMe SSD drops off the PCIe bus after system idle
* for 10 hours on a Lenovo N60z board.
*/
if (dmi_match(DMI_BOARD_NAME, "LXKT-ZXEG-N6"))
return NVME_QUIRK_NO_APST;

return 0;
}

Expand Down
4 changes: 3 additions & 1 deletion fs/binfmt_flat.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,10 @@

#ifdef CONFIG_BINFMT_FLAT_NO_DATA_START_OFFSET
#define DATA_START_OFFSET_WORDS (0)
#define MAX_SHARED_LIBS_UPDATE (0)
#else
#define DATA_START_OFFSET_WORDS (MAX_SHARED_LIBS)
#define MAX_SHARED_LIBS_UPDATE (MAX_SHARED_LIBS)
#endif

struct lib_info {
Expand Down Expand Up @@ -880,7 +882,7 @@ static int load_flat_binary(struct linux_binprm *bprm)
return res;

/* Update data segment pointers for all libraries */
for (i = 0; i < MAX_SHARED_LIBS; i++) {
for (i = 0; i < MAX_SHARED_LIBS_UPDATE; i++) {
if (!libinfo.lib_list[i].loaded)
continue;
for (j = 0; j < MAX_SHARED_LIBS; j++) {
Expand Down
2 changes: 2 additions & 0 deletions fs/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -2179,6 +2179,8 @@ static void __block_commit_write(struct folio *folio, size_t from, size_t to)
struct buffer_head *bh, *head;

bh = head = folio_buffers(folio);
if (!bh)
return;
blocksize = bh->b_size;

block_start = 0;
Expand Down
2 changes: 1 addition & 1 deletion fs/cramfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ static void cramfs_kill_sb(struct super_block *sb)
sb->s_mtd = NULL;
} else if (IS_ENABLED(CONFIG_CRAMFS_BLOCKDEV) && sb->s_bdev) {
sync_blockdev(sb->s_bdev);
blkdev_put(sb->s_bdev, sb);
bdev_release(sb->s_bdev_handle);
}
kfree(sbi);
}
Expand Down
8 changes: 1 addition & 7 deletions fs/erofs/decompressor.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,15 +248,9 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_lz4_decompress_ctx *ctx,
if (ret != rq->outputsize) {
erofs_err(rq->sb, "failed to decompress %d in[%u, %u] out[%u]",
ret, rq->inputsize, inputmargin, rq->outputsize);

print_hex_dump(KERN_DEBUG, "[ in]: ", DUMP_PREFIX_OFFSET,
16, 1, src + inputmargin, rq->inputsize, true);
print_hex_dump(KERN_DEBUG, "[out]: ", DUMP_PREFIX_OFFSET,
16, 1, out, rq->outputsize, true);

if (ret >= 0)
memset(out + ret, 0, rq->outputsize - ret);
ret = -EIO;
ret = -EFSCORRUPTED;
} else {
ret = 0;
}
Expand Down
8 changes: 7 additions & 1 deletion fs/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1609,6 +1609,7 @@ static void bprm_fill_uid(struct linux_binprm *bprm, struct file *file)
unsigned int mode;
vfsuid_t vfsuid;
vfsgid_t vfsgid;
int err;

if (!mnt_may_suid(file->f_path.mnt))
return;
Expand All @@ -1625,12 +1626,17 @@ static void bprm_fill_uid(struct linux_binprm *bprm, struct file *file)
/* Be careful if suid/sgid is set */
inode_lock(inode);

/* reload atomically mode/uid/gid now that lock held */
/* Atomically reload and check mode/uid/gid now that lock held. */
mode = inode->i_mode;
vfsuid = i_uid_into_vfsuid(idmap, inode);
vfsgid = i_gid_into_vfsgid(idmap, inode);
err = inode_permission(idmap, inode, MAY_EXEC);
inode_unlock(inode);

/* Did the exec bit vanish out from under us? Give up. */
if (err)
return;

/* We ignore suid/sgid if there are no mappings for them in the ns */
if (!vfsuid_has_mapping(bprm->cred->user_ns, vfsuid) ||
!vfsgid_has_mapping(bprm->cred->user_ns, vfsgid))
Expand Down
24 changes: 15 additions & 9 deletions fs/ext4/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -2966,23 +2966,29 @@ static int ext4_da_should_update_i_disksize(struct folio *folio,

static int ext4_da_do_write_end(struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page)
struct folio *folio)
{
struct inode *inode = mapping->host;
loff_t old_size = inode->i_size;
bool disksize_changed = false;
loff_t new_i_size;

if (unlikely(!folio_buffers(folio))) {
folio_unlock(folio);
folio_put(folio);
return -EIO;
}
/*
* block_write_end() will mark the inode as dirty with I_DIRTY_PAGES
* flag, which all that's needed to trigger page writeback.
*/
copied = block_write_end(NULL, mapping, pos, len, copied, page, NULL);
copied = block_write_end(NULL, mapping, pos, len, copied,
&folio->page, NULL);
new_i_size = pos + copied;

/*
* It's important to update i_size while still holding page lock,
* because page writeout could otherwise come in and zero beyond
* It's important to update i_size while still holding folio lock,
* because folio writeout could otherwise come in and zero beyond
* i_size.
*
* Since we are holding inode lock, we are sure i_disksize <=
Expand All @@ -3000,14 +3006,14 @@ static int ext4_da_do_write_end(struct address_space *mapping,

i_size_write(inode, new_i_size);
end = (new_i_size - 1) & (PAGE_SIZE - 1);
if (copied && ext4_da_should_update_i_disksize(page_folio(page), end)) {
if (copied && ext4_da_should_update_i_disksize(folio, end)) {
ext4_update_i_disksize(inode, new_i_size);
disksize_changed = true;
}
}

unlock_page(page);
put_page(page);
folio_unlock(folio);
folio_put(folio);

if (old_size < pos)
pagecache_isize_extended(inode, old_size, pos);
Expand Down Expand Up @@ -3046,10 +3052,10 @@ static int ext4_da_write_end(struct file *file,
return ext4_write_inline_data_end(inode, pos, len, copied,
folio);

if (unlikely(copied < len) && !PageUptodate(page))
if (unlikely(copied < len) && !folio_test_uptodate(folio))
copied = 0;

return ext4_da_do_write_end(mapping, pos, len, copied, &folio->page);
return ext4_da_do_write_end(mapping, pos, len, copied, folio);
}

/*
Expand Down
Loading

0 comments on commit 1760371

Please sign in to comment.