Commit decd6167 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'akpm' (patches from Andrew)

Merge misc fixes from Andrew Morton:
 "7 fixes"

* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
  kasan: add missing functions declarations to kasan.h
  kasan: consistently disable debugging features
  ipc/util.c: sysvipc_find_ipc() incorrectly updates position index
  userfaultfd: fix remap event with MREMAP_DONTUNMAP
  mm/gup: fix fixup_user_fault() on multiple retries
  epoll: call final ep_events_available() check under the lock
  mm, memcg: fix inconsistent oom event behavior
parents 8c1684bb 13cf0488
...@@ -1879,34 +1879,33 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, ...@@ -1879,34 +1879,33 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
* event delivery. * event delivery.
*/ */
init_wait(&wait); init_wait(&wait);
write_lock_irq(&ep->lock);
__add_wait_queue_exclusive(&ep->wq, &wait);
write_unlock_irq(&ep->lock);
write_lock_irq(&ep->lock);
/* /*
* We don't want to sleep if the ep_poll_callback() sends us * Barrierless variant, waitqueue_active() is called under
* a wakeup in between. That's why we set the task state * the same lock on wakeup ep_poll_callback() side, so it
* to TASK_INTERRUPTIBLE before doing the checks. * is safe to avoid an explicit barrier.
*/ */
set_current_state(TASK_INTERRUPTIBLE); __set_current_state(TASK_INTERRUPTIBLE);
/* /*
* Always short-circuit for fatal signals to allow * Do the final check under the lock. ep_scan_ready_list()
* threads to make a timely exit without the chance of * plays with two lists (->rdllist and ->ovflist) and there
* finding more events available and fetching * is always a race when both lists are empty for short
* repeatedly. * period of time although events are pending, so lock is
* important.
*/ */
if (fatal_signal_pending(current)) { eavail = ep_events_available(ep);
if (!eavail) {
if (signal_pending(current))
res = -EINTR; res = -EINTR;
break; else
__add_wait_queue_exclusive(&ep->wq, &wait);
} }
write_unlock_irq(&ep->lock);
eavail = ep_events_available(ep); if (eavail || res)
if (eavail)
break;
if (signal_pending(current)) {
res = -EINTR;
break; break;
}
if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS)) { if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS)) {
timed_out = 1; timed_out = 1;
...@@ -1927,6 +1926,15 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, ...@@ -1927,6 +1926,15 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
} }
send_events: send_events:
if (fatal_signal_pending(current)) {
/*
* Always short-circuit for fatal signals to allow
* threads to make a timely exit without the chance of
* finding more events available and fetching
* repeatedly.
*/
res = -EINTR;
}
/* /*
* Try to transfer events to user space. In case we get 0 events and * Try to transfer events to user space. In case we get 0 events and
* there's still timeout left over, we go trying again in search of * there's still timeout left over, we go trying again in search of
......
...@@ -783,6 +783,8 @@ static inline void memcg_memory_event(struct mem_cgroup *memcg, ...@@ -783,6 +783,8 @@ static inline void memcg_memory_event(struct mem_cgroup *memcg,
atomic_long_inc(&memcg->memory_events[event]); atomic_long_inc(&memcg->memory_events[event]);
cgroup_file_notify(&memcg->events_file); cgroup_file_notify(&memcg->events_file);
if (!cgroup_subsys_on_dfl(memory_cgrp_subsys))
break;
if (cgrp_dfl_root.flags & CGRP_ROOT_MEMORY_LOCAL_EVENTS) if (cgrp_dfl_root.flags & CGRP_ROOT_MEMORY_LOCAL_EVENTS)
break; break;
} while ((memcg = parent_mem_cgroup(memcg)) && } while ((memcg = parent_mem_cgroup(memcg)) &&
......
...@@ -764,21 +764,21 @@ static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, ...@@ -764,21 +764,21 @@ static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos,
total++; total++;
} }
*new_pos = pos + 1; ipc = NULL;
if (total >= ids->in_use) if (total >= ids->in_use)
return NULL; goto out;
for (; pos < ipc_mni; pos++) { for (; pos < ipc_mni; pos++) {
ipc = idr_find(&ids->ipcs_idr, pos); ipc = idr_find(&ids->ipcs_idr, pos);
if (ipc != NULL) { if (ipc != NULL) {
rcu_read_lock(); rcu_read_lock();
ipc_lock_object(ipc); ipc_lock_object(ipc);
return ipc; break;
} }
} }
out:
/* Out of range - return NULL to terminate iteration */ *new_pos = pos + 1;
return NULL; return ipc;
} }
static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos) static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
......
...@@ -1218,6 +1218,10 @@ int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, ...@@ -1218,6 +1218,10 @@ int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm,
if (!vma_permits_fault(vma, fault_flags)) if (!vma_permits_fault(vma, fault_flags))
return -EFAULT; return -EFAULT;
if ((fault_flags & FAULT_FLAG_KILLABLE) &&
fatal_signal_pending(current))
return -EINTR;
ret = handle_mm_fault(vma, address, fault_flags); ret = handle_mm_fault(vma, address, fault_flags);
major |= ret & VM_FAULT_MAJOR; major |= ret & VM_FAULT_MAJOR;
if (ret & VM_FAULT_ERROR) { if (ret & VM_FAULT_ERROR) {
...@@ -1230,12 +1234,10 @@ int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, ...@@ -1230,12 +1234,10 @@ int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm,
if (ret & VM_FAULT_RETRY) { if (ret & VM_FAULT_RETRY) {
down_read(&mm->mmap_sem); down_read(&mm->mmap_sem);
if (!(fault_flags & FAULT_FLAG_TRIED)) {
*unlocked = true; *unlocked = true;
fault_flags |= FAULT_FLAG_TRIED; fault_flags |= FAULT_FLAG_TRIED;
goto retry; goto retry;
} }
}
if (tsk) { if (tsk) {
if (major) if (major)
......
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
KASAN_SANITIZE := n KASAN_SANITIZE := n
UBSAN_SANITIZE_common.o := n UBSAN_SANITIZE := n
UBSAN_SANITIZE_generic.o := n
UBSAN_SANITIZE_generic_report.o := n
UBSAN_SANITIZE_tags.o := n
KCOV_INSTRUMENT := n KCOV_INSTRUMENT := n
# Disable ftrace to avoid recursion.
CFLAGS_REMOVE_common.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_common.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_generic.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_generic.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_generic_report.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_generic_report.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_init.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_quarantine.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_report.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_tags.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_tags.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_tags_report.o = $(CC_FLAGS_FTRACE)
# Function splitter causes unnecessary splits in __asan_load1/__asan_store1 # Function splitter causes unnecessary splits in __asan_load1/__asan_store1
# see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63533 # see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63533
CFLAGS_common.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) CFLAGS_common.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
CFLAGS_generic.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) CFLAGS_generic.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
CFLAGS_generic_report.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) CFLAGS_generic_report.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
CFLAGS_init.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
CFLAGS_quarantine.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
CFLAGS_report.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
CFLAGS_tags.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) CFLAGS_tags.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
CFLAGS_tags_report.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
obj-$(CONFIG_KASAN) := common.o init.o report.o obj-$(CONFIG_KASAN) := common.o init.o report.o
obj-$(CONFIG_KASAN_GENERIC) += generic.o generic_report.o quarantine.o obj-$(CONFIG_KASAN_GENERIC) += generic.o generic_report.o quarantine.o
......
...@@ -212,8 +212,6 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag) ...@@ -212,8 +212,6 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag)
asmlinkage void kasan_unpoison_task_stack_below(const void *watermark); asmlinkage void kasan_unpoison_task_stack_below(const void *watermark);
void __asan_register_globals(struct kasan_global *globals, size_t size); void __asan_register_globals(struct kasan_global *globals, size_t size);
void __asan_unregister_globals(struct kasan_global *globals, size_t size); void __asan_unregister_globals(struct kasan_global *globals, size_t size);
void __asan_loadN(unsigned long addr, size_t size);
void __asan_storeN(unsigned long addr, size_t size);
void __asan_handle_no_return(void); void __asan_handle_no_return(void);
void __asan_alloca_poison(unsigned long addr, size_t size); void __asan_alloca_poison(unsigned long addr, size_t size);
void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom); void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom);
...@@ -228,6 +226,8 @@ void __asan_load8(unsigned long addr); ...@@ -228,6 +226,8 @@ void __asan_load8(unsigned long addr);
void __asan_store8(unsigned long addr); void __asan_store8(unsigned long addr);
void __asan_load16(unsigned long addr); void __asan_load16(unsigned long addr);
void __asan_store16(unsigned long addr); void __asan_store16(unsigned long addr);
void __asan_loadN(unsigned long addr, size_t size);
void __asan_storeN(unsigned long addr, size_t size);
void __asan_load1_noabort(unsigned long addr); void __asan_load1_noabort(unsigned long addr);
void __asan_store1_noabort(unsigned long addr); void __asan_store1_noabort(unsigned long addr);
...@@ -239,6 +239,21 @@ void __asan_load8_noabort(unsigned long addr); ...@@ -239,6 +239,21 @@ void __asan_load8_noabort(unsigned long addr);
void __asan_store8_noabort(unsigned long addr); void __asan_store8_noabort(unsigned long addr);
void __asan_load16_noabort(unsigned long addr); void __asan_load16_noabort(unsigned long addr);
void __asan_store16_noabort(unsigned long addr); void __asan_store16_noabort(unsigned long addr);
void __asan_loadN_noabort(unsigned long addr, size_t size);
void __asan_storeN_noabort(unsigned long addr, size_t size);
void __asan_report_load1_noabort(unsigned long addr);
void __asan_report_store1_noabort(unsigned long addr);
void __asan_report_load2_noabort(unsigned long addr);
void __asan_report_store2_noabort(unsigned long addr);
void __asan_report_load4_noabort(unsigned long addr);
void __asan_report_store4_noabort(unsigned long addr);
void __asan_report_load8_noabort(unsigned long addr);
void __asan_report_store8_noabort(unsigned long addr);
void __asan_report_load16_noabort(unsigned long addr);
void __asan_report_store16_noabort(unsigned long addr);
void __asan_report_load_n_noabort(unsigned long addr, size_t size);
void __asan_report_store_n_noabort(unsigned long addr, size_t size);
void __asan_set_shadow_00(const void *addr, size_t size); void __asan_set_shadow_00(const void *addr, size_t size);
void __asan_set_shadow_f1(const void *addr, size_t size); void __asan_set_shadow_f1(const void *addr, size_t size);
...@@ -247,4 +262,19 @@ void __asan_set_shadow_f3(const void *addr, size_t size); ...@@ -247,4 +262,19 @@ void __asan_set_shadow_f3(const void *addr, size_t size);
void __asan_set_shadow_f5(const void *addr, size_t size); void __asan_set_shadow_f5(const void *addr, size_t size);
void __asan_set_shadow_f8(const void *addr, size_t size); void __asan_set_shadow_f8(const void *addr, size_t size);
void __hwasan_load1_noabort(unsigned long addr);
void __hwasan_store1_noabort(unsigned long addr);
void __hwasan_load2_noabort(unsigned long addr);
void __hwasan_store2_noabort(unsigned long addr);
void __hwasan_load4_noabort(unsigned long addr);
void __hwasan_store4_noabort(unsigned long addr);
void __hwasan_load8_noabort(unsigned long addr);
void __hwasan_store8_noabort(unsigned long addr);
void __hwasan_load16_noabort(unsigned long addr);
void __hwasan_store16_noabort(unsigned long addr);
void __hwasan_loadN_noabort(unsigned long addr, size_t size);
void __hwasan_storeN_noabort(unsigned long addr, size_t size);
void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size);
#endif #endif
...@@ -794,7 +794,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, ...@@ -794,7 +794,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
if (locked && new_len > old_len) if (locked && new_len > old_len)
mm_populate(new_addr + old_len, new_len - old_len); mm_populate(new_addr + old_len, new_len - old_len);
userfaultfd_unmap_complete(mm, &uf_unmap_early); userfaultfd_unmap_complete(mm, &uf_unmap_early);
mremap_userfaultfd_complete(&uf, addr, new_addr, old_len); mremap_userfaultfd_complete(&uf, addr, ret, old_len);
userfaultfd_unmap_complete(mm, &uf_unmap); userfaultfd_unmap_complete(mm, &uf_unmap);
return ret; return ret;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment