diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2014-10-27 03:28:08 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-10-27 08:27:02 -0400 |
commit | 9b2efe035eafb1a29ff3dfe21ed0e755aac09130 (patch) | |
tree | 37f0a0c357aaf7305ca9acf2850c78da576c4f93 /arch | |
parent | 1f759bb3a2a0d75ceeeec729b1c66a7f443631ba (diff) |
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 070b7be633dc "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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/kernel/vdso32/clock_gettime.S | 12 | ||||
-rw-r--r-- | arch/s390/kernel/vdso32/gettimeofday.S | 14 | ||||
-rw-r--r-- | arch/s390/kernel/vdso64/clock_gettime.S | 13 | ||||
-rw-r--r-- | arch/s390/kernel/vdso64/gettimeofday.S | 6 |
4 files changed, 29 insertions, 16 deletions
diff --git a/arch/s390/kernel/vdso32/clock_gettime.S b/arch/s390/kernel/vdso32/clock_gettime.S index 48c2206a3956..5eec9afbb5b5 100644 --- a/arch/s390/kernel/vdso32/clock_gettime.S +++ b/arch/s390/kernel/vdso32/clock_gettime.S | |||
@@ -19,6 +19,7 @@ | |||
19 | .type __kernel_clock_gettime,@function | 19 | .type __kernel_clock_gettime,@function |
20 | __kernel_clock_gettime: | 20 | __kernel_clock_gettime: |
21 | .cfi_startproc | 21 | .cfi_startproc |
22 | ahi %r15,-16 | ||
22 | basr %r5,0 | 23 | basr %r5,0 |
23 | 0: al %r5,21f-0b(%r5) /* get &_vdso_data */ | 24 | 0: al %r5,21f-0b(%r5) /* get &_vdso_data */ |
24 | chi %r2,__CLOCK_REALTIME_COARSE | 25 | chi %r2,__CLOCK_REALTIME_COARSE |
@@ -34,8 +35,8 @@ __kernel_clock_gettime: | |||
34 | 1: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ | 35 | 1: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ |
35 | tml %r4,0x0001 /* pending update ? loop */ | 36 | tml %r4,0x0001 /* pending update ? loop */ |
36 | jnz 1b | 37 | jnz 1b |
37 | stcke 24(%r15) /* Store TOD clock */ | 38 | stcke 0(%r15) /* Store TOD clock */ |
38 | lm %r0,%r1,25(%r15) | 39 | lm %r0,%r1,1(%r15) |
39 | s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ | 40 | s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ |
40 | sl %r1,__VDSO_XTIME_STAMP+4(%r5) | 41 | sl %r1,__VDSO_XTIME_STAMP+4(%r5) |
41 | brc 3,2f | 42 | brc 3,2f |
@@ -70,6 +71,7 @@ __kernel_clock_gettime: | |||
70 | 8: st %r2,0(%r3) /* store tp->tv_sec */ | 71 | 8: st %r2,0(%r3) /* store tp->tv_sec */ |
71 | st %r1,4(%r3) /* store tp->tv_nsec */ | 72 | st %r1,4(%r3) /* store tp->tv_nsec */ |
72 | lhi %r2,0 | 73 | lhi %r2,0 |
74 | ahi %r15,16 | ||
73 | br %r14 | 75 | br %r14 |
74 | 76 | ||
75 | /* CLOCK_MONOTONIC_COARSE */ | 77 | /* CLOCK_MONOTONIC_COARSE */ |
@@ -96,8 +98,8 @@ __kernel_clock_gettime: | |||
96 | 11: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ | 98 | 11: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ |
97 | tml %r4,0x0001 /* pending update ? loop */ | 99 | tml %r4,0x0001 /* pending update ? loop */ |
98 | jnz 11b | 100 | jnz 11b |
99 | stcke 24(%r15) /* Store TOD clock */ | 101 | stcke 0(%r15) /* Store TOD clock */ |
100 | lm %r0,%r1,25(%r15) | 102 | lm %r0,%r1,1(%r15) |
101 | s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ | 103 | s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ |
102 | sl %r1,__VDSO_XTIME_STAMP+4(%r5) | 104 | sl %r1,__VDSO_XTIME_STAMP+4(%r5) |
103 | brc 3,12f | 105 | brc 3,12f |
@@ -132,11 +134,13 @@ __kernel_clock_gettime: | |||
132 | 17: st %r2,0(%r3) /* store tp->tv_sec */ | 134 | 17: st %r2,0(%r3) /* store tp->tv_sec */ |
133 | st %r1,4(%r3) /* store tp->tv_nsec */ | 135 | st %r1,4(%r3) /* store tp->tv_nsec */ |
134 | lhi %r2,0 | 136 | lhi %r2,0 |
137 | ahi %r15,16 | ||
135 | br %r14 | 138 | br %r14 |
136 | 139 | ||
137 | /* Fallback to system call */ | 140 | /* Fallback to system call */ |
138 | 19: lhi %r1,__NR_clock_gettime | 141 | 19: lhi %r1,__NR_clock_gettime |
139 | svc 0 | 142 | svc 0 |
143 | ahi %r15,16 | ||
140 | br %r14 | 144 | br %r14 |
141 | 145 | ||
142 | 20: .long 1000000000 | 146 | 20: .long 1000000000 |
diff --git a/arch/s390/kernel/vdso32/gettimeofday.S b/arch/s390/kernel/vdso32/gettimeofday.S index 60def5f562db..719de6186b20 100644 --- a/arch/s390/kernel/vdso32/gettimeofday.S +++ b/arch/s390/kernel/vdso32/gettimeofday.S | |||
@@ -19,6 +19,7 @@ | |||
19 | .type __kernel_gettimeofday,@function | 19 | .type __kernel_gettimeofday,@function |
20 | __kernel_gettimeofday: | 20 | __kernel_gettimeofday: |
21 | .cfi_startproc | 21 | .cfi_startproc |
22 | ahi %r15,-16 | ||
22 | basr %r5,0 | 23 | basr %r5,0 |
23 | 0: al %r5,13f-0b(%r5) /* get &_vdso_data */ | 24 | 0: al %r5,13f-0b(%r5) /* get &_vdso_data */ |
24 | 1: ltr %r3,%r3 /* check if tz is NULL */ | 25 | 1: ltr %r3,%r3 /* check if tz is NULL */ |
@@ -29,30 +30,30 @@ __kernel_gettimeofday: | |||
29 | l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ | 30 | l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ |
30 | tml %r4,0x0001 /* pending update ? loop */ | 31 | tml %r4,0x0001 /* pending update ? loop */ |
31 | jnz 1b | 32 | jnz 1b |
32 | stcke 24(%r15) /* Store TOD clock */ | 33 | stcke 0(%r15) /* Store TOD clock */ |
33 | lm %r0,%r1,25(%r15) | 34 | lm %r0,%r1,1(%r15) |
34 | s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ | 35 | s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ |
35 | sl %r1,__VDSO_XTIME_STAMP+4(%r5) | 36 | sl %r1,__VDSO_XTIME_STAMP+4(%r5) |
36 | brc 3,3f | 37 | brc 3,3f |
37 | ahi %r0,-1 | 38 | ahi %r0,-1 |
38 | 3: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */ | 39 | 3: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */ |
39 | st %r0,24(%r15) | 40 | st %r0,0(%r15) |
40 | l %r0,__VDSO_TK_MULT(%r5) | 41 | l %r0,__VDSO_TK_MULT(%r5) |
41 | ltr %r1,%r1 | 42 | ltr %r1,%r1 |
42 | mr %r0,%r0 | 43 | mr %r0,%r0 |
43 | jnm 4f | 44 | jnm 4f |
44 | a %r0,__VDSO_TK_MULT(%r5) | 45 | a %r0,__VDSO_TK_MULT(%r5) |
45 | 4: al %r0,24(%r15) | 46 | 4: al %r0,0(%r15) |
46 | al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */ | 47 | al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */ |
47 | al %r1,__VDSO_XTIME_NSEC+4(%r5) | 48 | al %r1,__VDSO_XTIME_NSEC+4(%r5) |
48 | brc 12,5f | 49 | brc 12,5f |
49 | ahi %r0,1 | 50 | ahi %r0,1 |
50 | 5: mvc 24(4,%r15),__VDSO_XTIME_SEC+4(%r5) | 51 | 5: mvc 0(4,%r15),__VDSO_XTIME_SEC+4(%r5) |
51 | cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ | 52 | cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ |
52 | jne 1b | 53 | jne 1b |
53 | l %r4,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ | 54 | l %r4,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ |
54 | srdl %r0,0(%r4) /* >> tk->shift */ | 55 | srdl %r0,0(%r4) /* >> tk->shift */ |
55 | l %r4,24(%r15) /* get tv_sec from stack */ | 56 | l %r4,0(%r15) /* get tv_sec from stack */ |
56 | basr %r5,0 | 57 | basr %r5,0 |
57 | 6: ltr %r0,%r0 | 58 | 6: ltr %r0,%r0 |
58 | jnz 7f | 59 | jnz 7f |
@@ -71,6 +72,7 @@ __kernel_gettimeofday: | |||
71 | 9: srl %r0,6 | 72 | 9: srl %r0,6 |
72 | st %r0,4(%r2) /* store tv->tv_usec */ | 73 | st %r0,4(%r2) /* store tv->tv_usec */ |
73 | 10: slr %r2,%r2 | 74 | 10: slr %r2,%r2 |
75 | ahi %r15,16 | ||
74 | br %r14 | 76 | br %r14 |
75 | 11: .long 1000000000 | 77 | 11: .long 1000000000 |
76 | 12: .long 274877907 | 78 | 12: .long 274877907 |
diff --git a/arch/s390/kernel/vdso64/clock_gettime.S b/arch/s390/kernel/vdso64/clock_gettime.S index 9d9761f8e110..7699e735ae28 100644 --- a/arch/s390/kernel/vdso64/clock_gettime.S +++ b/arch/s390/kernel/vdso64/clock_gettime.S | |||
@@ -19,6 +19,7 @@ | |||
19 | .type __kernel_clock_gettime,@function | 19 | .type __kernel_clock_gettime,@function |
20 | __kernel_clock_gettime: | 20 | __kernel_clock_gettime: |
21 | .cfi_startproc | 21 | .cfi_startproc |
22 | aghi %r15,-16 | ||
22 | larl %r5,_vdso_data | 23 | larl %r5,_vdso_data |
23 | cghi %r2,__CLOCK_REALTIME_COARSE | 24 | cghi %r2,__CLOCK_REALTIME_COARSE |
24 | je 4f | 25 | je 4f |
@@ -37,10 +38,10 @@ __kernel_clock_gettime: | |||
37 | 0: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ | 38 | 0: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ |
38 | tmll %r4,0x0001 /* pending update ? loop */ | 39 | tmll %r4,0x0001 /* pending update ? loop */ |
39 | jnz 0b | 40 | jnz 0b |
40 | stcke 48(%r15) /* Store TOD clock */ | 41 | stcke 0(%r15) /* Store TOD clock */ |
41 | lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ | 42 | lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ |
42 | lg %r0,__VDSO_WTOM_SEC(%r5) | 43 | lg %r0,__VDSO_WTOM_SEC(%r5) |
43 | lg %r1,49(%r15) | 44 | lg %r1,1(%r15) |
44 | sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ | 45 | sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ |
45 | msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ | 46 | msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ |
46 | alg %r1,__VDSO_WTOM_NSEC(%r5) | 47 | alg %r1,__VDSO_WTOM_NSEC(%r5) |
@@ -56,6 +57,7 @@ __kernel_clock_gettime: | |||
56 | 2: stg %r0,0(%r3) /* store tp->tv_sec */ | 57 | 2: stg %r0,0(%r3) /* store tp->tv_sec */ |
57 | stg %r1,8(%r3) /* store tp->tv_nsec */ | 58 | stg %r1,8(%r3) /* store tp->tv_nsec */ |
58 | lghi %r2,0 | 59 | lghi %r2,0 |
60 | aghi %r15,16 | ||
59 | br %r14 | 61 | br %r14 |
60 | 62 | ||
61 | /* CLOCK_MONOTONIC_COARSE */ | 63 | /* CLOCK_MONOTONIC_COARSE */ |
@@ -82,9 +84,9 @@ __kernel_clock_gettime: | |||
82 | 5: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ | 84 | 5: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ |
83 | tmll %r4,0x0001 /* pending update ? loop */ | 85 | tmll %r4,0x0001 /* pending update ? loop */ |
84 | jnz 5b | 86 | jnz 5b |
85 | stcke 48(%r15) /* Store TOD clock */ | 87 | stcke 0(%r15) /* Store TOD clock */ |
86 | lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ | 88 | lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ |
87 | lg %r1,49(%r15) | 89 | lg %r1,1(%r15) |
88 | sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ | 90 | sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ |
89 | msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ | 91 | msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ |
90 | alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ | 92 | alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ |
@@ -101,6 +103,7 @@ __kernel_clock_gettime: | |||
101 | 7: stg %r0,0(%r3) /* store tp->tv_sec */ | 103 | 7: stg %r0,0(%r3) /* store tp->tv_sec */ |
102 | stg %r1,8(%r3) /* store tp->tv_nsec */ | 104 | stg %r1,8(%r3) /* store tp->tv_nsec */ |
103 | lghi %r2,0 | 105 | lghi %r2,0 |
106 | aghi %r15,16 | ||
104 | br %r14 | 107 | br %r14 |
105 | 108 | ||
106 | /* CLOCK_THREAD_CPUTIME_ID for this thread */ | 109 | /* CLOCK_THREAD_CPUTIME_ID for this thread */ |
@@ -134,11 +137,13 @@ __kernel_clock_gettime: | |||
134 | slgr %r4,%r0 /* r4 = tv_nsec */ | 137 | slgr %r4,%r0 /* r4 = tv_nsec */ |
135 | stg %r4,8(%r3) | 138 | stg %r4,8(%r3) |
136 | lghi %r2,0 | 139 | lghi %r2,0 |
140 | aghi %r15,16 | ||
137 | br %r14 | 141 | br %r14 |
138 | 142 | ||
139 | /* Fallback to system call */ | 143 | /* Fallback to system call */ |
140 | 12: lghi %r1,__NR_clock_gettime | 144 | 12: lghi %r1,__NR_clock_gettime |
141 | svc 0 | 145 | svc 0 |
146 | aghi %r15,16 | ||
142 | br %r14 | 147 | br %r14 |
143 | 148 | ||
144 | 13: .quad 1000000000 | 149 | 13: .quad 1000000000 |
diff --git a/arch/s390/kernel/vdso64/gettimeofday.S b/arch/s390/kernel/vdso64/gettimeofday.S index 7a344995a97f..6ce46707663c 100644 --- a/arch/s390/kernel/vdso64/gettimeofday.S +++ b/arch/s390/kernel/vdso64/gettimeofday.S | |||
@@ -19,6 +19,7 @@ | |||
19 | .type __kernel_gettimeofday,@function | 19 | .type __kernel_gettimeofday,@function |
20 | __kernel_gettimeofday: | 20 | __kernel_gettimeofday: |
21 | .cfi_startproc | 21 | .cfi_startproc |
22 | aghi %r15,-16 | ||
22 | larl %r5,_vdso_data | 23 | larl %r5,_vdso_data |
23 | 0: ltgr %r3,%r3 /* check if tz is NULL */ | 24 | 0: ltgr %r3,%r3 /* check if tz is NULL */ |
24 | je 1f | 25 | je 1f |
@@ -28,8 +29,8 @@ __kernel_gettimeofday: | |||
28 | lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ | 29 | lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ |
29 | tmll %r4,0x0001 /* pending update ? loop */ | 30 | tmll %r4,0x0001 /* pending update ? loop */ |
30 | jnz 0b | 31 | jnz 0b |
31 | stcke 48(%r15) /* Store TOD clock */ | 32 | stcke 0(%r15) /* Store TOD clock */ |
32 | lg %r1,49(%r15) | 33 | lg %r1,1(%r15) |
33 | sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ | 34 | sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ |
34 | msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ | 35 | msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ |
35 | alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ | 36 | alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ |
@@ -50,6 +51,7 @@ __kernel_gettimeofday: | |||
50 | srlg %r0,%r0,6 | 51 | srlg %r0,%r0,6 |
51 | stg %r0,8(%r2) /* store tv->tv_usec */ | 52 | stg %r0,8(%r2) /* store tv->tv_usec */ |
52 | 4: lghi %r2,0 | 53 | 4: lghi %r2,0 |
54 | aghi %r15,16 | ||
53 | br %r14 | 55 | br %r14 |
54 | 5: .quad 1000000000 | 56 | 5: .quad 1000000000 |
55 | .long 274877907 | 57 | .long 274877907 |