Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b2efe03 authored by Heiko Carstens's avatar Heiko Carstens Committed by Martin Schwidefsky
Browse files

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 070b7be6 "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: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 1f759bb3
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -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
+8 −6
Original line number Diff line number Diff line
@@ -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
+9 −4
Original line number Diff line number Diff line
@@ -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
+4 −2
Original line number Diff line number Diff line
@@ -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