s390/vdso: fix stack corruption

The kernel provided vdso functions do not get a stack frame from the
calling function and therefore may not change the stack contents, unless
they allocate space on their own.

This problem was exposed with 070b7be633 "s390/vdso: replace stck with
stcke" which writes 16 bytes instead of 8 bytes into the stack frame. These
additional 8 bytes however were indeed used by the caller (glibc) to save
data and therefore this data was corrupted by the vdso code.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Heiko Carstens 2014-10-27 08:28:08 +01:00 committed by Martin Schwidefsky
parent 1f759bb3a2
commit 9b2efe035e
4 changed files with 29 additions and 16 deletions

View file

@ -19,6 +19,7 @@
.type __kernel_clock_gettime,@function
__kernel_clock_gettime:
.cfi_startproc
ahi %r15,-16
basr %r5,0
0: al %r5,21f-0b(%r5) /* get &_vdso_data */
chi %r2,__CLOCK_REALTIME_COARSE
@ -34,8 +35,8 @@ __kernel_clock_gettime:
1: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
tml %r4,0x0001 /* pending update ? loop */
jnz 1b
stcke 24(%r15) /* Store TOD clock */
lm %r0,%r1,25(%r15)
stcke 0(%r15) /* Store TOD clock */
lm %r0,%r1,1(%r15)
s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,2f
@ -70,6 +71,7 @@ __kernel_clock_gettime:
8: st %r2,0(%r3) /* store tp->tv_sec */
st %r1,4(%r3) /* store tp->tv_nsec */
lhi %r2,0
ahi %r15,16
br %r14
/* CLOCK_MONOTONIC_COARSE */
@ -96,8 +98,8 @@ __kernel_clock_gettime:
11: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
tml %r4,0x0001 /* pending update ? loop */
jnz 11b
stcke 24(%r15) /* Store TOD clock */
lm %r0,%r1,25(%r15)
stcke 0(%r15) /* Store TOD clock */
lm %r0,%r1,1(%r15)
s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,12f
@ -132,11 +134,13 @@ __kernel_clock_gettime:
17: st %r2,0(%r3) /* store tp->tv_sec */
st %r1,4(%r3) /* store tp->tv_nsec */
lhi %r2,0
ahi %r15,16
br %r14
/* Fallback to system call */
19: lhi %r1,__NR_clock_gettime
svc 0
ahi %r15,16
br %r14
20: .long 1000000000

View file

@ -19,6 +19,7 @@
.type __kernel_gettimeofday,@function
__kernel_gettimeofday:
.cfi_startproc
ahi %r15,-16
basr %r5,0
0: al %r5,13f-0b(%r5) /* get &_vdso_data */
1: ltr %r3,%r3 /* check if tz is NULL */
@ -29,30 +30,30 @@ __kernel_gettimeofday:
l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
tml %r4,0x0001 /* pending update ? loop */
jnz 1b
stcke 24(%r15) /* Store TOD clock */
lm %r0,%r1,25(%r15)
stcke 0(%r15) /* Store TOD clock */
lm %r0,%r1,1(%r15)
s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,3f
ahi %r0,-1
3: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
st %r0,24(%r15)
st %r0,0(%r15)
l %r0,__VDSO_TK_MULT(%r5)
ltr %r1,%r1
mr %r0,%r0
jnm 4f
a %r0,__VDSO_TK_MULT(%r5)
4: al %r0,24(%r15)
4: al %r0,0(%r15)
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
al %r1,__VDSO_XTIME_NSEC+4(%r5)
brc 12,5f
ahi %r0,1
5: mvc 24(4,%r15),__VDSO_XTIME_SEC+4(%r5)
5: mvc 0(4,%r15),__VDSO_XTIME_SEC+4(%r5)
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
jne 1b
l %r4,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
srdl %r0,0(%r4) /* >> tk->shift */
l %r4,24(%r15) /* get tv_sec from stack */
l %r4,0(%r15) /* get tv_sec from stack */
basr %r5,0
6: ltr %r0,%r0
jnz 7f
@ -71,6 +72,7 @@ __kernel_gettimeofday:
9: srl %r0,6
st %r0,4(%r2) /* store tv->tv_usec */
10: slr %r2,%r2
ahi %r15,16
br %r14
11: .long 1000000000
12: .long 274877907

View file

@ -19,6 +19,7 @@
.type __kernel_clock_gettime,@function
__kernel_clock_gettime:
.cfi_startproc
aghi %r15,-16
larl %r5,_vdso_data
cghi %r2,__CLOCK_REALTIME_COARSE
je 4f
@ -37,10 +38,10 @@ __kernel_clock_gettime:
0: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */
tmll %r4,0x0001 /* pending update ? loop */
jnz 0b
stcke 48(%r15) /* Store TOD clock */
stcke 0(%r15) /* Store TOD clock */
lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
lg %r0,__VDSO_WTOM_SEC(%r5)
lg %r1,49(%r15)
lg %r1,1(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
alg %r1,__VDSO_WTOM_NSEC(%r5)
@ -56,6 +57,7 @@ __kernel_clock_gettime:
2: stg %r0,0(%r3) /* store tp->tv_sec */
stg %r1,8(%r3) /* store tp->tv_nsec */
lghi %r2,0
aghi %r15,16
br %r14
/* CLOCK_MONOTONIC_COARSE */
@ -82,9 +84,9 @@ __kernel_clock_gettime:
5: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */
tmll %r4,0x0001 /* pending update ? loop */
jnz 5b
stcke 48(%r15) /* Store TOD clock */
stcke 0(%r15) /* Store TOD clock */
lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
lg %r1,49(%r15)
lg %r1,1(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
@ -101,6 +103,7 @@ __kernel_clock_gettime:
7: stg %r0,0(%r3) /* store tp->tv_sec */
stg %r1,8(%r3) /* store tp->tv_nsec */
lghi %r2,0
aghi %r15,16
br %r14
/* CLOCK_THREAD_CPUTIME_ID for this thread */
@ -134,11 +137,13 @@ __kernel_clock_gettime:
slgr %r4,%r0 /* r4 = tv_nsec */
stg %r4,8(%r3)
lghi %r2,0
aghi %r15,16
br %r14
/* Fallback to system call */
12: lghi %r1,__NR_clock_gettime
svc 0
aghi %r15,16
br %r14
13: .quad 1000000000

View file

@ -19,6 +19,7 @@
.type __kernel_gettimeofday,@function
__kernel_gettimeofday:
.cfi_startproc
aghi %r15,-16
larl %r5,_vdso_data
0: ltgr %r3,%r3 /* check if tz is NULL */
je 1f
@ -28,8 +29,8 @@ __kernel_gettimeofday:
lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */
tmll %r4,0x0001 /* pending update ? loop */
jnz 0b
stcke 48(%r15) /* Store TOD clock */
lg %r1,49(%r15)
stcke 0(%r15) /* Store TOD clock */
lg %r1,1(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
@ -50,6 +51,7 @@ __kernel_gettimeofday:
srlg %r0,%r0,6
stg %r0,8(%r2) /* store tv->tv_usec */
4: lghi %r2,0
aghi %r15,16
br %r14
5: .quad 1000000000
.long 274877907