Hi, On Fri, May 10, 2024 at 02:04:51AM +0100, Al Viro wrote: > On Fri, May 10, 2024 at 01:49:06AM +0100, Al Viro wrote: > > On Fri, May 10, 2024 at 12:35:51AM +0000, Justin Stitt wrote: > > > @@ -147,7 +147,9 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence) > > > struct dentry *dentry = file->f_path.dentry; > > > switch (whence) { > > > case 1: > > > - offset += file->f_pos; > > > + /* cannot represent offset with loff_t */ > > > + if (check_add_overflow(offset, file->f_pos, &offset)) > > > + return -EOVERFLOW; > > > > Instead of -EINVAL it correctly returns in such cases? Why? > > We have file->f_pos in range 0..LLONG_MAX. We are adding a value in > range LLONG_MIN..LLONG_MAX. The sum (in $\Bbb Z$) cannot be below > LLONG_MIN or above 2 * LLONG_MAX, so if it can't be represented by loff_t, > it must have been in range LLONG_MAX + 1 .. 2 * LLONG_MAX. Result of > wraparound would be equal to that sum - 2 * LLONG_MAX - 2, which is going > to be in no greater than -2. We will run > fallthrough; > case 0: > if (offset >= 0) > break; > fallthrough; > default: > return -EINVAL; > and fail with -EINVAL. This feels like a case of accidental correctness. You demonstrated that even with overflow we end up going down a control path that returns an error code so all is good. However, I think finding the solution shouldn't require as much mental gymnastics. We clearly don't want our file offsets to wraparound and a plain-and-simple check for that lets readers of the code understand this. > > Could you explain why would -EOVERFLOW be preferable and why should we > engage in that bit of cargo cult? I noticed some patterns in fs/ regarding -EOVERFLOW and thought this was a good application of this particular error code. Some examples: read_write.c::do_sendfile() ... if (unlikely(pos + count > max)) { retval = -EOVERFLOW; if (pos >= max) goto fput_out; count = max - pos; } read_write.c::generic_copy_file_checks() ... /* Ensure offsets don't wrap. */ if (pos_in + count < pos_in || pos_out + count < pos_out) return -EOVERFLOW; ... amongst others. So to answer your question, I don't have strong feelings about what the error code should be; I was just attempting to match patterns I had seen within this section of the codebase when handling overflow/wraparound. If -EOVERFLOW is technically incorrect or if it is just bad style, I'm happy to send a new version swapping it over to -EINVAL Thanks Justin