mirror of
https://github.com/torvalds/linux.git
synced 2025-11-01 09:09:47 +02:00
mm: update coredump logic to correctly use bitmap mm flags
The coredump logic is slightly different from other users in that it both stores mm flags and additionally sets and gets using masks. Since the MMF_DUMPABLE_* flags must remain as they are for uABI reasons, and of course these are within the first 32-bits of the flags, it is reasonable to provide access to these in the same fashion so this logic can all still keep working as it has been. Therefore, introduce coredump-specific helpers __mm_flags_get_dumpable() and __mm_flags_set_mask_dumpable() for this purpose, and update all core dump users of mm flags to use these. [lorenzo.stoakes@oracle.com: abstract set_mask_bits() invocation to mm_types.h to satisfy ARC] Link: https://lkml.kernel.org/r/0e7ad263-1ff7-446d-81fe-97cff9c0e7ed@lucifer.local Link: https://lkml.kernel.org/r/2a5075f7e3c5b367d988178c79a3063d12ee53a9.1755012943.git.lorenzo.stoakes@oracle.com Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com> Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Reviewed-by: Christian Brauner <brauner@kernel.org> Acked-by: David Hildenbrand <david@redhat.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Gordeev <agordeev@linux.ibm.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Andreas Larsson <andreas@gaisler.com> Cc: Andy Lutomirski <luto@kernel.org> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Baolin Wang <baolin.wang@linux.alibaba.com> Cc: Barry Song <baohua@kernel.org> Cc: Ben Segall <bsegall@google.com> Cc: Borislav Betkov <bp@alien8.de> Cc: Chengming Zhou <chengming.zhou@linux.dev> Cc: Christian Borntraeger <borntraeger@linux.ibm.com> Cc: David Rientjes <rientjes@google.com> Cc: David S. Miller <davem@davemloft.net> Cc: Dev Jain <dev.jain@arm.com> Cc: Dietmar Eggemann <dietmar.eggemann@arm.com> Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com> Cc: Heiko Carstens <hca@linux.ibm.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jan Kara <jack@suse.cz> Cc: Jann Horn <jannh@google.com> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Jiri Olsa <jolsa@kernel.org> Cc: John Hubbard <jhubbard@nvidia.com> Cc: Juri Lelli <juri.lelli@redhat.com> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Kees Cook <kees@kernel.org> Cc: Marc Rutland <mark.rutland@arm.com> Cc: Mariano Pache <npache@redhat.com> Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org> Cc: Mateusz Guzik <mjguzik@gmail.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Mel Gorman <mgorman <mgorman@suse.de> Cc: Michal Hocko <mhocko@suse.com> Cc: Namhyung kim <namhyung@kernel.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Peter Xu <peterx@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ryan Roberts <ryan.roberts@arm.com> Cc: Shakeel Butt <shakeel.butt@linux.dev> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Sven Schnelle <svens@linux.ibm.com> Cc: Thomas Gleinxer <tglx@linutronix.de> Cc: Valentin Schneider <vschneid@redhat.com> Cc: Vasily Gorbik <gor@linux.ibm.com> Cc: Vincent Guittot <vincent.guittot@linaro.org> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: xu xin <xu.xin16@zte.com.cn> Cc: Zi Yan <ziy@nvidia.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
c0951573e0
commit
39f8049cd4
6 changed files with 43 additions and 8 deletions
|
|
@ -1103,8 +1103,10 @@ void vfs_coredump(const kernel_siginfo_t *siginfo)
|
||||||
* We must use the same mm->flags while dumping core to avoid
|
* We must use the same mm->flags while dumping core to avoid
|
||||||
* inconsistency of bit flags, since this flag is not protected
|
* inconsistency of bit flags, since this flag is not protected
|
||||||
* by any locks.
|
* by any locks.
|
||||||
|
*
|
||||||
|
* Note that we only care about MMF_DUMP* flags.
|
||||||
*/
|
*/
|
||||||
.mm_flags = mm->flags,
|
.mm_flags = __mm_flags_get_dumpable(mm),
|
||||||
.vma_meta = NULL,
|
.vma_meta = NULL,
|
||||||
.cpu = raw_smp_processor_id(),
|
.cpu = raw_smp_processor_id(),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1999,7 +1999,7 @@ void set_dumpable(struct mm_struct *mm, int value)
|
||||||
if (WARN_ON((unsigned)value > SUID_DUMP_ROOT))
|
if (WARN_ON((unsigned)value > SUID_DUMP_ROOT))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
set_mask_bits(&mm->flags, MMF_DUMPABLE_MASK, value);
|
__mm_flags_set_mask_dumpable(mm, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DEFINE3(execve,
|
SYSCALL_DEFINE3(execve,
|
||||||
|
|
|
||||||
|
|
@ -357,8 +357,11 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
|
|
||||||
if ((kinfo.mask & PIDFD_INFO_COREDUMP) && !(kinfo.coredump_mask)) {
|
if ((kinfo.mask & PIDFD_INFO_COREDUMP) && !(kinfo.coredump_mask)) {
|
||||||
task_lock(task);
|
task_lock(task);
|
||||||
if (task->mm)
|
if (task->mm) {
|
||||||
kinfo.coredump_mask = pidfs_coredump_mask(task->mm->flags);
|
unsigned long flags = __mm_flags_get_dumpable(task->mm);
|
||||||
|
|
||||||
|
kinfo.coredump_mask = pidfs_coredump_mask(flags);
|
||||||
|
}
|
||||||
task_unlock(task);
|
task_unlock(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2962,8 +2962,10 @@ static ssize_t proc_coredump_filter_read(struct file *file, char __user *buf,
|
||||||
ret = 0;
|
ret = 0;
|
||||||
mm = get_task_mm(task);
|
mm = get_task_mm(task);
|
||||||
if (mm) {
|
if (mm) {
|
||||||
|
unsigned long flags = __mm_flags_get_dumpable(mm);
|
||||||
|
|
||||||
len = snprintf(buffer, sizeof(buffer), "%08lx\n",
|
len = snprintf(buffer, sizeof(buffer), "%08lx\n",
|
||||||
((mm->flags & MMF_DUMP_FILTER_MASK) >>
|
((flags & MMF_DUMP_FILTER_MASK) >>
|
||||||
MMF_DUMP_FILTER_SHIFT));
|
MMF_DUMP_FILTER_SHIFT));
|
||||||
mmput(mm);
|
mmput(mm);
|
||||||
ret = simple_read_from_buffer(buf, count, ppos, buffer, len);
|
ret = simple_read_from_buffer(buf, count, ppos, buffer, len);
|
||||||
|
|
@ -3002,9 +3004,9 @@ static ssize_t proc_coredump_filter_write(struct file *file,
|
||||||
|
|
||||||
for (i = 0, mask = 1; i < MMF_DUMP_FILTER_BITS; i++, mask <<= 1) {
|
for (i = 0, mask = 1; i < MMF_DUMP_FILTER_BITS; i++, mask <<= 1) {
|
||||||
if (val & mask)
|
if (val & mask)
|
||||||
set_bit(i + MMF_DUMP_FILTER_SHIFT, &mm->flags);
|
mm_flags_set(i + MMF_DUMP_FILTER_SHIFT, mm);
|
||||||
else
|
else
|
||||||
clear_bit(i + MMF_DUMP_FILTER_SHIFT, &mm->flags);
|
mm_flags_clear(i + MMF_DUMP_FILTER_SHIFT, mm);
|
||||||
}
|
}
|
||||||
|
|
||||||
mmput(mm);
|
mmput(mm);
|
||||||
|
|
|
||||||
|
|
@ -1255,6 +1255,18 @@ static inline unsigned long __mm_flags_get_word(const struct mm_struct *mm)
|
||||||
return bitmap_read(bitmap, 0, BITS_PER_LONG);
|
return bitmap_read(bitmap, 0, BITS_PER_LONG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update the first system word of mm flags ONLY, applying the specified mask to
|
||||||
|
* it, then setting all flags specified by bits.
|
||||||
|
*/
|
||||||
|
static inline void __mm_flags_set_mask_bits_word(struct mm_struct *mm,
|
||||||
|
unsigned long mask, unsigned long bits)
|
||||||
|
{
|
||||||
|
unsigned long *bitmap = ACCESS_PRIVATE(&mm->_flags, __mm_flags);
|
||||||
|
|
||||||
|
set_mask_bits(bitmap, mask, bits);
|
||||||
|
}
|
||||||
|
|
||||||
#define MM_MT_FLAGS (MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN | \
|
#define MM_MT_FLAGS (MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN | \
|
||||||
MT_FLAGS_USE_RCU)
|
MT_FLAGS_USE_RCU)
|
||||||
extern struct mm_struct init_mm;
|
extern struct mm_struct init_mm;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,20 @@
|
||||||
#define SUID_DUMP_USER 1 /* Dump as user of process */
|
#define SUID_DUMP_USER 1 /* Dump as user of process */
|
||||||
#define SUID_DUMP_ROOT 2 /* Dump as root */
|
#define SUID_DUMP_ROOT 2 /* Dump as root */
|
||||||
|
|
||||||
|
static inline unsigned long __mm_flags_get_dumpable(struct mm_struct *mm)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* By convention, dumpable bits are contained in first 32 bits of the
|
||||||
|
* bitmap, so we can simply access this first unsigned long directly.
|
||||||
|
*/
|
||||||
|
return __mm_flags_get_word(mm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __mm_flags_set_mask_dumpable(struct mm_struct *mm, int value)
|
||||||
|
{
|
||||||
|
__mm_flags_set_mask_bits_word(mm, MMF_DUMPABLE_MASK, value);
|
||||||
|
}
|
||||||
|
|
||||||
extern void set_dumpable(struct mm_struct *mm, int value);
|
extern void set_dumpable(struct mm_struct *mm, int value);
|
||||||
/*
|
/*
|
||||||
* This returns the actual value of the suid_dumpable flag. For things
|
* This returns the actual value of the suid_dumpable flag. For things
|
||||||
|
|
@ -22,7 +36,9 @@ static inline int __get_dumpable(unsigned long mm_flags)
|
||||||
|
|
||||||
static inline int get_dumpable(struct mm_struct *mm)
|
static inline int get_dumpable(struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
return __get_dumpable(mm->flags);
|
unsigned long flags = __mm_flags_get_dumpable(mm);
|
||||||
|
|
||||||
|
return __get_dumpable(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _LINUX_SCHED_COREDUMP_H */
|
#endif /* _LINUX_SCHED_COREDUMP_H */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue