Commit 853bc0ab authored by Arnd Bergmann's avatar Arnd Bergmann

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: default avatarArnd Bergmann <arnd@arndb.de>
parent 37e86e0f
...@@ -11,7 +11,7 @@ extern int init_cow_file(int fd, char *cow_file, char *backing_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 file_reader(__u64 offset, char *buf, int len, void *arg);
extern int read_cow_header(int (*reader)(__u64, char *, int, void *), extern int read_cow_header(int (*reader)(__u64, char *, int, void *),
void *arg, __u32 *version_out, 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, unsigned long long *size_out, int *sectorsize_out,
__u32 *align_out, int *bitmap_offset_out); __u32 *align_out, int *bitmap_offset_out);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#define PATH_LEN_V1 256 #define PATH_LEN_V1 256
/* unsigned time_t works until year 2106 */
typedef __u32 time32_t; typedef __u32 time32_t;
struct cow_header_v1 { struct cow_header_v1 {
...@@ -197,7 +198,7 @@ int write_cow_header(char *cow_file, int fd, char *backing_file, ...@@ -197,7 +198,7 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
int sectorsize, int alignment, unsigned long long *size) int sectorsize, int alignment, unsigned long long *size)
{ {
struct cow_header_v3 *header; struct cow_header_v3 *header;
unsigned long modtime; long long modtime;
int err; int err;
err = cow_seek_file(fd, 0); err = cow_seek_file(fd, 0);
...@@ -276,7 +277,7 @@ int file_reader(__u64 offset, char *buf, int len, void *arg) ...@@ -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, int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
__u32 *version_out, char **backing_file_out, __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 *sectorsize_out, __u32 *align_out,
int *bitmap_offset_out) int *bitmap_offset_out)
{ {
...@@ -363,7 +364,7 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, ...@@ -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 * 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 * Additionally, we must use be32toh() instead of be64toh(), since
* the program used to use the former (tested - I got mtime * the program used to use the former (tested - I got mtime
......
...@@ -561,7 +561,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) ...@@ -561,7 +561,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
__u32 version; __u32 version;
__u32 align; __u32 align;
char *backing_file; char *backing_file;
time_t mtime; time64_t mtime;
unsigned long long size; unsigned long long size;
int sector_size; int sector_size;
int bitmap_offset; int bitmap_offset;
...@@ -600,9 +600,9 @@ static int read_cow_bitmap(int fd, void *buf, int offset, int len) ...@@ -600,9 +600,9 @@ static int read_cow_bitmap(int fd, void *buf, int offset, int len)
return 0; 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; unsigned long long actual;
int err; int err;
...@@ -628,7 +628,7 @@ static int backing_file_mismatch(char *file, __u64 size, time_t mtime) ...@@ -628,7 +628,7 @@ static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
return -EINVAL; return -EINVAL;
} }
if (modtime != mtime) { 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); "backing file\n", mtime, modtime);
return -EINVAL; return -EINVAL;
} }
...@@ -671,7 +671,7 @@ static int open_ubd_file(char *file, struct openflags *openflags, int shared, ...@@ -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, unsigned long *bitmap_len_out, int *data_offset_out,
int *create_cow_out) int *create_cow_out)
{ {
time_t mtime; time64_t mtime;
unsigned long long size; unsigned long long size;
__u32 version, align; __u32 version, align;
char *backing_file; char *backing_file;
......
...@@ -150,7 +150,7 @@ extern int os_sync_file(int fd); ...@@ -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_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_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_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_pipe(int *fd, int stream, int close_on_exec);
extern int os_set_fd_async(int fd); extern int os_set_fd_async(int fd);
extern int os_clear_fd_async(int fd); extern int os_clear_fd_async(int fd);
......
...@@ -341,7 +341,7 @@ int os_file_size(const char *file, unsigned long long *size_out) ...@@ -341,7 +341,7 @@ int os_file_size(const char *file, unsigned long long *size_out)
return 0; 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; struct uml_stat buf;
int err; int err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment