On Fri, Oct 18, 2019 at 08:33:11AM -0700, Randy Dunlap wrote: > On 10/18/19 12:03 AM, Stephen Rothwell wrote: > > Hi all, > > > > Changes since 20191017: > > > > on x86_64: > lib/usercopy.o: warning: objtool: check_zeroed_user()+0x35f: call to __ubsan_handle_shift_out_of_bounds() with UACCESS enabled Blergh... I suppose the below will fix that. I'm a bit conflicted on it though, the alternative is annotating more ubsan crud. --- lib/usercopy.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/usercopy.c b/lib/usercopy.c index cbb4d9ec00f2..9c5245778dfd 100644 --- a/lib/usercopy.c +++ b/lib/usercopy.c @@ -49,21 +49,28 @@ EXPORT_SYMBOL(_copy_to_user); */ int check_zeroed_user(const void __user *from, size_t size) { + unsigned long head_mask, tail_mask; unsigned long val; - uintptr_t align = (uintptr_t) from % sizeof(unsigned long); + uintptr_t align; if (unlikely(size == 0)) return 1; - from -= align; - size += align; + align = (uintptr_t) from % sizeof(unsigned long); + if (align) { + from -= align; + size += align; + head_mask = ~aligned_byte_mask(align); + } + + tail_mask = aligned_byte_mask(size % sizeof(unsigned long)); if (!user_access_begin(from, size)) return -EFAULT; unsafe_get_user(val, (unsigned long __user *) from, err_fault); if (align) - val &= ~aligned_byte_mask(align); + val &= head_mask; while (size > sizeof(unsigned long)) { if (unlikely(val)) @@ -76,7 +83,7 @@ int check_zeroed_user(const void __user *from, size_t size) } if (size < sizeof(unsigned long)) - val &= aligned_byte_mask(size); + val &= tail_mask; done: user_access_end();