Skip to content

Commit

Permalink
lkl: fix 32-bit timespec casts
Browse files Browse the repository at this point in the history
On 32-bit architectures, struct lkl_timespec is 2*sizeof(long) while
__lkl__kernel_timespec is 2*sizeof(long long); casting these pointer
types is unsafe.

Fixes: 3d4047a ("lkl: follow up fixes after v5.1 merge (y2038)")
Signed-off-by: David Disseldorp <[email protected]>
  • Loading branch information
ddiss committed Feb 5, 2025
1 parent ab1c2d0 commit 0692c1e
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 34 deletions.
30 changes: 16 additions & 14 deletions tools/lkl/cptofs.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,22 +463,24 @@ static int do_entry(const char *_src, const char *_dst, const char *name, uid_t
printf("skipping %s: unsupported entry type %d\n", src, type);
}

if (!ret) {
if (cptofs) {
struct lkl_timespec lkl_ts[] = { atime, mtime };
if (ret)
goto err_out;

ret = lkl_sys_utimensat(LKL_AT_FDCWD, dst,
(struct __lkl__kernel_timespec
*)lkl_ts,
LKL_AT_SYMLINK_NOFOLLOW);
} else {
struct timespec ts[] = {
{ .tv_sec = atime.tv_sec, .tv_nsec = atime.tv_nsec, },
{ .tv_sec = mtime.tv_sec, .tv_nsec = mtime.tv_nsec, },
};
if (cptofs) {
struct __lkl__kernel_timespec lkl_ts[] = {
{ .tv_sec = atime.tv_sec, .tv_nsec = atime.tv_nsec, },
{ .tv_sec = mtime.tv_sec, .tv_nsec = mtime.tv_nsec, },
};

ret = utimensat(AT_FDCWD, dst, ts, AT_SYMLINK_NOFOLLOW);
}
ret = lkl_sys_utimensat(LKL_AT_FDCWD, dst, lkl_ts,
LKL_AT_SYMLINK_NOFOLLOW);
} else {
struct timespec ts[] = {
{ .tv_sec = atime.tv_sec, .tv_nsec = atime.tv_nsec, },
{ .tv_sec = mtime.tv_sec, .tv_nsec = mtime.tv_nsec, },
};

ret = utimensat(AT_FDCWD, dst, ts, AT_SYMLINK_NOFOLLOW);
}

err_out:
Expand Down
19 changes: 11 additions & 8 deletions tools/lkl/include/lkl.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ static inline long lkl_sys_select(int n, lkl_fd_set *rfds, lkl_fd_set *wfds,
lkl_fd_set *efds, struct lkl_timeval *tv)
{
long data[2] = { 0, _LKL_NSIG/8 };
struct lkl_timespec ts;
struct __lkl__kernel_timespec ts;

if (tv) {
if (tv->tv_sec < 0 || tv->tv_usec < 0)
Expand All @@ -285,8 +285,7 @@ static inline long lkl_sys_select(int n, lkl_fd_set *rfds, lkl_fd_set *wfds,
ts.tv_sec = tv->tv_sec;
ts.tv_nsec = tv->tv_usec * 1000;
}
return lkl_sys_pselect6(n, rfds, wfds, efds, tv ?
(struct __lkl__kernel_timespec *)&ts : 0, data);
return lkl_sys_pselect6(n, rfds, wfds, efds, tv ? &ts : 0, data);
}
#endif

Expand All @@ -296,11 +295,15 @@ static inline long lkl_sys_select(int n, lkl_fd_set *rfds, lkl_fd_set *wfds,
*/
static inline long lkl_sys_poll(struct lkl_pollfd *fds, int n, int timeout)
{
return lkl_sys_ppoll(fds, n, timeout >= 0 ?
(struct __lkl__kernel_timespec *)
&((struct lkl_timespec){ .tv_sec = timeout/1000,
.tv_nsec = timeout%1000*1000000 }) : 0,
0, _LKL_NSIG/8);
struct __lkl__kernel_timespec ts;

if (timeout >= 0)
ts = (struct __lkl__kernel_timespec){
.tv_sec = timeout / 1000,
.tv_nsec = timeout % 1000 * 1000000,
};

return lkl_sys_ppoll(fds, n, timeout >= 0 ? &ts : 0, 0, _LKL_NSIG/8);
}
#endif

Expand Down
20 changes: 8 additions & 12 deletions tools/lkl/lklfuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,19 +503,16 @@ static int lklfuse_utimens(const char *path, const struct timespec tv[2],
struct fuse_file_info *fi)
{
int ret;
struct lkl_timespec ts[2] = {
struct __lkl__kernel_timespec ts[2] = {
{ .tv_sec = tv[0].tv_sec, .tv_nsec = tv[0].tv_nsec },
{ .tv_sec = tv[1].tv_sec, .tv_nsec = tv[1].tv_nsec },
};

if (fi)
ret = lkl_sys_utimensat(fi->fh, NULL,
(struct __lkl__kernel_timespec *)ts,
0);
ret = lkl_sys_utimensat(fi->fh, NULL, ts, 0);
else
ret = lkl_sys_utimensat(-1, path,
(struct __lkl__kernel_timespec *)ts,
LKL_AT_SYMLINK_NOFOLLOW);
ret = lkl_sys_utimensat(-1, path, ts, LKL_AT_SYMLINK_NOFOLLOW);

return ret;
}

Expand Down Expand Up @@ -686,7 +683,7 @@ static int start_lkl(void)
long ret;
char mpoint[32];
struct timespec walltime;
struct lkl_timespec ts;
struct __lkl__kernel_timespec ts;
int mount_flags = 0;
char remaining_mopts[4096] = { 0 };

Expand All @@ -709,10 +706,9 @@ static int start_lkl(void)
if (ret < 0)
goto out_halt;

ts = (struct lkl_timespec){ .tv_sec = walltime.tv_sec,
.tv_nsec = walltime.tv_nsec };
ret = lkl_sys_clock_settime(LKL_CLOCK_REALTIME,
(struct __lkl__kernel_timespec *)&ts);
ts = (struct __lkl__kernel_timespec){ .tv_sec = walltime.tv_sec,
.tv_nsec = walltime.tv_nsec };
ret = lkl_sys_clock_settime(LKL_CLOCK_REALTIME, &ts);
if (ret < 0) {
fprintf(stderr, "lkl_sys_clock_settime() failed: %s\n",
lkl_strerror(ret));
Expand Down

0 comments on commit 0692c1e

Please sign in to comment.