On Fri, Jan 12, 2018 at 8:49 PM, Jeff Moyer <jmoyer@xxxxxxxxxx> wrote: > Matthew Wilcox <willy@xxxxxxxxxxxxx> writes: > >> On Thu, Dec 14, 2017 at 11:18:30AM +0800, Leizhen (ThunderTown) wrote: >>> On 2017/12/14 3:31, Matthew Wilcox wrote: >>> > On Wed, Dec 13, 2017 at 11:27:00AM -0500, Jeff Moyer wrote: >>> >> Matthew Wilcox <willy@xxxxxxxxxxxxx> writes: >>> >> >>> >>> On Wed, Dec 13, 2017 at 09:42:52PM +0800, Zhen Lei wrote: >>> >>>> Below information is reported by a lower kernel version, and I saw the >>> >>>> problem still exist in current version. >>> >>> >>> >>> I think you're right, but what an awful interface we have here! >>> >>> The user must not only fetch it, they must validate it separately? >>> >>> And if they forget, then userspace is provoking undefined behaviour? Ugh. >>> >>> Why not this: >>> >> >>> >> Why not go a step further and have get_timespec64 check for validity? >>> >> I wonder what caller doesn't want that to happen... >>> I tried this before. But I found some places call get_timespec64 in the following function. >>> If we do the check in get_timespec64, the check will be duplicated. >>> >>> For example: >>> static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, >>> .... >>> if (get_timespec64(&ts, tsp)) >>> return -EFAULT; >>> >>> to = &end_time; >>> if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) >>> >>> int poll_select_set_timeout(struct timespec64 *to, time64_t sec, long nsec) >>> { >>> struct timespec64 ts = {.tv_sec = sec, .tv_nsec = nsec}; >>> >>> if (!timespec64_valid(&ts)) >>> return -EINVAL; >> >> The check is only two comparisons! Why do we have an interface that can >> cause bugs for the sake of saving *two comparisons*?! Can we talk about >> the cost of a cache miss versus the cost of executing these comparisons? > > Any update on this? Willy, I'd be okay with your get_valid_timespec64 > patch if you wanted to formally submit that. I had suggested a more complete helper function at some point, to take care of all combinations of checking/non-checking, 32/64 bit, microsecond/nanosecond, and zeroing/checking the upper 32 bits of nanoseconds before comparing against 1 billion, but Deepa thought that was overkill, so I didn't continue that. For all I can tell, the get_timespec64() helper should almost always include the check, the one exception I know is utimensat() and related functions that may encode the special UTIME_NOW and UTIME_OMIT constants in the nanoseconds. Arnd