Return EOVERFLOW error in case then the size of tv_sec field of struct timespec

in COMPAT_LINUX32 Linuxulator's not equal to the size of native tv_sec.

MFC after:	1 month
This commit is contained in:
Dmitry Chagin 2017-02-26 09:40:42 +00:00
parent 354aa2dd56
commit 0670e972e3
3 changed files with 30 additions and 14 deletions

View file

@ -2290,8 +2290,9 @@ linux_pselect6(struct thread *td, struct linux_pselect6_args *args)
TIMEVAL_TO_TIMESPEC(&utv, &uts);
native_to_linux_timespec(&lts, &uts);
error = copyout(&lts, args->tsp, sizeof(lts));
error = native_to_linux_timespec(&lts, &uts);
if (error == 0)
error = copyout(&lts, args->tsp, sizeof(lts));
}
return (error);
@ -2343,8 +2344,9 @@ linux_ppoll(struct thread *td, struct linux_ppoll_args *args)
} else
timespecclear(&uts);
native_to_linux_timespec(&lts, &uts);
error = copyout(&lts, args->tsp, sizeof(lts));
error = native_to_linux_timespec(&lts, &uts);
if (error == 0)
error = copyout(&lts, args->tsp, sizeof(lts));
}
return (error);
@ -2438,7 +2440,9 @@ linux_sched_rr_get_interval(struct thread *td,
PROC_UNLOCK(tdt->td_proc);
if (error != 0)
return (error);
native_to_linux_timespec(&lts, &ts);
error = native_to_linux_timespec(&lts, &ts);
if (error != 0)
return (error);
return (copyout(&lts, uap->interval, sizeof(lts)));
}

View file

@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/ucred.h>
#include <sys/limits.h>
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/resourcevar.h>
@ -118,16 +119,21 @@ LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_clockid, "int");
LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, return, "int");
void
int
native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp)
{
LIN_SDT_PROBE2(time, native_to_linux_timespec, entry, ltp, ntp);
#ifdef COMPAT_LINUX32
if (ntp->tv_sec > INT_MAX &&
sizeof(ltp->tv_sec) != sizeof(ntp->tv_sec))
return (EOVERFLOW);
#endif
ltp->tv_sec = ntp->tv_sec;
ltp->tv_nsec = ntp->tv_nsec;
LIN_SDT_PROBE0(time, native_to_linux_timespec, return);
return (0);
}
int
@ -322,8 +328,9 @@ linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args)
LIN_SDT_PROBE1(time, linux_clock_gettime, return, error);
return (error);
}
native_to_linux_timespec(&lts, &tp);
error = native_to_linux_timespec(&lts, &tp);
if (error != 0)
return (error);
error = copyout(&lts, args->tp, sizeof lts);
if (error != 0)
LIN_SDT_PROBE1(time, linux_clock_gettime, copyout_error, error);
@ -450,8 +457,9 @@ linux_clock_getres(struct thread *td, struct linux_clock_getres_args *args)
LIN_SDT_PROBE1(time, linux_clock_getres, return, error);
return (error);
}
native_to_linux_timespec(&lts, &ts);
error = native_to_linux_timespec(&lts, &ts);
if (error != 0)
return (error);
error = copyout(&lts, args->tp, sizeof lts);
if (error != 0)
LIN_SDT_PROBE1(time, linux_clock_getres, copyout_error, error);
@ -490,7 +498,9 @@ linux_nanosleep(struct thread *td, struct linux_nanosleep_args *args)
}
error = kern_nanosleep(td, &rqts, rmtp);
if (args->rmtp != NULL) {
native_to_linux_timespec(&lrmts, rmtp);
error2 = native_to_linux_timespec(&lrmts, rmtp);
if (error2 != 0)
return (error2);
error2 = copyout(&lrmts, args->rmtp, sizeof(lrmts));
if (error2 != 0) {
LIN_SDT_PROBE1(time, linux_nanosleep, copyout_error,
@ -553,7 +563,9 @@ linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args
error = kern_nanosleep(td, &rqts, rmtp);
if (args->rmtp != NULL) {
/* XXX. Not for TIMER_ABSTIME */
native_to_linux_timespec(&lrmts, rmtp);
error2 = native_to_linux_timespec(&lrmts, rmtp);
if (error2 != 0)
return (error2);
error2 = copyout(&lrmts, args->rmtp, sizeof(lrmts));
if (error2 != 0) {
LIN_SDT_PROBE1(time, linux_clock_nanosleep,

View file

@ -111,7 +111,7 @@ struct l_itimerspec {
struct l_timespec it_value;
};
void native_to_linux_timespec(struct l_timespec *,
int native_to_linux_timespec(struct l_timespec *,
struct timespec *);
int linux_to_native_timespec(struct timespec *,
struct l_timespec *);