Fix compat32 for ntp_adjtime(2).

struct timex is not 32-bit safe, it uses longs for members.
Provide translation.

Reviewed by:	brooks, cy
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D27471
This commit is contained in:
Konstantin Belousov 2020-12-04 18:57:58 +00:00
parent be2535b0a6
commit 31df9c26c5
3 changed files with 88 additions and 1 deletions

View File

@ -409,4 +409,24 @@ struct procctl_reaper_pids32 {
uint32_t rp_pids;
};
struct timex32 {
unsigned int modes;
int32_t offset;
int32_t freq;
int32_t maxerror;
int32_t esterror;
int status;
int32_t constant;
int32_t precision;
int32_t tolerance;
int32_t ppsfreq;
int32_t jitter;
int shift;
int32_t stabil;
int32_t jitcnt;
int32_t calcnt;
int32_t errcnt;
int32_t stbcnt;
};
#endif /* !_COMPAT_FREEBSD32_FREEBSD32_H_ */

View File

@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysproto.h>
#include <sys/systm.h>
#include <sys/thr.h>
#include <sys/timex.h>
#include <sys/unistd.h>
#include <sys/ucontext.h>
#include <sys/umtx.h>
@ -3766,3 +3767,68 @@ freebsd32_sched_rr_get_interval(struct thread *td,
}
return (error);
}
static void
timex_to_32(struct timex32 *dst, struct timex *src)
{
CP(*src, *dst, modes);
CP(*src, *dst, offset);
CP(*src, *dst, freq);
CP(*src, *dst, maxerror);
CP(*src, *dst, esterror);
CP(*src, *dst, status);
CP(*src, *dst, constant);
CP(*src, *dst, precision);
CP(*src, *dst, tolerance);
CP(*src, *dst, ppsfreq);
CP(*src, *dst, jitter);
CP(*src, *dst, shift);
CP(*src, *dst, stabil);
CP(*src, *dst, jitcnt);
CP(*src, *dst, calcnt);
CP(*src, *dst, errcnt);
CP(*src, *dst, stbcnt);
}
static void
timex_from_32(struct timex *dst, struct timex32 *src)
{
CP(*src, *dst, modes);
CP(*src, *dst, offset);
CP(*src, *dst, freq);
CP(*src, *dst, maxerror);
CP(*src, *dst, esterror);
CP(*src, *dst, status);
CP(*src, *dst, constant);
CP(*src, *dst, precision);
CP(*src, *dst, tolerance);
CP(*src, *dst, ppsfreq);
CP(*src, *dst, jitter);
CP(*src, *dst, shift);
CP(*src, *dst, stabil);
CP(*src, *dst, jitcnt);
CP(*src, *dst, calcnt);
CP(*src, *dst, errcnt);
CP(*src, *dst, stbcnt);
}
int
freebsd32_ntp_adjtime(struct thread *td, struct freebsd32_ntp_adjtime_args *uap)
{
struct timex tx;
struct timex32 tx32;
int error, retval;
error = copyin(uap->tp, &tx32, sizeof(tx32));
if (error == 0) {
timex_from_32(&tx, &tx32);
error = kern_ntp_adjtime(td, &tx, &retval);
if (error == 0) {
timex_to_32(&tx32, &tx);
error = copyout(&tx32, uap->tp, sizeof(tx32));
if (error == 0)
td->td_retval[0] = retval;
}
}
return (error);
}

View File

@ -343,7 +343,8 @@
const void *buf, size_t nbyte, int pad, \
uint32_t offset1, uint32_t offset2); }
175 AUE_NULL UNIMPL nosys
176 AUE_NTP_ADJTIME NOPROTO { int ntp_adjtime(struct timex *tp); }
176 AUE_NTP_ADJTIME STD { int freebsd32_ntp_adjtime( \
struct timex32 *tp); }
177 AUE_NULL UNIMPL sfork (BSD/OS 2.x)
178 AUE_NULL UNIMPL getdescriptor (BSD/OS 2.x)
179 AUE_NULL UNIMPL setdescriptor (BSD/OS 2.x)