The overflow check was hosed in two ways: overflows in C are undefined,
hence gcc was free to just optimize the whole thing away. We need to
catch overflows before we run into them, not after.
It checked for an overflow against size_t, but the field we need to
write this in is unsigned. i.e. typically 32bit rather than 64bit. Hence
check for the right maximum.
(The whole check is paranoia anyway, the kernel really shouldn't return
values that would induce an overflow, but you never know, the syscall
turned out to be problematic in so many other ways, hence let's stick to
this.)
/* The buffer was too small. Size the new buffer by what name_to_handle_at() returned. */
n = h->handle_bytes;
- if (offsetof(struct file_handle, f_handle) + n < n) /* check for addition overflow */
+
+ /* paranoia: check for overlow (note that .handle_bytes is unsigned only) */
+ if (n > UINT_MAX - offsetof(struct file_handle, f_handle))
return -EOVERFLOW;
}
}