lkml.org 
[lkml]   [2019]   [Jul]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Date
SubjectRe: [5.2 REGRESSION] Generic vDSO breaks seccomp-enabled userspace on i386
On Sat, Jul 27, 2019 at 2:52 PM Thomas Gleixner <tglx@linutronix.de> wrote:
>
> On Sat, 27 Jul 2019, Thomas Gleixner wrote:
> > On Sat, 27 Jul 2019, Andy Lutomirski wrote:
> > >
> > > I think it's getting quite late to start inventing new seccomp
> > > features to fix this. I think the right solution for 5.3 is to change
> > > the 32-bit vdso fallback to use the old clock_gettime, i.e.
> > > clock_gettime32. This is obviously not an acceptable long-term
> > > solution.
> >
> > Sigh. I'll have a look....
>
> Completely untested patch below.
>
> For the record: I have to say that I hate it.

Me too.

How about something more like the attached. (The attachment obviously
won't compile, since it's incomplete. I'm wondering if you think the
idea is okay. The idea is to have the vdso calls fall back to the
corresponding syscalls rather than internally converting.)

--Andy
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 2d1c1f241fd9..b7284330018d 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -51,7 +51,7 @@ static int do_hres(const struct vdso_data *vd, clockid_t clk,
ns = vdso_ts->nsec;
last = vd->cycle_last;
if (unlikely((s64)cycles < 0))
- return clock_gettime_fallback(clk, ts);
+ return -1;

ns += vdso_calc_delta(cycles, last, vd->mask, vd->mult);
ns >>= vd->shift;
@@ -86,6 +86,7 @@ __cvdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
{
const struct vdso_data *vd = __arch_get_vdso_data();
u32 msk;
+ int ret;

/* Check for negative values or invalid clocks */
if (unlikely((u32) clock >= MAX_CLOCKS))
@@ -97,14 +98,17 @@ __cvdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
*/
msk = 1U << clock;
if (likely(msk & VDSO_HRES)) {
- return do_hres(&vd[CS_HRES_COARSE], clock, ts);
+ ret = do_hres(&vd[CS_HRES_COARSE], clock, ts);
} else if (msk & VDSO_COARSE) {
do_coarse(&vd[CS_HRES_COARSE], clock, ts);
return 0;
} else if (msk & VDSO_RAW) {
- return do_hres(&vd[CS_RAW], clock, ts);
+ ret = do_hres(&vd[CS_RAW], clock, ts);
}

+ if (likely(ret == 0))
+ return clock_gettime_fallback(clock, ts);
+
fallback:
return clock_gettime_fallback(clock, ts);
}
@@ -120,15 +124,14 @@ __cvdso_clock_gettime32(clockid_t clock, struct old_timespec32 *res)

ret = __cvdso_clock_gettime(clock, &ts);

- if (ret == 0) {
+ if (likely(ret == 0)) {
res->tv_sec = ts.tv_sec;
res->tv_nsec = ts.tv_nsec;
+ return ret;
}

- return ret;
-
fallback:
- return clock_gettime_fallback(clock, (struct __kernel_timespec *)res);
+ return clock_gettime32_fallback(clock, (struct __kernel_timespec *)res);
}

static __maybe_unused int
\
 
 \ /
  Last update: 2019-07-28 02:34    [W:0.036 / U:1.636 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site