Hi,
This is a small update to the series, see the cover letter of v1 for more information. Thanks everyone for the reviews!
v1..v2: * Fixed a couple of typos in commit messages. * Added initialisation of msg_control_is_user in do_ipv6_setsockopt() (patch 13)
Review branch:
https://git.morello-project.org/kbrodsky-arm/linux/-/commits/morello/gcc_fix...
Thanks, Kevin
Kevin Brodsky (18): arm64: signal: Avoid unnecessary capability arithmetic drivers/android/binder: Cast to (void *) when printing %p drivers/android/binder: Cast user_uintptr_t arg when printing math.h: Make round_{up,down} capability-friendly asm-generic/cacheflush.h: Use appropriate user pointer conversion kernel: signal: Use appropriate user pointer conversion perf/core: Use appropriate user pointer conversion compat: Fix shift warning in compat64 audit: Explicitly create user pointer coredump: Explicitly create user pointer kernel/futex: Explicitly create user pointer rseq: Explicitly create user pointers net: Finish up ->msg_control{,_user} split tcp: Explicitly create user pointers Input: evdev: Explicitly create user pointers mmc: block: Explicitly create user pointers drm: Explicitly create user pointers drm/panfrost: Explicitly create user pointers
arch/arm64/kernel/signal.c | 6 +++-- drivers/android/binder.c | 4 ++-- drivers/android/binder_alloc.c | 25 +++++++++++---------- drivers/gpu/drm/drm_atomic_uapi.c | 8 +++---- drivers/gpu/drm/drm_color_mgmt.c | 12 +++++----- drivers/gpu/drm/drm_connector.c | 8 +++---- drivers/gpu/drm/drm_crtc.c | 2 +- drivers/gpu/drm/drm_framebuffer.c | 2 +- drivers/gpu/drm/drm_lease.c | 4 ++-- drivers/gpu/drm/drm_mode_object.c | 4 ++-- drivers/gpu/drm/drm_plane.c | 2 +- drivers/gpu/drm/panfrost/panfrost_drv.c | 4 ++-- drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 2 +- drivers/input/evdev.c | 4 ++-- drivers/mmc/core/block.c | 6 ++--- fs/coredump.c | 2 +- include/asm-generic/cacheflush.h | 6 ++--- include/linux/math.h | 5 +++++ kernel/auditsc.c | 2 +- kernel/compat.c | 4 ++-- kernel/events/core.c | 2 +- kernel/futex/waitwake.c | 2 +- kernel/rseq.c | 4 ++-- kernel/signal.c | 2 +- net/compat.c | 13 ++++++----- net/core/scm.c | 9 +++++--- net/ipv4/tcp.c | 8 +++---- net/ipv6/ipv6_sockglue.c | 1 + 28 files changed, 83 insertions(+), 70 deletions(-)
sp_top is only used to compute the size to provide to access_ok(). It should therefore be just an address, not a capability (in PCuABI). GCC rightly warns about this situation, as subtracting two capabilities is ambiguous (it may be interpreted as a capability operation subtracting the address of the LHS with the address of the RHS, while here we expect a simple integer subtraction).
Fixes: ("linux/sched/signal.h: Modify the stack pointer to user_uintptr_t") Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- arch/arm64/kernel/signal.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index b804457a36b2..80289e90fc66 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -1001,7 +1001,8 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user, static int get_sigframe(struct rt_sigframe_user_layout *user, struct ksignal *ksig, struct pt_regs *regs) { - user_uintptr_t sp, sp_top; + user_uintptr_t sp; + ptraddr_t sp_top; int err;
init_user_layout(user); @@ -1009,7 +1010,8 @@ static int get_sigframe(struct rt_sigframe_user_layout *user, if (err) return err;
- sp = sp_top = sigsp(signal_sp(regs), ksig); + sp = sigsp(signal_sp(regs), ksig); + sp_top = (ptraddr_t)sp;
sp = round_down(sp - sizeof(struct frame_record), 16); user->next_frame = (struct frame_record __user *)sp;
Commit "drivers/android/binder_alloc: Represent user addresses as integers" changed the type of many variables / members representing addresses from void * to unsigned long. It however failed to introduce the appropriate (void *) casts when printing these variables, which is the type %p expects. GCC warns about this sort of mismatch; add the casts to make it happy.
Fixes: ("drivers/android/binder_alloc: Represent user addresses as integers") Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- drivers/android/binder.c | 2 +- drivers/android/binder_alloc.c | 25 +++++++++++++------------ 2 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/drivers/android/binder.c b/drivers/android/binder.c index b9280b58c058..bccf30d0fa4f 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -5955,7 +5955,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m, seq_printf(m, " node %d", buffer->target_node->debug_id); seq_printf(m, " size %zd:%zd data %pK\n", buffer->data_size, buffer->offsets_size, - buffer->user_data); + (void *)buffer->user_data); }
static void print_binder_work_ilocked(struct seq_file *m, diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 8f6190b490c5..44b094060f75 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -190,7 +190,8 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, "%d: %s pages %pK-%pK\n", alloc->pid, - allocate ? "allocate" : "free", start, end); + allocate ? "allocate" : "free", + (void *)start, (void *)end);
if (end <= start) return 0; @@ -250,7 +251,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, __GFP_ZERO); if (!page->page_ptr) { pr_err("%d: binder_alloc_buf failed for page at %pK\n", - alloc->pid, page_addr); + alloc->pid, (void *)page_addr); goto err_alloc_page_failed; } page->alloc = alloc; @@ -594,8 +595,8 @@ static void binder_delete_free_buffer(struct binder_alloc *alloc, to_free = false; binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, "%d: merge free, buffer %pK share page with %pK\n", - alloc->pid, buffer->user_data, - prev->user_data); + alloc->pid, (void *)buffer->user_data, + (void *)prev->user_data); }
if (!list_is_last(&buffer->entry, &alloc->buffers)) { @@ -605,24 +606,24 @@ static void binder_delete_free_buffer(struct binder_alloc *alloc, binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, "%d: merge free, buffer %pK share page with %pK\n", alloc->pid, - buffer->user_data, - next->user_data); + (void *)buffer->user_data, + (void *)next->user_data); } }
if (PAGE_ALIGNED(buffer->user_data)) { binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, "%d: merge free, buffer start %pK is page aligned\n", - alloc->pid, buffer->user_data); + alloc->pid, (void *)buffer->user_data); to_free = false; }
if (to_free) { binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, "%d: merge free, buffer %pK do not share page with %pK or %pK\n", - alloc->pid, buffer->user_data, - prev->user_data, - next ? next->user_data : 0); + alloc->pid, (void *)buffer->user_data, + (void *)prev->user_data, + (void *)(next ? next->user_data : 0)); binder_update_page_range(alloc, 0, buffer_start_page(buffer), buffer_start_page(buffer) + PAGE_SIZE); } @@ -846,7 +847,7 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc) page_addr = alloc->buffer + i * PAGE_SIZE; binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, "%s: %d: page %d at %pK %s\n", - __func__, alloc->pid, i, page_addr, + __func__, alloc->pid, i, (void *)page_addr, on_lru ? "on lru" : "active"); __free_page(alloc->pages[i].page_ptr); page_count++; @@ -866,7 +867,7 @@ static void print_binder_buffer(struct seq_file *m, const char *prefix, struct binder_buffer *buffer) { seq_printf(m, "%s %d: %pK size %zd:%zd:%zd %s\n", - prefix, buffer->debug_id, buffer->user_data, + prefix, buffer->debug_id, (void *)buffer->user_data, buffer->data_size, buffer->offsets_size, buffer->extra_buffers_size, buffer->transaction ? "active" : "delivered");
%lx expects an (unsigned) long, but user_uintptr_t is a different type in PCuABI (uintcap_t). Cast arg to (unsigned long) to avoid a warning when building with GCC.
Fixes: ("fs/ioctl: Modify 3rd argument of fops->unlocked_ioctl to user_uintptr_t") Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- drivers/android/binder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/android/binder.c b/drivers/android/binder.c index bccf30d0fa4f..6ada02805d6a 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -5516,7 +5516,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, user_uintptr_t arg thread->looper_need_return = false; wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); if (ret && ret != -EINTR) - pr_info("%d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); + pr_info("%d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, (unsigned long)arg, ret); err_unlocked: trace_binder_ioctl_done(ret); return ret;
round_{up,down} are occasionally used to align user_uintptr_t variables, that is capabilities in PCuABI. The way these macros are currently implemented is ambiguous when capabilities are involved, fortunately CHERI-aware compilers (and upstream Clang since 10.0) implement builtins that are able to align any type, including capabilities. Use these builtins if available.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- include/linux/math.h | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/include/linux/math.h b/include/linux/math.h index 439b8f0b9ebd..1e75ea17f264 100644 --- a/include/linux/math.h +++ b/include/linux/math.h @@ -6,6 +6,10 @@ #include <asm/div64.h> #include <uapi/linux/kernel.h>
+#if __has_builtin(__builtin_align_up) && __has_builtin(__builtin_align_down) +#define round_up(x, y) __builtin_align_up((x), (y)) +#define round_down(x, y) __builtin_align_down((x), (y)) +#else /* * This looks more complex than it should be. But we need to * get the type for the ~ right in round_down (it needs to be @@ -33,6 +37,7 @@ * To perform arbitrary rounding down, use rounddown() below. */ #define round_down(x, y) ((x) & ~__round_mask(x, y)) +#endif /* __has_builtin(__builtin_align_up) && __has_builtin(__builtin_align_down) */
#define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP
instrument_copy_*() take a user pointer as src/dst, but in this case they are actually kernel pointers, as copy_{to,from}_user_page() always work with kernel pointers. We should therefore pass these kernel pointers as (invalid) user pointers, which is fine as memory tools only need them for recording/tracking purposes, not to dereference them.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- include/asm-generic/cacheflush.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/asm-generic/cacheflush.h b/include/asm-generic/cacheflush.h index f46258d1a080..a6617c221e00 100644 --- a/include/asm-generic/cacheflush.h +++ b/include/asm-generic/cacheflush.h @@ -107,7 +107,7 @@ static inline void flush_cache_vunmap(unsigned long start, unsigned long end) #ifndef copy_to_user_page #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ - instrument_copy_to_user((void __user *)dst, src, len); \ + instrument_copy_to_user(as_user_ptr(dst), src, len); \ memcpy(dst, src, len); \ flush_icache_user_page(vma, page, vaddr, len); \ } while (0) @@ -117,10 +117,10 @@ static inline void flush_cache_vunmap(unsigned long start, unsigned long end) #ifndef copy_from_user_page #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ do { \ - instrument_copy_from_user_before(dst, (void __user *)src, \ + instrument_copy_from_user_before(dst, as_user_ptr(src), \ len); \ memcpy(dst, src, len); \ - instrument_copy_from_user_after(dst, (void __user *)src, len, \ + instrument_copy_from_user_after(dst, as_user_ptr(src), len, \ 0); \ } while (0) #endif
si_call_addr is typed as a user pointer, but it really is just an address. Use as_user_ptr() to store the address as a user pointer, unmodified.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- kernel/signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/signal.c b/kernel/signal.c index d4158d626b45..6eb8dddf5946 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1845,7 +1845,7 @@ int force_sig_seccomp(int syscall, int reason, bool force_coredump) clear_siginfo(&info); info.si_signo = SIGSYS; info.si_code = SYS_SECCOMP; - info.si_call_addr = (void __user *)KSTK_EIP(current); + info.si_call_addr = as_user_ptr(KSTK_EIP(current)); info.si_errno = reason; info.si_arch = syscall_get_arch(current); info.si_syscall = syscall;
send_sig_perf() and variants take a user pointer as first argument, matching the type of si_addr. However si_addr just represents an address, not a valid user pointer. It is therefore appropriate to pass the address as an (invalid) user pointer, using as_user_ptr().
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- kernel/events/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/events/core.c b/kernel/events/core.c index 37e013afb718..c362d35cdf40 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6480,7 +6480,7 @@ static void perf_sigtrap(struct perf_event *event) if (current->flags & PF_EXITING) return;
- send_sig_perf((void __user *)event->pending_addr, + send_sig_perf(as_user_ptr(event->pending_addr), event->attr.type, event->attr.sig_data); }
Commit "compat: make compat_get_bitmap work with 64-bit compat longs" made compat_{get,put}_bitmap() compat64-friendly by adding a separate path when compat_long_t is the same size as long.
Even though this condition can be evaluated at compile time and the inactive path eliminated completely, the compiler still parses both paths. As a result, in compat64, GCC complains about the shift in the 32-bit path, because BITS_PER_COMPAT_LONG is 64 in this case and it does not make sense to shift a (64-bit) integer by more than 63.
Avoid this warning by shifting by BITS_PER_LONG / 2 instead, which is equivalent as we already assert above that compat_long_t is half the size of long in this path.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- kernel/compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/compat.c b/kernel/compat.c index c3edaca046f9..01342b3781d6 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -215,7 +215,7 @@ long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask, compat_ulong_t l1, l2; unsafe_get_user(l1, umask++, Efault); unsafe_get_user(l2, umask++, Efault); - *mask++ = ((unsigned long)l2 << BITS_PER_COMPAT_LONG) | l1; + *mask++ = ((unsigned long)l2 << (BITS_PER_LONG / 2)) | l1; nr_compat_longs -= 2; } if (nr_compat_longs) @@ -252,7 +252,7 @@ long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask, while (nr_compat_longs > 1) { unsigned long m = *mask++; unsafe_put_user((compat_ulong_t)m, umask++, Efault); - unsafe_put_user(m >> BITS_PER_COMPAT_LONG, umask++, Efault); + unsafe_put_user(m >> (BITS_PER_LONG / 2), umask++, Efault); nr_compat_longs -= 2; } if (nr_compat_longs)
audit_log_execve_info() is directly reading memory from a user mapping. The access is entirely driven by the kernel, not by userspace, so a user pointer has to be created manually from the address of the arguments region (mm->arg_start). Using uaddr_to_user_ptr_safe() is the appropriate way to create a user pointer in this case.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- kernel/auditsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 9f8c05228d6d..a136fb44180c 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1129,7 +1129,7 @@ static void audit_log_execve_info(struct audit_context *context, unsigned int arg; char *buf_head; char *buf; - const char __user *p = (const char __user *)current->mm->arg_start; + const char __user *p = uaddr_to_user_ptr_safe(current->mm->arg_start);
/* NOTE: this buffer needs to be large enough to hold all the non-arg * data we put in the audit record for this argument (see the
dump_vma_snapshot() is directly reading memory from a user mapping. The access is entirely driven by the kernel, not by userspace, so a user pointer has to be created manually from the computed address. Using uaddr_to_user_ptr_safe() is the appropriate way to create a user pointer in this case.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- fs/coredump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/coredump.c b/fs/coredump.c index 7bad7785e8e6..90009027a8af 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -1182,7 +1182,7 @@ static bool dump_vma_snapshot(struct coredump_params *cprm) if (m->dump_size == DUMP_SIZE_MAYBE_ELFHDR_PLACEHOLDER) { char elfmag[SELFMAG];
- if (copy_from_user(elfmag, (void __user *)m->start, SELFMAG) || + if (copy_from_user(elfmag, uaddr_to_user_ptr_safe(m->start), SELFMAG) || memcmp(elfmag, ELFMAG, SELFMAG) != 0) { m->dump_size = 0; } else {
struct futex_waitv::uaddr is typed as __u64, although it represents a user pointer. For now let's create a user pointer manually using uaddr_to_user_ptr(), but eventually the struct should be modified to represent uaddr as __kernel_uintptr_t instead, allowing userspace to provide a whole user pointer instead of just an address.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- kernel/futex/waitwake.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/futex/waitwake.c b/kernel/futex/waitwake.c index ba01b9408203..1ab5640e7f84 100644 --- a/kernel/futex/waitwake.c +++ b/kernel/futex/waitwake.c @@ -433,7 +433,7 @@ static int futex_wait_multiple_setup(struct futex_vector *vs, int count, int *wo set_current_state(TASK_INTERRUPTIBLE|TASK_FREEZABLE);
for (i = 0; i < count; i++) { - u32 __user *uaddr = (u32 __user *)(unsigned long)vs[i].w.uaddr; + u32 __user *uaddr = uaddr_to_user_ptr(vs[i].w.uaddr); struct futex_q *q = &vs[i].q; u32 val = (u32)vs[i].w.val;
rseq structs represent all addresses as __u64. Some of them are in fact being used as pointers to access user memory. For now, let's create user pointers manually to make the access.
struct rseq::rseq_cs really represents a pointer (to a struct rseq_c) and its type should eventually be changed accordingly (__kernel_uintptr_t). The situation is less clear for struct rseq_cs::start_ip and struct rseq_cs::abort_ip as they are mostly addresses, but checks in PCuABI may still be desirable.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- kernel/rseq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/rseq.c b/kernel/rseq.c index 9eebc6090c52..0afb44439a8d 100644 --- a/kernel/rseq.c +++ b/kernel/rseq.c @@ -141,7 +141,7 @@ static int rseq_get_rseq_cs(struct task_struct *t, struct rseq_cs *rseq_cs) } if (ptr >= TASK_SIZE) return -EINVAL; - urseq_cs = (struct rseq_cs __user *)(unsigned long)ptr; + urseq_cs = uaddr_to_user_ptr(ptr); if (copy_from_user(rseq_cs, urseq_cs, sizeof(*rseq_cs))) return -EFAULT;
@@ -157,7 +157,7 @@ static int rseq_get_rseq_cs(struct task_struct *t, struct rseq_cs *rseq_cs) if (rseq_cs->abort_ip - rseq_cs->start_ip < rseq_cs->post_commit_offset) return -EINVAL;
- usig = (u32 __user *)(unsigned long)(rseq_cs->abort_ip - sizeof(u32)); + usig = uaddr_to_user_ptr(rseq_cs->abort_ip - sizeof(u32)); ret = get_user(sig, usig); if (ret) return ret;
Commit 1f466e1f15cf ("net: cleanly handle kernel vs user buffers for ->msg_control") introduced the msg_control_user and msg_control_is_user fields in struct msghdr to ensure user pointers are represented as such. It also took care of converting most users of struct msghdr::msg_control where user pointers are involved. It did however miss a number of cases, and some code using msg_control inappropriately has also appeared in the meantime.
This commit is attempting to complete the split. Most issues are about msg_control being used when in fact a user pointer is stored in the union; msg_control_user is now used instead. An exception is made for null checks, as it should be safe to use msg_control unconditionally for that purpose.
Additionally, a special situation in cmsghdr_from_user_compat_to_kern() is addressed. There the input struct msghdr holds a user pointer (msg_control_user), but a kernel pointer is stored in msg_control when returning. msg_control_is_user is now updated accordingly.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- net/compat.c | 13 +++++++------ net/core/scm.c | 9 ++++++--- net/ipv4/tcp.c | 4 ++-- net/ipv6/ipv6_sockglue.c | 1 + 4 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/net/compat.c b/net/compat.c index f2fcf4204a1d..e10570f549a1 100644 --- a/net/compat.c +++ b/net/compat.c @@ -120,7 +120,7 @@ int get_compat_msghdr(struct msghdr *kmsg,
#define CMSG_COMPAT_FIRSTHDR(msg) \ (((msg)->msg_controllen) >= sizeof(struct compat_cmsghdr) ? \ - (struct compat_cmsghdr __user *)((msg)->msg_control) : \ + (struct compat_cmsghdr __user *)((msg)->msg_control_user) : \ (struct compat_cmsghdr __user *)NULL)
#define CMSG_COMPAT_OK(ucmlen, ucmsg, mhdr) \ @@ -133,7 +133,7 @@ static inline struct compat_cmsghdr __user *cmsg_compat_nxthdr(struct msghdr *ms struct compat_cmsghdr __user *cmsg, int cmsg_len) { char __user *ptr = (char __user *)cmsg + CMSG_COMPAT_ALIGN(cmsg_len); - if ((unsigned long)(ptr + 1 - (char __user *)msg->msg_control) > + if ((unsigned long)(ptr + 1 - (char __user *)msg->msg_control_user) > msg->msg_controllen) return NULL; return (struct compat_cmsghdr __user *)ptr; @@ -218,6 +218,7 @@ int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk, goto Einval;
/* Ok, looks like we made it. Hook it up and return success. */ + kmsg->msg_control_is_user = false; kmsg->msg_control = kcmsg_base; kmsg->msg_controllen = kcmlen; return 0; @@ -232,7 +233,7 @@ int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk,
int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data) { - struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control; + struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control_user; struct compat_cmsghdr cmhdr; struct old_timeval32 ctv; struct old_timespec32 cts[3]; @@ -281,7 +282,7 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat cmlen = CMSG_COMPAT_SPACE(len); if (kmsg->msg_controllen < cmlen) cmlen = kmsg->msg_controllen; - kmsg->msg_control += cmlen; + kmsg->msg_control_user += cmlen; kmsg->msg_controllen -= cmlen; return 0; } @@ -296,7 +297,7 @@ static int scm_max_fds_compat(struct msghdr *msg) void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm) { struct compat_cmsghdr __user *cm = - (struct compat_cmsghdr __user *)msg->msg_control; + (struct compat_cmsghdr __user *)msg->msg_control_user; unsigned int o_flags = (msg->msg_flags & MSG_CMSG_CLOEXEC) ? O_CLOEXEC : 0; int fdmax = min_t(int, scm_max_fds_compat(msg), scm->fp->count); int __user *cmsg_data = CMSG_COMPAT_DATA(cm); @@ -320,7 +321,7 @@ void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm) cmlen = CMSG_COMPAT_SPACE(i * sizeof(int)); if (msg->msg_controllen < cmlen) cmlen = msg->msg_controllen; - msg->msg_control += cmlen; + msg->msg_control_user += cmlen; msg->msg_controllen -= cmlen; } } diff --git a/net/core/scm.c b/net/core/scm.c index 5c356f0dee30..cb9dc17f1139 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -248,7 +248,10 @@ int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data) }
cmlen = min(CMSG_SPACE(len), msg->msg_controllen); - msg->msg_control += cmlen; + if (msg->msg_control_is_user) + msg->msg_control_user += cmlen; + else + msg->msg_control += cmlen; msg->msg_controllen -= cmlen; return 0;
@@ -297,7 +300,7 @@ static int scm_max_fds(struct msghdr *msg) void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) { struct cmsghdr __user *cm = - (__force struct cmsghdr __user *)msg->msg_control; + (__force struct cmsghdr __user *)msg->msg_control_user; unsigned int o_flags = (msg->msg_flags & MSG_CMSG_CLOEXEC) ? O_CLOEXEC : 0; int fdmax = min_t(int, scm_max_fds(msg), scm->fp->count); int __user *cmsg_data = CMSG_USER_DATA(cm); @@ -330,7 +333,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) cmlen = CMSG_SPACE(i * sizeof(int)); if (msg->msg_controllen < cmlen) cmlen = msg->msg_controllen; - msg->msg_control += cmlen; + msg->msg_control_user += cmlen; msg->msg_controllen -= cmlen; } } diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 17b213acffc8..8f5e605ea673 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2163,7 +2163,7 @@ static void tcp_zc_finalize_rx_tstamp(struct sock *sk, struct msghdr cmsg_dummy;
msg_control_addr = (unsigned long)zc->msg_control; - cmsg_dummy.msg_control = (void *)msg_control_addr; + cmsg_dummy.msg_control_user = (void __user *)msg_control_addr; cmsg_dummy.msg_controllen = (__kernel_size_t)zc->msg_controllen; cmsg_dummy.msg_flags = in_compat_syscall() @@ -2174,7 +2174,7 @@ static void tcp_zc_finalize_rx_tstamp(struct sock *sk, zc->msg_controllen == cmsg_dummy.msg_controllen) { tcp_recv_timestamp(&cmsg_dummy, sk, tss); zc->msg_control = (__u64) - ((uintptr_t)cmsg_dummy.msg_control); + ((uintptr_t)cmsg_dummy.msg_control_user); zc->msg_controllen = (__u64)cmsg_dummy.msg_controllen; zc->msg_flags = (__u32)cmsg_dummy.msg_flags; diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 532f4478c884..b1b3d4be650b 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -728,6 +728,7 @@ int do_ipv6_setsockopt(struct sock *sk, int level, int optname, goto done;
msg.msg_controllen = optlen; + msg.msg_control_is_user = false; msg.msg_control = (void *)(opt+1); ipc6.opt = opt;
Multiple fields of struct tcp_zerocopy_receive (address, copybuf_address, msg_control) are typed as __u64 even though they represent user pointers. For now let's create user pointers manually using uaddr_to_user_ptr(), but eventually the struct should be modified to represent the fields as __kernel_uintptr_t instead, allowing userspace to provide whole user pointers instead of just addresses.
Also address a user pointer conversion issue where we need to explicitly extract the address of struct msghdr::msg_control_user to store it in struct tcp_zerocopy_receive::msg_control (as it currently only represents an address).
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- net/ipv4/tcp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 8f5e605ea673..f5b69c347846 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2000,7 +2000,7 @@ static int receive_fallback_to_copy(struct sock *sk, if (copy_address != zc->copybuf_address) return -EINVAL;
- err = import_single_range(READ, (void __user *)copy_address, + err = import_single_range(READ, uaddr_to_user_ptr(copy_address), inq, &iov, &msg.msg_iter); if (err) return err; @@ -2034,7 +2034,7 @@ static int tcp_copy_straggler_data(struct tcp_zerocopy_receive *zc, if (copy_address != zc->copybuf_address) return -EINVAL;
- err = import_single_range(READ, (void __user *)copy_address, + err = import_single_range(READ, uaddr_to_user_ptr(copy_address), copylen, &iov, &msg.msg_iter); if (err) return err; @@ -2163,7 +2163,7 @@ static void tcp_zc_finalize_rx_tstamp(struct sock *sk, struct msghdr cmsg_dummy;
msg_control_addr = (unsigned long)zc->msg_control; - cmsg_dummy.msg_control_user = (void __user *)msg_control_addr; + cmsg_dummy.msg_control_user = uaddr_to_user_ptr(msg_control_addr); cmsg_dummy.msg_controllen = (__kernel_size_t)zc->msg_controllen; cmsg_dummy.msg_flags = in_compat_syscall() @@ -2174,7 +2174,7 @@ static void tcp_zc_finalize_rx_tstamp(struct sock *sk, zc->msg_controllen == cmsg_dummy.msg_controllen) { tcp_recv_timestamp(&cmsg_dummy, sk, tss); zc->msg_control = (__u64) - ((uintptr_t)cmsg_dummy.msg_control_user); + user_ptr_addr(cmsg_dummy.msg_control_user); zc->msg_controllen = (__u64)cmsg_dummy.msg_controllen; zc->msg_flags = (__u32)cmsg_dummy.msg_flags;
struct input_mask::codes_ptr is typed as __u64, although it represents a user pointer. For now let's create a user pointer manually using uaddr_to_user_ptr(), but eventually the struct should be modified to represent uaddr as __kernel_uintptr_t instead, allowing userspace to provide a whole user pointer instead of just an address.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- drivers/input/evdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 066dd1d8cfe4..9abb58dc57b0 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -1101,7 +1101,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, if (copy_from_user(&mask, p, sizeof(mask))) return -EFAULT;
- codes_ptr = (void __user *)(unsigned long)mask.codes_ptr; + codes_ptr = uaddr_to_user_ptr(mask.codes_ptr); return evdev_get_mask(client, mask.type, codes_ptr, mask.codes_size, compat_mode); @@ -1113,7 +1113,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, if (copy_from_user(&mask, p, sizeof(mask))) return -EFAULT;
- codes_ptr = (const void __user *)(unsigned long)mask.codes_ptr; + codes_ptr = uaddr_to_user_ptr(mask.codes_ptr); return evdev_set_mask(client, mask.type, codes_ptr, mask.codes_size, compat_mode);
struct mmc_ioc_cmd::data_ptr is typed as __u64, although it represents a user pointer. For now let's create a user pointer manually using uaddr_to_user_ptr(), but eventually the struct should be modified to represent data_ptr as __kernel_uintptr_t instead, allowing userspace to provide a whole user pointer instead of just an address.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- drivers/mmc/core/block.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 4a5d0e0283f9..8a05493f3691 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -430,8 +430,8 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user( return idata; }
- idata->buf = memdup_user((void __user *)(unsigned long) - idata->ic.data_ptr, idata->buf_bytes); + idata->buf = memdup_user(uaddr_to_user_ptr(idata->ic.data_ptr), + idata->buf_bytes); if (IS_ERR(idata->buf)) { err = PTR_ERR(idata->buf); goto idata_err; @@ -455,7 +455,7 @@ static int mmc_blk_ioctl_copy_to_user(struct mmc_ioc_cmd __user *ic_ptr, return -EFAULT;
if (!idata->ic.write_flag) { - if (copy_to_user((void __user *)(unsigned long)ic->data_ptr, + if (copy_to_user(uaddr_to_user_ptr(ic->data_ptr), idata->buf, idata->buf_bytes)) return -EFAULT; }
Various DRM uapi structs represent user pointers as __u64, which is not PCuABI-friendly. For now let's create a user pointer manually using uaddr_to_user_ptr(), but eventually the structs should be modified to represent the user pointer fields as __kernel_uintptr_t instead, allowing userspace to provide a whole user pointer instead of just an address.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- drivers/gpu/drm/drm_atomic_uapi.c | 8 ++++---- drivers/gpu/drm/drm_color_mgmt.c | 12 ++++++------ drivers/gpu/drm/drm_connector.c | 8 ++++---- drivers/gpu/drm/drm_crtc.c | 2 +- drivers/gpu/drm/drm_framebuffer.c | 2 +- drivers/gpu/drm/drm_lease.c | 4 ++-- drivers/gpu/drm/drm_mode_object.c | 4 ++-- drivers/gpu/drm/drm_plane.c | 2 +- 8 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 79730fa1dd8e..772540313d48 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -1282,10 +1282,10 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_mode_atomic *arg = data; - uint32_t __user *objs_ptr = (uint32_t __user *)(unsigned long)(arg->objs_ptr); - uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned long)(arg->count_props_ptr); - uint32_t __user *props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr); - uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned long)(arg->prop_values_ptr); + uint32_t __user *objs_ptr = uaddr_to_user_ptr(arg->objs_ptr); + uint32_t __user *count_props_ptr = uaddr_to_user_ptr(arg->count_props_ptr); + uint32_t __user *props_ptr = uaddr_to_user_ptr(arg->props_ptr); + uint64_t __user *prop_values_ptr = uaddr_to_user_ptr(arg->prop_values_ptr); unsigned int copied_objs, copied_props; struct drm_atomic_state *state; struct drm_modeset_acquire_ctx ctx; diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index d021497841b8..eb065ba37abd 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -384,19 +384,19 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
size = crtc_lut->gamma_size * (sizeof(uint16_t)); r_base = crtc->gamma_store; - if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) { + if (copy_from_user(r_base, uaddr_to_user_ptr(crtc_lut->red), size)) { ret = -EFAULT; goto out; }
g_base = r_base + size; - if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) { + if (copy_from_user(g_base, uaddr_to_user_ptr(crtc_lut->green), size)) { ret = -EFAULT; goto out; }
b_base = g_base + size; - if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) { + if (copy_from_user(b_base, uaddr_to_user_ptr(crtc_lut->blue), size)) { ret = -EFAULT; goto out; } @@ -448,19 +448,19 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev, drm_modeset_lock(&crtc->mutex, NULL); size = crtc_lut->gamma_size * (sizeof(uint16_t)); r_base = crtc->gamma_store; - if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) { + if (copy_to_user(uaddr_to_user_ptr(crtc_lut->red), r_base, size)) { ret = -EFAULT; goto out; }
g_base = r_base + size; - if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) { + if (copy_to_user(uaddr_to_user_ptr(crtc_lut->green), g_base, size)) { ret = -EFAULT; goto out; }
b_base = g_base + size; - if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) { + if (copy_to_user(uaddr_to_user_ptr(crtc_lut->blue), b_base, size)) { ret = -EFAULT; goto out; } diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 61c29ce74b03..3fce01825728 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -2679,7 +2679,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
if ((out_resp->count_encoders >= encoders_count) && encoders_count) { copied = 0; - encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr); + encoder_ptr = uaddr_to_user_ptr(out_resp->encoders_ptr);
drm_connector_for_each_possible_encoder(connector, encoder) { if (put_user(encoder->base.id, encoder_ptr + copied)) { @@ -2730,7 +2730,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, */ if ((out_resp->count_modes >= mode_count) && mode_count) { copied = 0; - mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr; + mode_ptr = uaddr_to_user_ptr(out_resp->modes_ptr); list_for_each_entry(mode, &connector->modes, head) { if (!mode->expose_to_userspace) continue; @@ -2782,8 +2782,8 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, * properties reflect the latest status. */ ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic, - (uint32_t __user *)(unsigned long)(out_resp->props_ptr), - (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr), + uaddr_to_user_ptr(out_resp->props_ptr), + uaddr_to_user_ptr(out_resp->prop_values_ptr), &out_resp->count_props); drm_modeset_unlock(&dev->mode_config.connection_mutex);
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index df9bf3c9206e..2d598d52ee70 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -853,7 +853,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
for (i = 0; i < crtc_req->count_connectors; i++) { connector_set[i] = NULL; - set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr; + set_connectors_ptr = uaddr_to_user_ptr(crtc_req->set_connectors_ptr); if (get_user(out_id, &set_connectors_ptr[i])) { ret = -EFAULT; goto out; diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 2dd97473ca10..394896984d47 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -711,7 +711,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, return -ENOENT;
num_clips = r->num_clips; - clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr; + clips_ptr = uaddr_to_user_ptr(r->clips_ptr);
if (!num_clips != !clips_ptr) { ret = -EINVAL; diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index d72c2fac0ff1..bc9b6cfab2b8 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c @@ -587,7 +587,7 @@ int drm_mode_list_lessees_ioctl(struct drm_device *dev, void *data, struct drm_file *lessor_priv) { struct drm_mode_list_lessees *arg = data; - __u32 __user *lessee_ids = (__u32 __user *) (uintptr_t) (arg->lessees_ptr); + __u32 __user *lessee_ids = uaddr_to_user_ptr(arg->lessees_ptr); __u32 count_lessees = arg->count_lessees; struct drm_master *lessor, *lessee; int count; @@ -634,7 +634,7 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev, void *data, struct drm_file *lessee_priv) { struct drm_mode_get_lease *arg = data; - __u32 __user *object_ids = (__u32 __user *) (uintptr_t) (arg->objects_ptr); + __u32 __user *object_ids = uaddr_to_user_ptr(arg->objects_ptr); __u32 count_objects = arg->count_objects; struct drm_master *lessee; struct idr *object_idr; diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index ba1608effc0f..041903363a3d 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -454,8 +454,8 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, }
ret = drm_mode_object_get_properties(obj, file_priv->atomic, - (uint32_t __user *)(unsigned long)(arg->props_ptr), - (uint64_t __user *)(unsigned long)(arg->prop_values_ptr), + uaddr_to_user_ptr(arg->props_ptr), + uaddr_to_user_ptr(arg->prop_values_ptr), &arg->count_props);
out_unref: diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 33357629a7f5..b32530db64a0 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -727,7 +727,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data, */ if (plane->format_count && (plane_resp->count_format_types >= plane->format_count)) { - format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr; + format_ptr = uaddr_to_user_ptr(plane_resp->format_type_ptr); if (copy_to_user(format_ptr, plane->format_types, sizeof(uint32_t) * plane->format_count)) {
Various Panfrost uapi structs represent user pointers as __u64, which is not PCuABI-friendly. For now let's create a user pointer manually using uaddr_to_user_ptr(), but eventually the structs should be modified to represent the user pointer fields as __kernel_uintptr_t instead, allowing userspace to provide a whole user pointer instead of just an address.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- drivers/gpu/drm/panfrost/panfrost_drv.c | 4 ++-- drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 2fa5afe21288..9f79b024a840 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -139,7 +139,7 @@ panfrost_lookup_bos(struct drm_device *dev, return 0;
ret = drm_gem_objects_lookup(file_priv, - (void __user *)(uintptr_t)args->bo_handles, + uaddr_to_user_ptr(args->bo_handles), job->bo_count, &job->bos); if (ret) return ret; @@ -203,7 +203,7 @@ panfrost_copy_in_sync(struct drm_device *dev, }
if (copy_from_user(handles, - (void __user *)(uintptr_t)args->in_syncs, + uaddr_to_user_ptr(args->in_syncs), in_fence_count * sizeof(u32))) { ret = -EFAULT; DRM_DEBUG("Failed to copy in syncobj handles\n"); diff --git a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c index bc0df93f7f21..d917c8733813 100644 --- a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c +++ b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c @@ -240,7 +240,7 @@ int panfrost_ioctl_perfcnt_dump(struct drm_device *dev, void *data, struct panfrost_device *pfdev = dev->dev_private; struct panfrost_perfcnt *perfcnt = pfdev->perfcnt; struct drm_panfrost_perfcnt_dump *req = data; - void __user *user_ptr = (void __user *)(uintptr_t)req->buf_ptr; + void __user *user_ptr = uaddr_to_user_ptr(req->buf_ptr); int ret;
ret = panfrost_unstable_ioctl_check();
On 16/02/2023 15:00, Kevin Brodsky wrote:
Hi,
This is a small update to the series, see the cover letter of v1 for more information. Thanks everyone for the reviews!
v1..v2:
- Fixed a couple of typos in commit messages.
- Added initialisation of msg_control_is_user in do_ipv6_setsockopt() (patch 13)
Review branch:
https://git.morello-project.org/kbrodsky-arm/linux/-/commits/morello/gcc_fix...
Thanks, Kevin
Kevin Brodsky (18): arm64: signal: Avoid unnecessary capability arithmetic drivers/android/binder: Cast to (void *) when printing %p drivers/android/binder: Cast user_uintptr_t arg when printing math.h: Make round_{up,down} capability-friendly asm-generic/cacheflush.h: Use appropriate user pointer conversion kernel: signal: Use appropriate user pointer conversion perf/core: Use appropriate user pointer conversion compat: Fix shift warning in compat64 audit: Explicitly create user pointer coredump: Explicitly create user pointer kernel/futex: Explicitly create user pointer rseq: Explicitly create user pointers net: Finish up ->msg_control{,_user} split tcp: Explicitly create user pointers Input: evdev: Explicitly create user pointers mmc: block: Explicitly create user pointers drm: Explicitly create user pointers drm/panfrost: Explicitly create user pointers
Now in next.
Kevin
arch/arm64/kernel/signal.c | 6 +++-- drivers/android/binder.c | 4 ++-- drivers/android/binder_alloc.c | 25 +++++++++++---------- drivers/gpu/drm/drm_atomic_uapi.c | 8 +++---- drivers/gpu/drm/drm_color_mgmt.c | 12 +++++----- drivers/gpu/drm/drm_connector.c | 8 +++---- drivers/gpu/drm/drm_crtc.c | 2 +- drivers/gpu/drm/drm_framebuffer.c | 2 +- drivers/gpu/drm/drm_lease.c | 4 ++-- drivers/gpu/drm/drm_mode_object.c | 4 ++-- drivers/gpu/drm/drm_plane.c | 2 +- drivers/gpu/drm/panfrost/panfrost_drv.c | 4 ++-- drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 2 +- drivers/input/evdev.c | 4 ++-- drivers/mmc/core/block.c | 6 ++--- fs/coredump.c | 2 +- include/asm-generic/cacheflush.h | 6 ++--- include/linux/math.h | 5 +++++ kernel/auditsc.c | 2 +- kernel/compat.c | 4 ++-- kernel/events/core.c | 2 +- kernel/futex/waitwake.c | 2 +- kernel/rseq.c | 4 ++-- kernel/signal.c | 2 +- net/compat.c | 13 ++++++----- net/core/scm.c | 9 +++++--- net/ipv4/tcp.c | 8 +++---- net/ipv6/ipv6_sockglue.c | 1 + 28 files changed, 83 insertions(+), 70 deletions(-)
linux-morello@op-lists.linaro.org