On Sun, 22 Jun 2025 10:40:00 -0700 Linus Torvalds <torva...@linux-foundation.org> wrote:
> On Sun, 22 Jun 2025 at 10:13, David Laight <david.laight.li...@gmail.com> > wrote: > > > > Not checking the size is slightly orthogonal. > > It really just depends on the accesses being 'reasonably sequential'. > > That is probably always true since access_ok() covers a single copy. > > It is probably true in practice, but yeah, it's worth thinking about. > Particularly for various user level structure accesses, we do end up > often accessing the members individually and thus potentially out of > order, but as you say "reasonable sequential" is still true: the > accesses are within a reasonably small offset of each other. I found one that did ptr[4] followed by ptr[0]. Which was potentially problematic if changed to use 'masked' accesses before you changed the code to use cmov. > > And when we have potentially very big accesses with large offsets from > the beginning (ie things like read/write() calls), we do them > sequentially. > > There *might* be odd ioctls and such that get offsets from user space, > though. So any conversion to using 'masked_user_access_begin()' needs > to have at least *some* thought and not be just a mindless conversion > from access_ok(). True - but the ioctl (like) code is more likely to be using copy_to/from_user() on the offsetted address rather than trying to be too clever. > > We have this same issue in access_ok() itself, and on x86-64 that does > > static inline bool __access_ok(const void __user *ptr, unsigned long size) > { > if (__builtin_constant_p(size <= PAGE_SIZE) && size <= PAGE_SIZE) { > return valid_user_address(ptr); > .. do the more careful one that actually uses the 'size' ... > > so it turns access_ok() itself into just a simple single-ended > comparison with the starting address for small sizes, because we know > it's ok to overflow by a bit (because of how valid_user_address() > works on x86). IIRC there is a comment just below that the says the size could (probably) just be ignored. Given how few access_ok() there ought to be, checking them shouldn't be a problem. But I get either io_uring or bpf does something strange and unexpected that is probably a bug waiting to be found. Remembers some very strange code that has two iovec[] for reading data from a second process. I think I failed to find all the access_ok() tests. IIRC it isn't used by anything 'important' and could be nuked on security grounds. David > > Linus