Skip to content

Commit

Permalink
s390/vdso: fix stack corruption
Browse files Browse the repository at this point in the history
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 070b7be "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 <[email protected]>
Signed-off-by: Martin Schwidefsky <[email protected]>
  • Loading branch information
heicarst authored and Martin Schwidefsky committed Oct 27, 2014
1 parent 1f759bb commit 9b2efe0
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 16 deletions.
12 changes: 8 additions & 4 deletions arch/s390/kernel/vdso32/clock_gettime.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 */
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
14 changes: 8 additions & 6 deletions arch/s390/kernel/vdso32/gettimeofday.S
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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
Expand All @@ -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
Expand Down
13 changes: 9 additions & 4 deletions arch/s390/kernel/vdso64/clock_gettime.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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 */
Expand All @@ -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 */
Expand All @@ -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 */
Expand Down Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions arch/s390/kernel/vdso64/gettimeofday.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 */
Expand All @@ -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
Expand Down

0 comments on commit 9b2efe0

Please sign in to comment.