]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
um: ubd: use 64-bit time_t where possible
authorArnd Bergmann <arnd@arndb.de>
Tue, 5 Nov 2019 08:39:51 +0000 (09:39 +0100)
committerArnd Bergmann <arnd@arndb.de>
Wed, 18 Dec 2019 17:07:31 +0000 (18:07 +0100)
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>
arch/um/drivers/cow.h
arch/um/drivers/cow_user.c
arch/um/drivers/ubd_kern.c
arch/um/include/shared/os.h
arch/um/os-Linux/file.c

index 760c507dd5b6630c1899c17033ce4c1bf850c028..103adac691ed91c5ac81da70ffb457f8dea626ae 100644 (file)
@@ -11,7 +11,7 @@ extern int init_cow_file(int fd, char *cow_file, char *backing_file,
 extern int file_reader(__u64 offset, char *buf, int len, void *arg);
 extern int read_cow_header(int (*reader)(__u64, char *, int, void *),
                           void *arg, __u32 *version_out,
-                          char **backing_file_out, time_t *mtime_out,
+                          char **backing_file_out, long long *mtime_out,
                           unsigned long long *size_out, int *sectorsize_out,
                           __u32 *align_out, int *bitmap_offset_out);
 
index 74b0c2686c95e7b5fdd8c6c82ad17457e2c03433..29b46581ddd137c6418d8b8d6ec7a6febe4080c1 100644 (file)
@@ -17,6 +17,7 @@
 
 #define PATH_LEN_V1 256
 
+/* unsigned time_t works until year 2106 */
 typedef __u32 time32_t;
 
 struct cow_header_v1 {
@@ -197,7 +198,7 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
                     int sectorsize, int alignment, unsigned long long *size)
 {
        struct cow_header_v3 *header;
-       unsigned long modtime;
+       long long modtime;
        int err;
 
        err = cow_seek_file(fd, 0);
@@ -276,7 +277,7 @@ int file_reader(__u64 offset, char *buf, int len, void *arg)
 
 int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
                    __u32 *version_out, char **backing_file_out,
-                   time_t *mtime_out, unsigned long long *size_out,
+                   long long *mtime_out, unsigned long long *size_out,
                    int *sectorsize_out, __u32 *align_out,
                    int *bitmap_offset_out)
 {
@@ -363,7 +364,7 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
 
                /*
                 * this was used until Dec2005 - 64bits are needed to represent
-                * 2038+. I.e. we can safely do this truncating cast.
+                * 2106+. I.e. we can safely do this truncating cast.
                 *
                 * Additionally, we must use be32toh() instead of be64toh(), since
                 * the program used to use the former (tested - I got mtime
index 6627d7c30f3700954ca655527b3490dbf28dacde..dcabb463e011f930044d533e28c1263fcf27c692 100644 (file)
@@ -561,7 +561,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
        __u32 version;
        __u32 align;
        char *backing_file;
-       time_t mtime;
+       time64_t mtime;
        unsigned long long size;
        int sector_size;
        int bitmap_offset;
@@ -600,9 +600,9 @@ static int read_cow_bitmap(int fd, void *buf, int offset, int len)
        return 0;
 }
 
-static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
+static int backing_file_mismatch(char *file, __u64 size, time64_t mtime)
 {
-       unsigned long modtime;
+       time64_t modtime;
        unsigned long long actual;
        int err;
 
@@ -628,7 +628,7 @@ static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
                return -EINVAL;
        }
        if (modtime != mtime) {
-               printk(KERN_ERR "mtime mismatch (%ld vs %ld) of COW header vs "
+               printk(KERN_ERR "mtime mismatch (%lld vs %lld) of COW header vs "
                       "backing file\n", mtime, modtime);
                return -EINVAL;
        }
@@ -671,7 +671,7 @@ static int open_ubd_file(char *file, struct openflags *openflags, int shared,
                  unsigned long *bitmap_len_out, int *data_offset_out,
                  int *create_cow_out)
 {
-       time_t mtime;
+       time64_t mtime;
        unsigned long long size;
        __u32 version, align;
        char *backing_file;
index 506bcd1bca68512225405f2aa01e54f5f81a5bc9..0f30204b6afa86e4116df23b02d152bb94c27012 100644 (file)
@@ -150,7 +150,7 @@ extern int os_sync_file(int fd);
 extern int os_file_size(const char *file, unsigned long long *size_out);
 extern int os_pread_file(int fd, void *buf, int len, unsigned long long offset);
 extern int os_pwrite_file(int fd, const void *buf, int count, unsigned long long offset);
-extern int os_file_modtime(const char *file, unsigned long *modtime);
+extern int os_file_modtime(const char *file, long long *modtime);
 extern int os_pipe(int *fd, int stream, int close_on_exec);
 extern int os_set_fd_async(int fd);
 extern int os_clear_fd_async(int fd);
index 5133e3afb96f707f3e71814fb64046e47a2d8bd5..fbda10535dab052a6ef41181b8844ef63f5adc50 100644 (file)
@@ -341,7 +341,7 @@ int os_file_size(const char *file, unsigned long long *size_out)
        return 0;
 }
 
-int os_file_modtime(const char *file, unsigned long *modtime)
+int os_file_modtime(const char *file, long long *modtime)
 {
        struct uml_stat buf;
        int err;