mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
Merge 6.1.102 into android14-6.1-lts
Changes in 6.1.102 drm/amdgpu: Fix signedness bug in sdma_v4_0_process_trap_irq() f2fs: avoid dead loop in f2fs_issue_checkpoint() ocfs2: add bounds checking to ocfs2_check_dir_entry() jfs: don't walk off the end of ealist fs/ntfs3: Validate ff offset ALSA: hda/realtek: Enable headset mic on Positivo SU C1400 ALSA: hda/realtek: Fix the speaker output on Samsung Galaxy Book Pro 360 arm64: dts: qcom: msm8996: Disable SS instance in Parkmode for USB arm64: dts: qcom: ipq6018: Disable SS instance in Parkmode for USB arm64: dts: qcom: sdm630: Disable SS instance in Parkmode for USB ALSA: pcm_dmaengine: Don't synchronize DMA channel when DMA is paused filelock: Fix fcntl/close race recovery compat path btrfs: do not BUG_ON on failure to get dir index for new snapshot tun: add missing verification for short frame tap: add missing verification for short frame Linux 6.1.102 Change-Id: I04d415693004d988ad48f793a36a8bfd01c4f8b3 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 101
|
||||
SUBLEVEL = 102
|
||||
EXTRAVERSION =
|
||||
NAME = Curry Ramen
|
||||
|
||||
|
||||
@@ -760,6 +760,7 @@
|
||||
clocks = <&xo>;
|
||||
clock-names = "ref";
|
||||
tx-fifo-resize;
|
||||
snps,parkmode-disable-ss-quirk;
|
||||
snps,is-utmi-l1-suspend;
|
||||
snps,hird-threshold = /bits/ 8 <0x0>;
|
||||
snps,dis_u2_susphy_quirk;
|
||||
|
||||
@@ -3004,6 +3004,7 @@
|
||||
snps,dis_u2_susphy_quirk;
|
||||
snps,dis_enblslpm_quirk;
|
||||
snps,is-utmi-l1-suspend;
|
||||
snps,parkmode-disable-ss-quirk;
|
||||
tx-fifo-resize;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1243,6 +1243,7 @@
|
||||
interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
|
||||
snps,dis_u2_susphy_quirk;
|
||||
snps,dis_enblslpm_quirk;
|
||||
snps,parkmode-disable-ss-quirk;
|
||||
|
||||
/*
|
||||
* SDM630 technically supports USB3 but I
|
||||
|
||||
@@ -2045,7 +2045,7 @@ static int sdma_v4_0_process_trap_irq(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
{
|
||||
uint32_t instance;
|
||||
int instance;
|
||||
|
||||
DRM_DEBUG("IH: SDMA trap\n");
|
||||
instance = sdma_v4_0_irq_id_to_seq(entry->client_id);
|
||||
|
||||
@@ -1156,6 +1156,11 @@ static int tap_get_user_xdp(struct tap_queue *q, struct xdp_buff *xdp)
|
||||
struct sk_buff *skb;
|
||||
int err, depth;
|
||||
|
||||
if (unlikely(xdp->data_end - xdp->data < ETH_HLEN)) {
|
||||
err = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (q->flags & IFF_VNET_HDR)
|
||||
vnet_hdr_len = READ_ONCE(q->vnet_hdr_sz);
|
||||
|
||||
|
||||
@@ -2448,6 +2448,9 @@ static int tun_xdp_one(struct tun_struct *tun,
|
||||
bool skb_xdp = false;
|
||||
struct page *page;
|
||||
|
||||
if (unlikely(datasize < ETH_HLEN))
|
||||
return -EINVAL;
|
||||
|
||||
xdp_prog = rcu_dereference(tun->xdp_prog);
|
||||
if (xdp_prog) {
|
||||
if (gso->gso_type) {
|
||||
|
||||
@@ -1701,7 +1701,10 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
|
||||
* insert the directory item
|
||||
*/
|
||||
ret = btrfs_set_inode_index(BTRFS_I(parent_inode), &index);
|
||||
BUG_ON(ret); /* -ENOMEM */
|
||||
if (ret) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* check if there is a file/dir which has the same name. */
|
||||
dir_item = btrfs_lookup_dir_item(NULL, parent_root, path,
|
||||
|
||||
@@ -2913,16 +2913,27 @@ static int f2fs_quota_on(struct super_block *sb, int type, int format_id,
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (path->dentry->d_sb != sb)
|
||||
return -EXDEV;
|
||||
|
||||
err = f2fs_quota_sync(sb, type);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
inode = d_inode(path->dentry);
|
||||
|
||||
err = filemap_fdatawrite(inode->i_mapping);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = filemap_fdatawait(inode->i_mapping);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = dquot_quota_on(sb, type, format_id, path);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
inode = d_inode(path->dentry);
|
||||
|
||||
inode_lock(inode);
|
||||
F2FS_I(inode)->i_flags |= F2FS_NOATIME_FL | F2FS_IMMUTABLE_FL;
|
||||
f2fs_set_inode_flags(inode);
|
||||
|
||||
@@ -797,7 +797,7 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
|
||||
size_t buf_size)
|
||||
{
|
||||
struct jfs_ea_list *ealist;
|
||||
struct jfs_ea *ea;
|
||||
struct jfs_ea *ea, *ealist_end;
|
||||
struct ea_buffer ea_buf;
|
||||
int xattr_size;
|
||||
ssize_t size;
|
||||
@@ -817,9 +817,16 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
|
||||
goto not_found;
|
||||
|
||||
ealist = (struct jfs_ea_list *) ea_buf.xattr;
|
||||
ealist_end = END_EALIST(ealist);
|
||||
|
||||
/* Find the named attribute */
|
||||
for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea))
|
||||
for (ea = FIRST_EA(ealist); ea < ealist_end; ea = NEXT_EA(ea)) {
|
||||
if (unlikely(ea + 1 > ealist_end) ||
|
||||
unlikely(NEXT_EA(ea) > ealist_end)) {
|
||||
size = -EUCLEAN;
|
||||
goto release;
|
||||
}
|
||||
|
||||
if ((namelen == ea->namelen) &&
|
||||
memcmp(name, ea->name, namelen) == 0) {
|
||||
/* Found it */
|
||||
@@ -834,6 +841,7 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
|
||||
memcpy(data, value, size);
|
||||
goto release;
|
||||
}
|
||||
}
|
||||
not_found:
|
||||
size = -ENODATA;
|
||||
release:
|
||||
@@ -861,7 +869,7 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
|
||||
ssize_t size = 0;
|
||||
int xattr_size;
|
||||
struct jfs_ea_list *ealist;
|
||||
struct jfs_ea *ea;
|
||||
struct jfs_ea *ea, *ealist_end;
|
||||
struct ea_buffer ea_buf;
|
||||
|
||||
down_read(&JFS_IP(inode)->xattr_sem);
|
||||
@@ -876,9 +884,16 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
|
||||
goto release;
|
||||
|
||||
ealist = (struct jfs_ea_list *) ea_buf.xattr;
|
||||
ealist_end = END_EALIST(ealist);
|
||||
|
||||
/* compute required size of list */
|
||||
for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) {
|
||||
for (ea = FIRST_EA(ealist); ea < ealist_end; ea = NEXT_EA(ea)) {
|
||||
if (unlikely(ea + 1 > ealist_end) ||
|
||||
unlikely(NEXT_EA(ea) > ealist_end)) {
|
||||
size = -EUCLEAN;
|
||||
goto release;
|
||||
}
|
||||
|
||||
if (can_list(ea))
|
||||
size += name_size(ea) + 1;
|
||||
}
|
||||
|
||||
@@ -2516,8 +2516,9 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
|
||||
error = do_lock_file_wait(filp, cmd, file_lock);
|
||||
|
||||
/*
|
||||
* Attempt to detect a close/fcntl race and recover by releasing the
|
||||
* lock that was just acquired. There is no need to do that when we're
|
||||
* Detect close/fcntl races and recover by zapping all POSIX locks
|
||||
* associated with this file and our files_struct, just like on
|
||||
* filp_flush(). There is no need to do that when we're
|
||||
* unlocking though, or for OFD locks.
|
||||
*/
|
||||
if (!error && file_lock->fl_type != F_UNLCK &&
|
||||
@@ -2532,9 +2533,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
|
||||
f = files_lookup_fd_locked(files, fd);
|
||||
spin_unlock(&files->file_lock);
|
||||
if (f != filp) {
|
||||
file_lock->fl_type = F_UNLCK;
|
||||
error = do_lock_file_wait(filp, cmd, file_lock);
|
||||
WARN_ON_ONCE(error);
|
||||
locks_remove_posix(filp, files);
|
||||
error = -EBADF;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -724,7 +724,8 @@ static bool check_rstbl(const struct RESTART_TABLE *rt, size_t bytes)
|
||||
|
||||
if (!rsize || rsize > bytes ||
|
||||
rsize + sizeof(struct RESTART_TABLE) > bytes || bytes < ts ||
|
||||
le16_to_cpu(rt->total) > ne || ff > ts || lf > ts ||
|
||||
le16_to_cpu(rt->total) > ne ||
|
||||
ff > ts - sizeof(__le32) || lf > ts - sizeof(__le32) ||
|
||||
(ff && ff < sizeof(struct RESTART_TABLE)) ||
|
||||
(lf && lf < sizeof(struct RESTART_TABLE))) {
|
||||
return false;
|
||||
@@ -754,6 +755,9 @@ static bool check_rstbl(const struct RESTART_TABLE *rt, size_t bytes)
|
||||
return false;
|
||||
|
||||
off = le32_to_cpu(*(__le32 *)Add2Ptr(rt, off));
|
||||
|
||||
if (off > ts - sizeof(__le32))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -294,13 +294,16 @@ out:
|
||||
* bh passed here can be an inode block or a dir data block, depending
|
||||
* on the inode inline data flag.
|
||||
*/
|
||||
static int ocfs2_check_dir_entry(struct inode * dir,
|
||||
struct ocfs2_dir_entry * de,
|
||||
struct buffer_head * bh,
|
||||
static int ocfs2_check_dir_entry(struct inode *dir,
|
||||
struct ocfs2_dir_entry *de,
|
||||
struct buffer_head *bh,
|
||||
char *buf,
|
||||
unsigned int size,
|
||||
unsigned long offset)
|
||||
{
|
||||
const char *error_msg = NULL;
|
||||
const int rlen = le16_to_cpu(de->rec_len);
|
||||
const unsigned long next_offset = ((char *) de - buf) + rlen;
|
||||
|
||||
if (unlikely(rlen < OCFS2_DIR_REC_LEN(1)))
|
||||
error_msg = "rec_len is smaller than minimal";
|
||||
@@ -308,9 +311,11 @@ static int ocfs2_check_dir_entry(struct inode * dir,
|
||||
error_msg = "rec_len % 4 != 0";
|
||||
else if (unlikely(rlen < OCFS2_DIR_REC_LEN(de->name_len)))
|
||||
error_msg = "rec_len is too small for name_len";
|
||||
else if (unlikely(
|
||||
((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize))
|
||||
error_msg = "directory entry across blocks";
|
||||
else if (unlikely(next_offset > size))
|
||||
error_msg = "directory entry overrun";
|
||||
else if (unlikely(next_offset > size - OCFS2_DIR_REC_LEN(1)) &&
|
||||
next_offset != size)
|
||||
error_msg = "directory entry too close to end";
|
||||
|
||||
if (unlikely(error_msg != NULL))
|
||||
mlog(ML_ERROR, "bad entry in directory #%llu: %s - "
|
||||
@@ -352,16 +357,17 @@ static inline int ocfs2_search_dirblock(struct buffer_head *bh,
|
||||
de_buf = first_de;
|
||||
dlimit = de_buf + bytes;
|
||||
|
||||
while (de_buf < dlimit) {
|
||||
while (de_buf < dlimit - OCFS2_DIR_MEMBER_LEN) {
|
||||
/* this code is executed quadratically often */
|
||||
/* do minimal checking `by hand' */
|
||||
|
||||
de = (struct ocfs2_dir_entry *) de_buf;
|
||||
|
||||
if (de_buf + namelen <= dlimit &&
|
||||
if (de->name + namelen <= dlimit &&
|
||||
ocfs2_match(namelen, name, de)) {
|
||||
/* found a match - just to be sure, do a full check */
|
||||
if (!ocfs2_check_dir_entry(dir, de, bh, offset)) {
|
||||
if (!ocfs2_check_dir_entry(dir, de, bh, first_de,
|
||||
bytes, offset)) {
|
||||
ret = -1;
|
||||
goto bail;
|
||||
}
|
||||
@@ -1138,7 +1144,7 @@ static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir,
|
||||
pde = NULL;
|
||||
de = (struct ocfs2_dir_entry *) first_de;
|
||||
while (i < bytes) {
|
||||
if (!ocfs2_check_dir_entry(dir, de, bh, i)) {
|
||||
if (!ocfs2_check_dir_entry(dir, de, bh, first_de, bytes, i)) {
|
||||
status = -EIO;
|
||||
mlog_errno(status);
|
||||
goto bail;
|
||||
@@ -1638,7 +1644,8 @@ int __ocfs2_add_entry(handle_t *handle,
|
||||
/* These checks should've already been passed by the
|
||||
* prepare function, but I guess we can leave them
|
||||
* here anyway. */
|
||||
if (!ocfs2_check_dir_entry(dir, de, insert_bh, offset)) {
|
||||
if (!ocfs2_check_dir_entry(dir, de, insert_bh, data_start,
|
||||
size, offset)) {
|
||||
retval = -ENOENT;
|
||||
goto bail;
|
||||
}
|
||||
@@ -1776,7 +1783,8 @@ static int ocfs2_dir_foreach_blk_id(struct inode *inode,
|
||||
}
|
||||
|
||||
de = (struct ocfs2_dir_entry *) (data->id_data + ctx->pos);
|
||||
if (!ocfs2_check_dir_entry(inode, de, di_bh, ctx->pos)) {
|
||||
if (!ocfs2_check_dir_entry(inode, de, di_bh, (char *)data->id_data,
|
||||
i_size_read(inode), ctx->pos)) {
|
||||
/* On error, skip the f_pos to the end. */
|
||||
ctx->pos = i_size_read(inode);
|
||||
break;
|
||||
@@ -1869,7 +1877,8 @@ static int ocfs2_dir_foreach_blk_el(struct inode *inode,
|
||||
while (ctx->pos < i_size_read(inode)
|
||||
&& offset < sb->s_blocksize) {
|
||||
de = (struct ocfs2_dir_entry *) (bh->b_data + offset);
|
||||
if (!ocfs2_check_dir_entry(inode, de, bh, offset)) {
|
||||
if (!ocfs2_check_dir_entry(inode, de, bh, bh->b_data,
|
||||
sb->s_blocksize, offset)) {
|
||||
/* On error, skip the f_pos to the
|
||||
next block. */
|
||||
ctx->pos = (ctx->pos | (sb->s_blocksize - 1)) + 1;
|
||||
@@ -3341,7 +3350,7 @@ static int ocfs2_find_dir_space_id(struct inode *dir, struct buffer_head *di_bh,
|
||||
struct super_block *sb = dir->i_sb;
|
||||
struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
|
||||
struct ocfs2_dir_entry *de, *last_de = NULL;
|
||||
char *de_buf, *limit;
|
||||
char *first_de, *de_buf, *limit;
|
||||
unsigned long offset = 0;
|
||||
unsigned int rec_len, new_rec_len, free_space;
|
||||
|
||||
@@ -3354,14 +3363,16 @@ static int ocfs2_find_dir_space_id(struct inode *dir, struct buffer_head *di_bh,
|
||||
else
|
||||
free_space = dir->i_sb->s_blocksize - i_size_read(dir);
|
||||
|
||||
de_buf = di->id2.i_data.id_data;
|
||||
first_de = di->id2.i_data.id_data;
|
||||
de_buf = first_de;
|
||||
limit = de_buf + i_size_read(dir);
|
||||
rec_len = OCFS2_DIR_REC_LEN(namelen);
|
||||
|
||||
while (de_buf < limit) {
|
||||
de = (struct ocfs2_dir_entry *)de_buf;
|
||||
|
||||
if (!ocfs2_check_dir_entry(dir, de, di_bh, offset)) {
|
||||
if (!ocfs2_check_dir_entry(dir, de, di_bh, first_de,
|
||||
i_size_read(dir), offset)) {
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
@@ -3443,7 +3454,8 @@ static int ocfs2_find_dir_space_el(struct inode *dir, const char *name,
|
||||
/* move to next block */
|
||||
de = (struct ocfs2_dir_entry *) bh->b_data;
|
||||
}
|
||||
if (!ocfs2_check_dir_entry(dir, de, bh, offset)) {
|
||||
if (!ocfs2_check_dir_entry(dir, de, bh, bh->b_data, blocksize,
|
||||
offset)) {
|
||||
status = -ENOENT;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
@@ -352,8 +352,12 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open_request_chan);
|
||||
int snd_dmaengine_pcm_sync_stop(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
|
||||
struct dma_tx_state state;
|
||||
enum dma_status status;
|
||||
|
||||
dmaengine_synchronize(prtd->dma_chan);
|
||||
status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state);
|
||||
if (status != DMA_PAUSED)
|
||||
dmaengine_synchronize(prtd->dma_chan);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -9928,6 +9928,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
|
||||
SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
|
||||
SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x10ec, 0x119e, "Positivo SU C1400", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x10ec, 0x11bc, "VAIO VJFE-IL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
||||
SND_PCI_QUIRK(0x10ec, 0x1230, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
|
||||
SND_PCI_QUIRK(0x10ec, 0x124c, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
|
||||
@@ -9941,6 +9942,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_AMP),
|
||||
SND_PCI_QUIRK(0x144d, 0xc18a, "Samsung Galaxy Book Ion (NP930XCJ-K01US)", ALC298_FIXUP_SAMSUNG_AMP),
|
||||
SND_PCI_QUIRK(0x144d, 0xc1a3, "Samsung Galaxy Book Pro (NP935XDB-KC1SE)", ALC298_FIXUP_SAMSUNG_AMP),
|
||||
SND_PCI_QUIRK(0x144d, 0xc1a4, "Samsung Galaxy Book Pro 360 (NT935QBD)", ALC298_FIXUP_SAMSUNG_AMP),
|
||||
SND_PCI_QUIRK(0x144d, 0xc1a6, "Samsung Galaxy Book Pro 360 (NP930QBD)", ALC298_FIXUP_SAMSUNG_AMP),
|
||||
SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
|
||||
SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_AMP),
|
||||
|
||||
Reference in New Issue
Block a user