Skip to content

Commit 76b6905

Browse files
committed
Merge tag 'mm-hotfixes-stable-2025-03-17-20-09' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull misc hotfixes from Andrew Morton: "15 hotfixes. 7 are cc:stable and the remainder address post-6.13 issues or aren't considered necessary for -stable kernels. 13 are for MM and the other two are for squashfs and procfs. All are singletons. Please see the individual changelogs for details" * tag 'mm-hotfixes-stable-2025-03-17-20-09' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: mm/page_alloc: fix memory accept before watermarks gets initialized mm: decline to manipulate the refcount on a slab page memcg: drain obj stock on cpu hotplug teardown mm/huge_memory: drop beyond-EOF folios with the right number of refs selftests/mm: run_vmtests.sh: fix half_ufd_size_MB calculation mm: fix error handling in __filemap_get_folio() with FGP_NOWAIT mm: memcontrol: fix swap counter leak from offline cgroup mm/vma: do not register private-anon mappings with khugepaged during mmap squashfs: fix invalid pointer dereference in squashfs_cache_delete mm/migrate: fix shmem xarray update during migration mm/hugetlb: fix surplus pages in dissolve_free_huge_page() mm/damon/core: initialize damos->walk_completed in damon_new_scheme() mm/damon: respect core layer filters' allowance decision on ops layer filemap: move prefaulting out of hot write path proc: fix UAF in proc_get_inode()
2 parents 9130945 + 800f105 commit 76b6905

File tree

20 files changed

+132
-43
lines changed

20 files changed

+132
-43
lines changed

fs/proc/generic.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,10 +559,16 @@ struct proc_dir_entry *proc_create_reg(const char *name, umode_t mode,
559559
return p;
560560
}
561561

562-
static inline void pde_set_flags(struct proc_dir_entry *pde)
562+
static void pde_set_flags(struct proc_dir_entry *pde)
563563
{
564564
if (pde->proc_ops->proc_flags & PROC_ENTRY_PERMANENT)
565565
pde->flags |= PROC_ENTRY_PERMANENT;
566+
if (pde->proc_ops->proc_read_iter)
567+
pde->flags |= PROC_ENTRY_proc_read_iter;
568+
#ifdef CONFIG_COMPAT
569+
if (pde->proc_ops->proc_compat_ioctl)
570+
pde->flags |= PROC_ENTRY_proc_compat_ioctl;
571+
#endif
566572
}
567573

568574
struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
@@ -626,6 +632,7 @@ struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,
626632
p->proc_ops = &proc_seq_ops;
627633
p->seq_ops = ops;
628634
p->state_size = state_size;
635+
pde_set_flags(p);
629636
return proc_register(parent, p);
630637
}
631638
EXPORT_SYMBOL(proc_create_seq_private);
@@ -656,6 +663,7 @@ struct proc_dir_entry *proc_create_single_data(const char *name, umode_t mode,
656663
return NULL;
657664
p->proc_ops = &proc_single_ops;
658665
p->single_show = show;
666+
pde_set_flags(p);
659667
return proc_register(parent, p);
660668
}
661669
EXPORT_SYMBOL(proc_create_single_data);

fs/proc/inode.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -656,13 +656,13 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
656656

657657
if (S_ISREG(inode->i_mode)) {
658658
inode->i_op = de->proc_iops;
659-
if (de->proc_ops->proc_read_iter)
659+
if (pde_has_proc_read_iter(de))
660660
inode->i_fop = &proc_iter_file_ops;
661661
else
662662
inode->i_fop = &proc_reg_file_ops;
663663
#ifdef CONFIG_COMPAT
664-
if (de->proc_ops->proc_compat_ioctl) {
665-
if (de->proc_ops->proc_read_iter)
664+
if (pde_has_proc_compat_ioctl(de)) {
665+
if (pde_has_proc_read_iter(de))
666666
inode->i_fop = &proc_iter_file_ops_compat;
667667
else
668668
inode->i_fop = &proc_reg_file_ops_compat;

fs/proc/internal.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ static inline void pde_make_permanent(struct proc_dir_entry *pde)
8585
pde->flags |= PROC_ENTRY_PERMANENT;
8686
}
8787

88+
static inline bool pde_has_proc_read_iter(const struct proc_dir_entry *pde)
89+
{
90+
return pde->flags & PROC_ENTRY_proc_read_iter;
91+
}
92+
93+
static inline bool pde_has_proc_compat_ioctl(const struct proc_dir_entry *pde)
94+
{
95+
#ifdef CONFIG_COMPAT
96+
return pde->flags & PROC_ENTRY_proc_compat_ioctl;
97+
#else
98+
return false;
99+
#endif
100+
}
101+
88102
extern struct kmem_cache *proc_dir_entry_cache;
89103
void pde_free(struct proc_dir_entry *pde);
90104

fs/squashfs/cache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ void squashfs_cache_delete(struct squashfs_cache *cache)
198198
{
199199
int i, j;
200200

201-
if (cache == NULL)
201+
if (IS_ERR(cache) || cache == NULL)
202202
return;
203203

204204
for (i = 0; i < cache->entries; i++) {

include/linux/damon.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,11 @@ struct damos {
470470
unsigned long next_apply_sis;
471471
/* informs if ongoing DAMOS walk for this scheme is finished */
472472
bool walk_completed;
473+
/*
474+
* If the current region in the filtering stage is allowed by core
475+
* layer-handled filters. If true, operations layer allows it, too.
476+
*/
477+
bool core_filters_allowed;
473478
/* public: */
474479
struct damos_quota quota;
475480
struct damos_watermarks wmarks;

include/linux/mm.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1458,7 +1458,10 @@ static inline void folio_get(struct folio *folio)
14581458

14591459
static inline void get_page(struct page *page)
14601460
{
1461-
folio_get(page_folio(page));
1461+
struct folio *folio = page_folio(page);
1462+
if (WARN_ON_ONCE(folio_test_slab(folio)))
1463+
return;
1464+
folio_get(folio);
14621465
}
14631466

14641467
static inline __must_check bool try_get_page(struct page *page)
@@ -1552,6 +1555,9 @@ static inline void put_page(struct page *page)
15521555
{
15531556
struct folio *folio = page_folio(page);
15541557

1558+
if (folio_test_slab(folio))
1559+
return;
1560+
15551561
/*
15561562
* For some devmap managed pages we need to catch refcount transition
15571563
* from 2 to 1:

include/linux/proc_fs.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@ enum {
2020
* If in doubt, ignore this flag.
2121
*/
2222
#ifdef MODULE
23-
PROC_ENTRY_PERMANENT = 0U,
23+
PROC_ENTRY_PERMANENT = 0U,
2424
#else
25-
PROC_ENTRY_PERMANENT = 1U << 0,
25+
PROC_ENTRY_PERMANENT = 1U << 0,
2626
#endif
27+
28+
PROC_ENTRY_proc_read_iter = 1U << 1,
29+
PROC_ENTRY_proc_compat_ioctl = 1U << 2,
2730
};
2831

2932
struct proc_ops {

include/linux/swap_cgroup.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#if defined(CONFIG_MEMCG) && defined(CONFIG_SWAP)
88

9-
extern void swap_cgroup_record(struct folio *folio, swp_entry_t ent);
9+
extern void swap_cgroup_record(struct folio *folio, unsigned short id, swp_entry_t ent);
1010
extern unsigned short swap_cgroup_clear(swp_entry_t ent, unsigned int nr_ents);
1111
extern unsigned short lookup_swap_cgroup_id(swp_entry_t ent);
1212
extern int swap_cgroup_swapon(int type, unsigned long max_pages);
@@ -15,7 +15,7 @@ extern void swap_cgroup_swapoff(int type);
1515
#else
1616

1717
static inline
18-
void swap_cgroup_record(struct folio *folio, swp_entry_t ent)
18+
void swap_cgroup_record(struct folio *folio, unsigned short id, swp_entry_t ent)
1919
{
2020
}
2121

lib/iov_iter.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,8 +1190,12 @@ static ssize_t __iov_iter_get_pages_alloc(struct iov_iter *i,
11901190
if (!n)
11911191
return -ENOMEM;
11921192
p = *pages;
1193-
for (int k = 0; k < n; k++)
1194-
get_page(p[k] = page + k);
1193+
for (int k = 0; k < n; k++) {
1194+
struct folio *folio = page_folio(page);
1195+
p[k] = page + k;
1196+
if (!folio_test_slab(folio))
1197+
folio_get(folio);
1198+
}
11951199
maxsize = min_t(size_t, maxsize, n * PAGE_SIZE - *start);
11961200
i->count -= maxsize;
11971201
i->iov_offset += maxsize;

mm/damon/core.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
373373
* or damon_attrs are updated.
374374
*/
375375
scheme->next_apply_sis = 0;
376+
scheme->walk_completed = false;
376377
INIT_LIST_HEAD(&scheme->filters);
377378
scheme->stat = (struct damos_stat){};
378379
INIT_LIST_HEAD(&scheme->list);
@@ -1429,9 +1430,13 @@ static bool damos_filter_out(struct damon_ctx *ctx, struct damon_target *t,
14291430
{
14301431
struct damos_filter *filter;
14311432

1433+
s->core_filters_allowed = false;
14321434
damos_for_each_filter(filter, s) {
1433-
if (damos_filter_match(ctx, t, r, filter))
1435+
if (damos_filter_match(ctx, t, r, filter)) {
1436+
if (filter->allow)
1437+
s->core_filters_allowed = true;
14341438
return !filter->allow;
1439+
}
14351440
}
14361441
return false;
14371442
}

0 commit comments

Comments
 (0)