Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

um: ubd: use 64-bit time_t where possible

The ubd code suffers from a possible y2038 overflow on 32-bit
architectures, both for the cow header and the os_file_modtime()
function.

Replace time_t with time64_t to extend the ubd_kern side as much
as possible.

Whether this makes a difference for the user side depends on
the host libc implementation that may use either 32-bit or 64-bit
time_t.

For the cow file format, the header contains an unsigned 32-bit
timestamp, which is good until y2106, passing this through a
'long long' gives us a consistent interpretation between 32-bit
and 64-bit um kernels.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+12 -11
+1 -1
arch/um/drivers/cow.h
··· 11 11 extern int file_reader(__u64 offset, char *buf, int len, void *arg); 12 12 extern int read_cow_header(int (*reader)(__u64, char *, int, void *), 13 13 void *arg, __u32 *version_out, 14 - char **backing_file_out, time_t *mtime_out, 14 + char **backing_file_out, long long *mtime_out, 15 15 unsigned long long *size_out, int *sectorsize_out, 16 16 __u32 *align_out, int *bitmap_offset_out); 17 17
+4 -3
arch/um/drivers/cow_user.c
··· 17 17 18 18 #define PATH_LEN_V1 256 19 19 20 + /* unsigned time_t works until year 2106 */ 20 21 typedef __u32 time32_t; 21 22 22 23 struct cow_header_v1 { ··· 198 197 int sectorsize, int alignment, unsigned long long *size) 199 198 { 200 199 struct cow_header_v3 *header; 201 - unsigned long modtime; 200 + long long modtime; 202 201 int err; 203 202 204 203 err = cow_seek_file(fd, 0); ··· 277 276 278 277 int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, 279 278 __u32 *version_out, char **backing_file_out, 280 - time_t *mtime_out, unsigned long long *size_out, 279 + long long *mtime_out, unsigned long long *size_out, 281 280 int *sectorsize_out, __u32 *align_out, 282 281 int *bitmap_offset_out) 283 282 { ··· 364 363 365 364 /* 366 365 * this was used until Dec2005 - 64bits are needed to represent 367 - * 2038+. I.e. we can safely do this truncating cast. 366 + * 2106+. I.e. we can safely do this truncating cast. 368 367 * 369 368 * Additionally, we must use be32toh() instead of be64toh(), since 370 369 * the program used to use the former (tested - I got mtime
+5 -5
arch/um/drivers/ubd_kern.c
··· 561 561 __u32 version; 562 562 __u32 align; 563 563 char *backing_file; 564 - time_t mtime; 564 + time64_t mtime; 565 565 unsigned long long size; 566 566 int sector_size; 567 567 int bitmap_offset; ··· 600 600 return 0; 601 601 } 602 602 603 - static int backing_file_mismatch(char *file, __u64 size, time_t mtime) 603 + static int backing_file_mismatch(char *file, __u64 size, time64_t mtime) 604 604 { 605 - unsigned long modtime; 605 + time64_t modtime; 606 606 unsigned long long actual; 607 607 int err; 608 608 ··· 628 628 return -EINVAL; 629 629 } 630 630 if (modtime != mtime) { 631 - printk(KERN_ERR "mtime mismatch (%ld vs %ld) of COW header vs " 631 + printk(KERN_ERR "mtime mismatch (%lld vs %lld) of COW header vs " 632 632 "backing file\n", mtime, modtime); 633 633 return -EINVAL; 634 634 } ··· 671 671 unsigned long *bitmap_len_out, int *data_offset_out, 672 672 int *create_cow_out) 673 673 { 674 - time_t mtime; 674 + time64_t mtime; 675 675 unsigned long long size; 676 676 __u32 version, align; 677 677 char *backing_file;
+1 -1
arch/um/include/shared/os.h
··· 150 150 extern int os_file_size(const char *file, unsigned long long *size_out); 151 151 extern int os_pread_file(int fd, void *buf, int len, unsigned long long offset); 152 152 extern int os_pwrite_file(int fd, const void *buf, int count, unsigned long long offset); 153 - extern int os_file_modtime(const char *file, unsigned long *modtime); 153 + extern int os_file_modtime(const char *file, long long *modtime); 154 154 extern int os_pipe(int *fd, int stream, int close_on_exec); 155 155 extern int os_set_fd_async(int fd); 156 156 extern int os_clear_fd_async(int fd);
+1 -1
arch/um/os-Linux/file.c
··· 341 341 return 0; 342 342 } 343 343 344 - int os_file_modtime(const char *file, unsigned long *modtime) 344 + int os_file_modtime(const char *file, long long *modtime) 345 345 { 346 346 struct uml_stat buf; 347 347 int err;