4.14.263-rc1 review
Greg Kroah-Hartman
maintainerPATCH 176/186 net_sched: restore "mpu xxx" handling
In reply to Greg Kroah-HartmanFrom: Kevin Bracey <[email protected]>
commit fb80445c438c78b40b547d12b8d56596ce4ccfeb upstream.
commit 56b765b79e9a ("htb: improved accuracy at high rates") broke "overhead X", "linklayer atm" and "mpu X" attributes.
"overhead X" and "linklayer atm" have already been fixed. This restores the "mpu X" handling, as might be used by DOCSIS or Ethernet shaping:
tc class add ... htb rate X overhead 4 mpu 64
The code being fixed is used by htb, tbf and act_police. Cake has its own mpu handling. qdisc_calculate_pkt_len still uses the size table containing values adjusted for mpu by user space.
iproute2 tc has always passed mpu into the kernel via a tc_ratespec structure, but the kernel never directly acted on it, merely stored it so that it could be read back by tc class show.
Rather, tc would generate length-to-time tables that included the mpu (and linklayer) in their construction, and the kernel used those tables.
Since v3.7, the tables were no longer used. Along with "mpu", this also broke "overhead" and "linklayer" which were fixed in 01cb71d2d47b ("net_sched: restore "overhead xxx" handling", v3.10) and 8a8e3d84b171 ("net_sched: restore "linklayer atm" handling", v3.11).
"overhead" was fixed by simply restoring use of tc_ratespec::overhead - this had originally been used by the kernel but was initially omitted from the new non-table-based calculations.
"linklayer" had been handled in the table like "mpu", but the mode was not originally passed in tc_ratespec. The new implementation was made to handle it by getting new versions of tc to pass the mode in an extended tc_ratespec, and for older versions of tc the table contents were analysed at load time to deduce linklayer.
As "mpu" has always been given to the kernel in tc_ratespec, accompanying the mpu-based table, we can restore system functionality with no userspace change by making the kernel act on the tc_ratespec value.
--- include/net/sch_generic.h | 5 +++++ net/sched/sch_generic.c | 1 + 2 files changed, 6 insertions(+)
include/net/sch_generic.h +5 -0
@@ -885,6 +885,7 @@ struct psched_ratecfg {u64 rate_bytes_ps;/* bytes per second */ u32 mult;u16 overhead; +u16 mpu;u8 linklayer;u8 shift; };
@@ -894,6 +895,9 @@ static inline u64 psched_l2t_ns(const st { len += r->overhead; +if (len < r->mpu) + len = r->mpu; +if (unlikely (r->linklayer ==TC_LINKLAYER_ATM ))return ((u64)(DIV_ROUND_UP (len,48 )*53 ) * r->mult) >> r->shift;
@@ -916,6 +920,7 @@ static inline void psched_ratecfg_getrat res->rate =min_t (u64, r->rate_bytes_ps, ~0U ); res->overhead = r->overhead; + res->mpu = r->mpu; res->linklayer = (r->linklayer &TC_LINKLAYER_MASK ); }
net/sched/sch_generic.c +1 -0
@@ -1010,6 +1010,7 @@ void psched_ratecfg_precompute(struct ps {memset (r,0 ,sizeof (*r)); r->overhead = conf->overhead; + r->mpu = conf->mpu; r->rate_bytes_ps =max_t (u64, conf->rate, rate64); r->linklayer = (conf->linklayer &TC_LINKLAYER_MASK ); r->mult =1 ;
Greg Kroah-Hartman
maintainerPATCH 177/186 bcmgenet: add WOL IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
commit 9deb48b53e7f4056c2eaa2dc2ee3338df619e4f6 upstream.
The driver neglects to check the result of platform_get_irq_optional()'s call and blithely passes the negative error codes to devm_request_irq() (which takes *unsigned* IRQ #), causing it to fail with -EINVAL. Stop calling devm_request_irq() with the invalid IRQ #s.
--- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +6 -4
@@ -3519,10 +3519,12 @@ static int bcmgenet_probe(struct platfor/* Request the WOL interrupt and advertise suspend if available */ priv->wol_irq_disabled = true; - err =devm_request_irq (&pdev->dev, priv->wol_irq, bcmgenet_wol_isr,0 , - dev->name, priv); -if (!err) -device_set_wakeup_capable (&pdev->dev,1 ); +if (priv->wol_irq >0 ) { + err =devm_request_irq (&pdev->dev, priv->wol_irq, + bcmgenet_wol_isr,0 , dev->name, priv); +if (!err) +device_set_wakeup_capable (&pdev->dev,1 ); + }/* Set the needed headroom to account for any possible * features enabling/disabling at runtime
Greg Kroah-Hartman
maintainerPATCH 178/186 scripts/dtc: dtx_diff: remove broken example from help text
In reply to Greg Kroah-HartmanFrom: Matthias Schiffer <[email protected]>
commit d8adf5b92a9d2205620874d498c39923ecea8749 upstream.
dtx_diff suggests to use <(...) syntax to pipe two inputs into it, but this has never worked: The /proc/self/fds/... paths passed by the shell will fail the [ -f "${dtx}" ] && [ -r "${dtx}" ] check in compile_to_dts, but even with this check removed, the function cannot work: hexdump will eat up the DTB magic, making the subsequent dtc call fail, as a pipe cannot be rewound.
Simply remove this broken example, as there is already an alternative one that works fine.
--- scripts/dtc/dtx_diff | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
scripts/dtc/dtx_diff +2 -6
@@ -56,12 +56,8 @@ Otherwise DTx is treated as a dts source or '/include/' to be processed. If DTx_1 and DTx_2 are in different architectures, then this script - may not work since \${ARCH} is part of the include path. Two possible - workarounds: - - `basename $0` \\ - <(ARCH=arch_of_dtx_1 `basename $0` DTx_1) \\ - <(ARCH=arch_of_dtx_2 `basename $0` DTx_2) + may not work since \${ARCH} is part of the include path. The following + workaround can be used: `basename $0` ARCH=arch_of_dtx_1 DTx_1 >tmp_dtx_1.dts `basename $0` ARCH=arch_of_dtx_2 DTx_2 >tmp_dtx_2.dts
Greg Kroah-Hartman
maintainerPATCH 179/186 lib82596: Fix IRQ check in sni_82596_probe
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
commit 99218cbf81bf21355a3de61cd46a706d36e900e6 upstream.
platform_get_irq() returns negative error number instead 0 on failure. And the doc of platform_get_irq() provides a usage example:
int irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;Fix the check of return value to catch errors correctly.
--- drivers/net/ethernet/i825xx/sni_82596.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/i825xx/sni_82596.c +2 -1
@@ -122,9 +122,10 @@ static int sni_82596_probe(struct platfo netdevice->dev_addr[5 ] =readb (eth_addr +0x06 );iounmap (eth_addr); -if (!netdevice->irq) { +if (netdevice->irq <0 ) {printk (KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n" , __FILE__, netdevice->base_addr); + retval = netdevice->irq; goto probe_failed; }
Greg Kroah-Hartman
maintainerPATCH 180/186 mips,s390,sh,sparc: gup: Work around the "COW can break either way" issue
In reply to Greg Kroah-HartmanFrom: Ben Hutchings <[email protected]>
In Linux 4.14 and 4.19 these architectures still have their own implementations of get_user_pages_fast(). These also need to force the write flag on when taking the fast path.
--- arch/mips/mm/gup.c | 9 ++++++++- arch/s390/mm/gup.c | 9 ++++++++- arch/sh/mm/gup.c | 9 ++++++++- arch/sparc/mm/gup.c | 9 ++++++++- 4 files changed, 32 insertions(+), 4 deletions(-)
arch/mips/mm/gup.c +8 -1
@@ -272,7 +272,14 @@ int get_user_pages_fast(unsigned long st next =pgd_addr_end (addr, end);if (pgd_none (pgd)) goto slow; -if (!gup_pud_range (pgd, addr, next, write, pages, &nr)) +/* +* The FAST_GUP case requires FOLL_WRITE even for pure reads, +* because get_user_pages() may need to cause an early COW in +* order to avoid confusing the normal COW routines. So only +* targets that are already writable are safe to do by just +* looking at the page tables. +*/ +if (!gup_pud_range (pgd, addr, next,1 , pages, &nr)) goto slow; }while (pgdp++, addr = next, addr != end);local_irq_enable ();
arch/s390/mm/gup.c +8 -1
@@ -285,7 +285,14 @@ int get_user_pages_fast(unsigned long stmight_sleep (); start &=PAGE_MASK ; - nr =__get_user_pages_fast (start, nr_pages, write, pages); +/* +* The FAST_GUP case requires FOLL_WRITE even for pure reads, +* because get_user_pages() may need to cause an early COW in +* order to avoid confusing the normal COW routines. So only +* targets that are already writable are safe to do by just +* looking at the page tables. +*/ + nr =__get_user_pages_fast (start, nr_pages,1 , pages);if (nr == nr_pages)return nr;
arch/sh/mm/gup.c +8 -1
@@ -240,7 +240,14 @@ int get_user_pages_fast(unsigned long st next =pgd_addr_end (addr, end);if (pgd_none (pgd)) goto slow; -if (!gup_pud_range (pgd, addr, next, write, pages, &nr)) +/* +* The FAST_GUP case requires FOLL_WRITE even for pure reads, +* because get_user_pages() may need to cause an early COW in +* order to avoid confusing the normal COW routines. So only +* targets that are already writable are safe to do by just +* looking at the page tables. +*/ +if (!gup_pud_range (pgd, addr, next,1 , pages, &nr)) goto slow; }while (pgdp++, addr = next, addr != end);local_irq_enable ();
arch/sparc/mm/gup.c +8 -1
@@ -262,7 +262,14 @@ int get_user_pages_fast(unsigned long st next =pgd_addr_end (addr, end);if (pgd_none (pgd)) goto slow; -if (!gup_pud_range (pgd, addr, next, write, pages, &nr)) +/* +* The FAST_GUP case requires FOLL_WRITE even for pure reads, +* because get_user_pages() may need to cause an early COW in +* order to avoid confusing the normal COW routines. So only +* targets that are already writable are safe to do by just +* looking at the page tables. +*/ +if (!gup_pud_range (pgd, addr, next,1 , pages, &nr)) goto slow; }while (pgdp++, addr = next, addr != end);
Greg Kroah-Hartman
maintainerPATCH 181/186 drm/ttm/nouveau: dont call tt destroy callback on alloc failure.
In reply to Greg Kroah-HartmanFrom: Dave Airlie <[email protected]>
commit 5de5b6ecf97a021f29403aa272cb4e03318ef586 upstream.
This is confusing, and from my reading of all the drivers only nouveau got this right.
Just make the API act under driver control of it's own allocation failing, and don't call destroy, if the page table fails to create there is nothing to cleanup here.
(I'm willing to believe I've missed something here, so please review deeply).
[bwh: Backported to 4.14:
- Drop change in ttm_sg_tt_init()
- Adjust context]
--- drivers/gpu/drm/nouveau/nouveau_sgdma.c | 9 +++------ drivers/gpu/drm/ttm/ttm_tt.c | 2 -- 2 files changed, 3 insertions(+), 8 deletions(-)
drivers/gpu/drm/nouveau/nouveau_sgdma.c +3 -6
@@ -106,12 +106,9 @@ nouveau_sgdma_create_ttm(struct ttm_bo_delse nvbe->ttm.ttm.func = &nv50_sgdma_backend; -if (ttm_dma_tt_init (&nvbe->ttm, bdev, size, page_flags, dummy_read_page)) -/* -* A failing ttm_dma_tt_init() will call ttm_tt_destroy() -* and thus our nouveau_sgdma_destroy() hook, so we don't need -* to free nvbe here. -*/ +if (ttm_dma_tt_init (&nvbe->ttm, bdev, size, page_flags, dummy_read_page)) { +kfree (nvbe);return NULL ; + }return &nvbe->ttm.ttm; }
drivers/gpu/drm/ttm/ttm_tt.c +0 -2
@@ -199,7 +199,6 @@ int ttm_tt_init(struct ttm_tt *ttm, struttm_tt_alloc_page_directory (ttm);if (!ttm->pages) { -ttm_tt_destroy (ttm);pr_err ("Failed allocating page table\n" );return -ENOMEM ; }
@@ -232,7 +231,6 @@ int ttm_dma_tt_init(struct ttm_dma_tt *tINIT_LIST_HEAD (&ttm_dma->pages_list);ttm_dma_tt_alloc_page_directory (ttm_dma);if (!ttm->pages) { -ttm_tt_destroy (ttm);pr_err ("Failed allocating page table\n" );return -ENOMEM ; }
Greg Kroah-Hartman
maintainerPATCH 182/186 fuse: fix bad inode
In reply to Greg Kroah-HartmanFrom: Miklos Szeredi <[email protected]>
commit 5d069dbe8aaf2a197142558b6fb2978189ba3454 upstream.
Jan Kara's analysis of the syzbot report (edited):
The reproducer opens a directory on FUSE filesystem, it then attaches dnotify mark to the open directory. After that a fuse_do_getattr() call finds that attributes returned by the server are inconsistent, and calls make_bad_inode() which, among other things does:
inode->i_mode = S_IFREG;
This then confuses dnotify which doesn't tear down its structures properly and eventually crashes.
Avoid calling make_bad_inode() on a live inode: switch to a private flag on the fuse inode. Also add the test to ops which the bad_inode_ops would have caught.
This bug goes back to the initial merge of fuse in 2.6.14...
[bwh: Backported to 4.19:
- Drop changes in fuse_dir_fsync(), fuse_readahead(), fuse_evict_inode()
- In fuse_get_link(), return ERR_PTR(-EIO) for bad inodes
- Convert some additional calls to is_bad_inode()
- Adjust filename, context]
--- fs/fuse/acl.c | 6 ++++++ fs/fuse/dir.c | 40 +++++++++++++++++++++++++++++++++++----- fs/fuse/file.c | 27 ++++++++++++++++++--------- fs/fuse/fuse_i.h | 12 ++++++++++++ fs/fuse/inode.c | 2 +- fs/fuse/xattr.c | 9 +++++++++ 6 files changed, 81 insertions(+), 15 deletions(-)
fs/fuse/acl.c +6 -0
@@ -19,6 +19,9 @@ struct posix_acl *fuse_get_acl(struct invoid *value =NULL ;struct posix_acl *acl; +if (fuse_is_bad (inode)) +return ERR_PTR (-EIO ); +if (!fc->posix_acl || fc->no_getxattr)return NULL ;
@@ -53,6 +56,9 @@ int fuse_set_acl(struct inode *inode, stconst char *name;int ret; +if (fuse_is_bad (inode)) +return -EIO ; +if (!fc->posix_acl || fc->no_setxattr)return -EOPNOTSUPP ;
fs/fuse/dir.c +35 -5
@@ -187,7 +187,7 @@ static int fuse_dentry_revalidate(structint ret; inode =d_inode_rcu (entry); -if (inode &&is_bad_inode (inode)) +if (inode &&fuse_is_bad (inode)) goto invalid;else if (time_before64 (fuse_dentry_time (entry),get_jiffies_64 ()) || (flags &LOOKUP_REVAL )) {
@@ -364,6 +364,9 @@ static struct dentry *fuse_lookup(structbool outarg_valid = true;bool locked; +if (fuse_is_bad (dir)) +return ERR_PTR (-EIO ); + locked =fuse_lock_inode (dir); err =fuse_lookup_name (dir->i_sb,get_node_id (dir), &entry->d_name, &outarg, &inode);
@@ -504,6 +507,9 @@ static int fuse_atomic_open(struct inodestruct fuse_conn *fc =get_fuse_conn (dir);struct dentry *res =NULL ; +if (fuse_is_bad (dir)) +return -EIO ; +if (d_in_lookup (entry)) { res =fuse_lookup (dir, entry,0 );if (IS_ERR (res))
@@ -551,6 +557,9 @@ static int create_new_entry(struct fuse_int err;struct fuse_forget_link *forget; +if (fuse_is_bad (dir)) +return -EIO ; + forget =fuse_alloc_forget ();if (!forget)return -ENOMEM ;
@@ -672,6 +681,9 @@ static int fuse_unlink(struct inode *dirstruct fuse_conn *fc =get_fuse_conn (dir);FUSE_ARGS (args); +if (fuse_is_bad (dir)) +return -EIO ; + args.in.h.opcode =FUSE_UNLINK ; args.in.h.nodeid =get_node_id (dir); args.in.numargs =1 ;
@@ -708,6 +720,9 @@ static int fuse_rmdir(struct inode *dir,struct fuse_conn *fc =get_fuse_conn (dir);FUSE_ARGS (args); +if (fuse_is_bad (dir)) +return -EIO ; + args.in.h.opcode =FUSE_RMDIR ; args.in.h.nodeid =get_node_id (dir); args.in.numargs =1 ;
@@ -786,6 +801,9 @@ static int fuse_rename2(struct inode *olstruct fuse_conn *fc =get_fuse_conn (olddir);int err; +if (fuse_is_bad (olddir)) +return -EIO ; +if (flags & ~(RENAME_NOREPLACE |RENAME_EXCHANGE ))return -EINVAL ;
@@ -921,7 +939,7 @@ static int fuse_do_getattr(struct inodeif (!err) {if (fuse_invalid_attr (&outarg.attr) || (inode->i_mode ^ outarg.attr.mode) &S_IFMT ) { -make_bad_inode (inode); +fuse_make_bad (inode); err = -EIO ; }else { fuse_change_attributes(inode, &outarg.attr,
@@ -1110,6 +1128,9 @@ static int fuse_permission(struct inodebool refreshed = false;int err =0 ; +if (fuse_is_bad (inode)) +return -EIO ; +if (!fuse_allow_current_process (fc))return -EACCES ;
@@ -1247,7 +1268,7 @@ retry:dput (dentry); goto retry; } -if (is_bad_inode (inode)) { +if (fuse_is_bad (inode)) {dput (dentry);return -EIO ; }
@@ -1345,7 +1366,7 @@ static int fuse_readdir(struct file *filu64 attr_version =0 ;bool locked; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return -EIO ; req =fuse_get_req (fc,1 );
@@ -1405,6 +1426,9 @@ static const char *fuse_get_link(structif (!dentry)return ERR_PTR (-ECHILD ); +if (fuse_is_bad (inode)) +return ERR_PTR (-EIO ); + link =kmalloc (PAGE_SIZE ,GFP_KERNEL );if (!link)return ERR_PTR (-ENOMEM );
@@ -1703,7 +1727,7 @@ int fuse_do_setattr(struct dentry *dentrif (fuse_invalid_attr (&outarg.attr) || (inode->i_mode ^ outarg.attr.mode) &S_IFMT ) { -make_bad_inode (inode); +fuse_make_bad (inode); err = -EIO ; goto error; }
@@ -1759,6 +1783,9 @@ static int fuse_setattr(struct dentry *estruct file *file = (attr->ia_valid &ATTR_FILE ) ? attr->ia_file :NULL ;int ret; +if (fuse_is_bad (inode)) +return -EIO ; +if (!fuse_allow_current_process (get_fuse_conn (inode)))return -EACCES ;
@@ -1817,6 +1844,9 @@ static int fuse_getattr(const struct patstruct inode *inode =d_inode (path->dentry);struct fuse_conn *fc =get_fuse_conn (inode); +if (fuse_is_bad (inode)) +return -EIO ; +if (!fuse_allow_current_process (fc))return -EACCES ;
fs/fuse/file.c +18 -9
@@ -206,6 +206,9 @@ int fuse_open_common(struct inode *inode fc->atomic_o_trunc && fc->writeback_cache; +if (fuse_is_bad (inode)) +return -EIO ; + err =generic_file_open (inode, file);if (err)return err;
@@ -407,7 +410,7 @@ static int fuse_flush(struct file *file,struct fuse_flush_in inarg;int err; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return -EIO ;if (fc->no_flush)
@@ -455,7 +458,7 @@ int fuse_fsync_common(struct file *file,struct fuse_fsync_in inarg;int err; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return -EIO ;inode_lock (inode);
@@ -770,7 +773,7 @@ static int fuse_readpage(struct file *fiint err; err = -EIO ; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode)) goto out; err =fuse_do_readpage (file, page);
@@ -897,7 +900,7 @@ static int fuse_readpages(struct file *fint nr_alloc =min_t (unsigned, nr_pages,FUSE_MAX_PAGES_PER_REQ ); err = -EIO ; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode)) goto out; data.file = file;
@@ -927,6 +930,9 @@ static ssize_t fuse_file_read_iter(strucstruct inode *inode = iocb->ki_filp->f_mapping->host;struct fuse_conn *fc =get_fuse_conn (inode); +if (fuse_is_bad (inode)) +return -EIO ; +/* * In auto invalidate mode, always update attributes on read. * Otherwise, only update if we attempt to read past EOF (to ensure
@@ -1127,7 +1133,7 @@ static ssize_t fuse_perform_write(structint err =0 ;ssize_t res =0 ; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return -EIO ;if (inode->i_size < pos +iov_iter_count (ii))
@@ -1184,6 +1190,9 @@ static ssize_t fuse_file_write_iter(strussize_t err;loff_t endbyte =0 ; +if (fuse_is_bad (inode)) +return -EIO ; +if (get_fuse_conn (inode)->writeback_cache) {/* Update size (EOF optimization) and mode (SUID clearing) */ err =fuse_update_attributes (mapping->host, file);
@@ -1420,7 +1429,7 @@ static ssize_t __fuse_direct_read(structssize_t res;struct inode *inode =file_inode (io->iocb->ki_filp); -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return -EIO ; res =fuse_direct_io (io, iter, ppos,0 );
@@ -1442,7 +1451,7 @@ static ssize_t fuse_direct_write_iter(ststruct fuse_io_priv io =FUSE_IO_PRIV_SYNC (iocb);ssize_t res; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return -EIO ;/* Don't allow parallel writes to the same file */
@@ -1916,7 +1925,7 @@ static int fuse_writepages(struct addresint err; err = -EIO ; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode)) goto out; data.inode = inode;
@@ -2701,7 +2710,7 @@ long fuse_ioctl_common(struct file *fileif (!fuse_allow_current_process (fc))return -EACCES ; -if (is_bad_inode (inode)) +if (fuse_is_bad (inode))return -EIO ;return fuse_do_ioctl (file, cmd, arg, flags);
fs/fuse/fuse_i.h +12 -0
@@ -117,6 +117,8 @@ enum {FUSE_I_INIT_RDPLUS ,/** An operation changing file size is in progress */ FUSE_I_SIZE_UNSTABLE , +/* Bad inode */ + FUSE_I_BAD, };struct fuse_conn ;
@@ -687,6 +689,16 @@ static inline u64 get_node_id(struct inoreturn get_fuse_inode (inode)->nodeid; } +static inline void fuse_make_bad (struct inode *inode) +{ +set_bit (FUSE_I_BAD , &get_fuse_inode (inode)->state); +} + +static inline bool fuse_is_bad (struct inode *inode) +{ +return unlikely (test_bit (FUSE_I_BAD , &get_fuse_inode (inode)->state)); +} +/** Device operations */ extern const struct file_operations fuse_dev_operations;
fs/fuse/inode.c +1 -1
@@ -317,7 +317,7 @@ struct inode *fuse_iget(struct super_blounlock_new_inode (inode); }else if ((inode->i_mode ^ attr->mode) &S_IFMT ) {/* Inode has changed type, any I/O on the old should fail */ -make_bad_inode (inode); +fuse_make_bad (inode);iput (inode); goto retry; }
fs/fuse/xattr.c +9 -0
@@ -113,6 +113,9 @@ ssize_t fuse_listxattr(struct dentry *enstruct fuse_getxattr_out outarg;ssize_t ret; +if (fuse_is_bad (inode)) +return -EIO ; +if (!fuse_allow_current_process (fc))return -EACCES ;
@@ -178,6 +181,9 @@ static int fuse_xattr_get(const struct x struct dentry *dentry, struct inode *inode, const char *name, void *value, size_t size) { + if (fuse_is_bad(inode)) + return -EIO; +return fuse_getxattr (inode, name, value, size); }
@@ -186,6 +192,9 @@ static int fuse_xattr_set(const struct x const char *name, const void *value, size_t size, int flags) { + if (fuse_is_bad(inode)) + return -EIO; +if (!value)return fuse_removexattr (inode, name);
Greg Kroah-Hartman
maintainerPATCH 183/186 fuse: fix live lock in fuse_iget()
In reply to Greg Kroah-HartmanFrom: Amir Goldstein <[email protected]>
commit 775c5033a0d164622d9d10dd0f0a5531639ed3ed upstream.
Commit 5d069dbe8aaf ("fuse: fix bad inode") replaced make_bad_inode() in fuse_iget() with a private implementation fuse_make_bad().
The private implementation fails to remove the bad inode from inode cache, so the retry loop with iget5_locked() finds the same bad inode and marks it bad forever.
kmsg snip:
[ ] rcu: INFO: rcu_sched self-detected stall on CPU
...
[ ] ? bit_wait_io+0x50/0x50 [ ] ? fuse_init_file_inode+0x70/0x70 [ ] ? find_inode.isra.32+0x60/0xb0 [ ] ? fuse_init_file_inode+0x70/0x70 [ ] ilookup5_nowait+0x65/0x90 [ ] ? fuse_init_file_inode+0x70/0x70 [ ] ilookup5.part.36+0x2e/0x80 [ ] ? fuse_init_file_inode+0x70/0x70 [ ] ? fuse_inode_eq+0x20/0x20 [ ] iget5_locked+0x21/0x80 [ ] ? fuse_inode_eq+0x20/0x20 [ ] fuse_iget+0x96/0x1b0
--- fs/fuse/fuse_i.h | 1 + 1 file changed, 1 insertion(+)
fs/fuse/fuse_i.h +1 -0
@@ -691,6 +691,7 @@ static inline u64 get_node_id(struct inostatic inline void fuse_make_bad (struct inode *inode) { +remove_inode_hash (inode);set_bit (FUSE_I_BAD , &get_fuse_inode (inode)->state); }
Greg Kroah-Hartman
maintainerPATCH 184/186 gianfar: simplify FCS handling and fix memory leak
In reply to Greg Kroah-HartmanFrom: Andy Spencer <[email protected]>
commit d903ec77118c09f93a610b384d83a6df33a64fe6 upstream.
Previously, buffer descriptors containing only the frame check sequence (FCS) were skipped and not added to the skb. However, the page reference count was still incremented, leading to a memory leak.
Fixing this inside gfar_add_rx_frag() is difficult due to reserved memory handling and page reuse. Instead, move the FCS handling to gfar_process_frame() and trim off the FCS before passing the skb up the networking stack.
--- drivers/net/ethernet/freescale/gianfar.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-)
drivers/net/ethernet/freescale/gianfar.c +7 -16
@@ -2936,29 +2936,17 @@ static bool gfar_add_rx_frag(struct gfar {int size = lstatus &BD_LENGTH_MASK ;struct page *page = rxb->page; -bool last = !!(lstatus &BD_LFLAG (RXBD_LAST )); - -/* Remove the FCS from the packet length */ -if (last) - size -=ETH_FCS_LEN ;if (likely (first)) {skb_put (skb, size); }else {/* the last fragments' length contains the full frame length */ -if (last) +if (lstatus &BD_LFLAG (RXBD_LAST )) size -= skb->len; -/* Add the last fragment if it contains something other than -* the FCS, otherwise drop it and trim off any part of the FCS -* that was already received. -*/ -if (size >0 ) -skb_add_rx_frag (skb,skb_shinfo (skb)->nr_frags, page, - rxb->page_offset +RXBUF_ALIGNMENT , - size,GFAR_RXB_TRUESIZE ); -else if (size <0 ) -pskb_trim (skb, skb->len + size); +skb_add_rx_frag (skb,skb_shinfo (skb)->nr_frags, page, + rxb->page_offset +RXBUF_ALIGNMENT , + size,GFAR_RXB_TRUESIZE ); }/* try reuse page */
@@ -3071,6 +3059,9 @@ static void gfar_process_frame(struct neif (priv->padding)skb_pull (skb, priv->padding); +/* Trim off the FCS */ +pskb_trim (skb, skb->len -ETH_FCS_LEN ); +if (ndev->features &NETIF_F_RXCSUM )gfar_rx_checksum (skb, fcb);
Greg Kroah-Hartman
maintainerPATCH 185/186 gianfar: fix jumbo packets+napi+rx overrun crash
In reply to Greg Kroah-HartmanFrom: Michael Braun <[email protected]>
commit d8861bab48b6c1fc3cdbcab8ff9d1eaea43afe7f upstream.
When using jumbo packets and overrunning rx queue with napi enabled, the following sequence is observed in gfar_add_rx_frag:
| lstatus | | skb | t | lstatus, size, flags | first | len, data_len, *ptr | ---+--------------------------------------+-------+-----------------------+ 13 | 18002348, 9032, INTERRUPT LAST | 0 | 9600, 8000, f554c12e | 12 | 10000640, 1600, INTERRUPT | 0 | 8000, 6400, f554c12e | 11 | 10000640, 1600, INTERRUPT | 0 | 6400, 4800, f554c12e | 10 | 10000640, 1600, INTERRUPT | 0 | 4800, 3200, f554c12e | 09 | 10000640, 1600, INTERRUPT | 0 | 3200, 1600, f554c12e | 08 | 14000640, 1600, INTERRUPT FIRST | 0 | 1600, 0, f554c12e | 07 | 14000640, 1600, INTERRUPT FIRST | 1 | 0, 0, f554c12e | 06 | 1c000080, 128, INTERRUPT LAST FIRST | 1 | 0, 0, abf3bd6e | 05 | 18002348, 9032, INTERRUPT LAST | 0 | 8000, 6400, c5a57780 | 04 | 10000640, 1600, INTERRUPT | 0 | 6400, 4800, c5a57780 | 03 | 10000640, 1600, INTERRUPT | 0 | 4800, 3200, c5a57780 | 02 | 10000640, 1600, INTERRUPT | 0 | 3200, 1600, c5a57780 | 01 | 10000640, 1600, INTERRUPT | 0 | 1600, 0, c5a57780 | 00 | 14000640, 1600, INTERRUPT FIRST | 1 | 0, 0, c5a57780 |
So at t=7 a new packets is started but not finished, probably due to rx overrun - but rx overrun is not indicated in the flags. Instead a new packets starts at t=8. This results in skb->len to exceed size for the LAST fragment at t=13 and thus a negative fragment size added to the skb.
This then crashes:
kernel BUG at include/linux/skbuff.h:2277!
Oops: Exception in kernel mode, sig: 5 [#1] ... NIP [c04689f4] skb_pull+0x2c/0x48 LR [c03f62ac] gfar_clean_rx_ring+0x2e4/0x844 Call Trace: [ec4bfd38] [c06a84c4] _raw_spin_unlock_irqrestore+0x60/0x7c (unreliable) [ec4bfda8] [c03f6a44] gfar_poll_rx_sq+0x48/0xe4 [ec4bfdc8] [c048d504] __napi_poll+0x54/0x26c [ec4bfdf8] [c048d908] net_rx_action+0x138/0x2c0 [ec4bfe68] [c06a8f34] __do_softirq+0x3a4/0x4fc [ec4bfed8] [c0040150] run_ksoftirqd+0x58/0x70 [ec4bfee8] [c0066ecc] smpboot_thread_fn+0x184/0x1cc [ec4bff08] [c0062718] kthread+0x140/0x144 [ec4bff38] [c0012350] ret_from_kernel_thread+0x14/0x1c
This patch fixes this by checking for computed LAST fragment size, so a negative sized fragment is never added.
In order to prevent the newer rx frame from getting corrupted, the FIRST flag is checked to discard the incomplete older frame.
--- drivers/net/ethernet/freescale/gianfar.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
drivers/net/ethernet/freescale/gianfar.c +15 -0
@@ -2944,6 +2944,10 @@ static bool gfar_add_rx_frag(struct gfarif (lstatus &BD_LFLAG (RXBD_LAST )) size -= skb->len; +WARN (size <0 ,"gianfar: rx fragment size underflow" ); +if (size <0 ) +return false; +skb_add_rx_frag (skb,skb_shinfo (skb)->nr_frags, page, rxb->page_offset +RXBUF_ALIGNMENT , size,GFAR_RXB_TRUESIZE );
@@ -3105,6 +3109,17 @@ int gfar_clean_rx_ring(struct gfar_priv_if (lstatus &BD_LFLAG (RXBD_EMPTY ))break ; +/* lost RXBD_LAST descriptor due to overrun */ +if (skb && + (lstatus &BD_LFLAG (RXBD_FIRST ))) { +/* discard faulty buffer */ +dev_kfree_skb (skb); + skb =NULL ; + rx_queue->stats.rx_dropped++; + +/* can continue normally */ + } +/* order rx buffer descriptor reads */ rmb ();
Greg Kroah-Hartman
maintainerPATCH 186/186 NFSv4: Initialise connection to the server in nfs4_alloc_client()
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
commit dd99e9f98fbf423ff6d365b37a98e8879170f17c upstream.
Set up the connection to the NFSv4 server in nfs4_alloc_client(), before we've added the struct nfs_client to the net-namespace's nfs_client_list so that a downed server won't cause other mounts to hang in the trunking detection code.
--- fs/nfs/nfs4client.c | 82 ++++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 40 deletions(-)
fs/nfs/nfs4client.c +42 -40
@@ -177,8 +177,11 @@ void nfs40_shutdown_client(struct nfs_clstruct nfs_client *nfs4_alloc_client (const struct nfs_client_initdata *cl_init) { -int err; +char buf[INET6_ADDRSTRLEN +1 ]; +const char *ip_addr = cl_init->ip_addr;struct nfs_client *clp =nfs_alloc_client (cl_init); +int err; +if (IS_ERR (clp))return clp;
@@ -202,6 +205,44 @@ struct nfs_client *nfs4_alloc_client(con#if IS_ENABLED (CONFIG_NFS_V4_1 )init_waitqueue_head (&clp->cl_lock_waitq);#endif + +if (cl_init->minorversion !=0 ) +__set_bit (NFS_CS_INFINITE_SLOTS , &clp->cl_flags); +__set_bit (NFS_CS_DISCRTRY , &clp->cl_flags); +__set_bit (NFS_CS_NO_RETRANS_TIMEOUT , &clp->cl_flags); + +/* +* Set up the connection to the server before we add add to the +* global list. +*/ + err =nfs_create_rpc_client (clp, cl_init,RPC_AUTH_GSS_KRB5I ); +if (err == -EINVAL ) + err =nfs_create_rpc_client (clp, cl_init,RPC_AUTH_UNIX ); +if (err <0 ) + goto error; + +/* If no clientaddr= option was specified, find a usable cb address */ +if (ip_addr ==NULL ) { +struct sockaddr_storage cb_addr; +struct sockaddr *sap = (struct sockaddr *)&cb_addr; + + err =rpc_localaddr (clp->cl_rpcclient, sap,sizeof (cb_addr)); +if (err <0 ) + goto error; + err =rpc_ntop (sap, buf,sizeof (buf)); +if (err <0 ) + goto error; + ip_addr = (const char *)buf; + } +strlcpy (clp->cl_ipaddr, ip_addr,sizeof (clp->cl_ipaddr)); + + err =nfs_idmap_new (clp); +if (err <0 ) { +dprintk ("%s: failed to create idmapper. Error = %d\n" , + __func__, err); + goto error; + } +__set_bit (NFS_CS_IDMAP , &clp->cl_res_state);return clp; error:
@@ -354,8 +395,6 @@ static int nfs4_init_client_minor_versiostruct nfs_client *nfs4_init_client (struct nfs_client *clp,const struct nfs_client_initdata *cl_init) { -char buf[INET6_ADDRSTRLEN +1 ]; -const char *ip_addr = cl_init->ip_addr;struct nfs_client *old;int error;
@@ -363,43 +402,6 @@ struct nfs_client *nfs4_init_client(stru/* the client is initialised already */ return clp; -/* Check NFS protocol revision and initialize RPC op vector */ - clp->rpc_ops = &nfs_v4_clientops; - -if (clp->cl_minorversion !=0 ) -__set_bit (NFS_CS_INFINITE_SLOTS , &clp->cl_flags); -__set_bit (NFS_CS_DISCRTRY , &clp->cl_flags); -__set_bit (NFS_CS_NO_RETRANS_TIMEOUT , &clp->cl_flags); - - error =nfs_create_rpc_client (clp, cl_init,RPC_AUTH_GSS_KRB5I ); -if (error == -EINVAL ) - error =nfs_create_rpc_client (clp, cl_init,RPC_AUTH_UNIX ); -if (error <0 ) - goto error; - -/* If no clientaddr= option was specified, find a usable cb address */ -if (ip_addr ==NULL ) { -struct sockaddr_storage cb_addr; -struct sockaddr *sap = (struct sockaddr *)&cb_addr; - - error =rpc_localaddr (clp->cl_rpcclient, sap,sizeof (cb_addr)); -if (error <0 ) - goto error; - error =rpc_ntop (sap, buf,sizeof (buf)); -if (error <0 ) - goto error; - ip_addr = (const char *)buf; - } -strlcpy (clp->cl_ipaddr, ip_addr,sizeof (clp->cl_ipaddr)); - - error =nfs_idmap_new (clp); -if (error <0 ) { -dprintk ("%s: failed to create idmapper. Error = %d\n" , - __func__, error); - goto error; - } -__set_bit (NFS_CS_IDMAP , &clp->cl_res_state); - error =nfs4_init_client_minor_version (clp);if (error <0 ) goto error;
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.263 release. There are 186 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 26 Jan 2022 18:39:11 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.263-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.14.y
and the diffstat can be found below.thanks,
greg k-h
Following patch caused build failures on arm imx_v6_v7_defconfig
Quoted 2 lines
Lucas Stach <[email protected]>
drm/etnaviv: limit submit sizes
build/clang-nightly-imx_v6_v7_defconfig
build/gcc-11-imx_v6_v7_defconfig
build/gcc-10-imx_v6_v7_defconfig
build/clang-11-imx_v6_v7_defconfig
build/clang-12-imx_v6_v7_defconfig
build/clang-13-imx_v6_v7_defconfig
Error:
-------
make --silent --keep-going --jobs=8 ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf- 'CC=sccache
arm-linux-gnueabihf-gcc' 'HOSTCC=sccache gcc'
drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c: In function 'etnaviv_ioctl_gem_submit':drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c:345:37: error: 'struct drm_etnaviv_gem_submit' has no member named 'nr_pmrs'; did you mean 'nr_bos'?
args->nr_bos > SZ_64K || args->nr_pmrs > 128) {
^~~~~~~
nr_bosmake[5]: *** [scripts/Makefile.build:329:drivers/gpu/drm/etnaviv/etnaviv_gem_submit.o] Error 1
--
Linaro LKFT
https://lkft.linaro.org
Quoted 18 lines · Naresh Kamboju
Quoted 15 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.263 release. There are 186 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 26 Jan 2022 18:39:11 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.263-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.14.y
and the diffstat can be found below.
Quoted 8 lines
Quoted 3 lines
thanks,
greg k-h
Following patch caused build failures on arm
imx_v6_v7_defconfigQuoted 2 lines
Lucas Stach <[email protected]>
drm/etnaviv: limit submit sizes
The following patch might be missing,
commit 05916bed11b6d4c61b473a76220151a7d0547164
Christian Gmeiner <[email protected]>
drm/etnaviv: add uapi for perfmon feature
Quoted 30 lines
build/clang-nightly-imx_v6_v7_defconfig
build/gcc-11-imx_v6_v7_defconfig
build/gcc-10-imx_v6_v7_defconfig
build/clang-11-imx_v6_v7_defconfig
build/clang-12-imx_v6_v7_defconfig
build/clang-13-imx_v6_v7_defconfigError:
-------
make --silent --keep-going --jobs=8 ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf- 'CC=sccache
arm-linux-gnueabihf-gcc' 'HOSTCC=sccache gcc'
drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c: In function 'etnaviv_ioctl_gem_submit':drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c:345:37: error: 'structdrm_etnaviv_gem_submit' has no member named 'nr_pmrs'; did you mean 'nr_bos'?args->nr_bos > SZ_64K || args->nr_pmrs > 128) { ^~~~~~~ nr_bosmake[5]: *** [
scripts/Makefile.build:329:drivers/gpu/drm/etnaviv/etnaviv_gem_submit.o] Error 1--
Linaro LKFT
https://lkft.linaro.org
Greg Kroah-Hartman
maintainerQuoted 25 lines · Naresh Kamboju
Quoted 24 lines · Naresh Kamboju
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.263 release. There are 186 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 26 Jan 2022 18:39:11 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.263-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.14.y
and the diffstat can be found below.thanks,
greg k-h
Following patch caused build failures on arm
imx_v6_v7_defconfig
Quoted 10 lines
Quoted 2 lines
Quoted 2 lines
Lucas Stach <[email protected]>
drm/etnaviv: limit submit sizesThe following patch might be missing,
commit
05916bed11b6d4c61b473a76220151a7d0547164
Christian Gmeiner <[email protected]>
drm/etnaviv: add uapi for perfmon feature
Thanks, I'll drop the limit commit from 4.14 and older as it doesn't seem like this option is present on kernels older than 4.15.
thanks,
greg k-h