21
21
#include <sys/uio.h>
22
22
23
23
#include "helpers.h"
24
+ #include "../kselftest.h"
24
25
25
26
#ifdef __x86_64__
26
27
# define VSYS (x ) (x)
39
40
/* max length of lines in /proc/self/maps - anything longer is skipped here */
40
41
#define MAPS_LINE_LEN 128
41
42
42
- static void sethandler (int sig , void (* handler )(int , siginfo_t * , void * ),
43
- int flags )
44
- {
45
- struct sigaction sa ;
46
- memset (& sa , 0 , sizeof (sa ));
47
- sa .sa_sigaction = handler ;
48
- sa .sa_flags = SA_SIGINFO | flags ;
49
- sigemptyset (& sa .sa_mask );
50
- if (sigaction (sig , & sa , 0 ))
51
- err (1 , "sigaction" );
52
- }
53
-
54
43
/* vsyscalls and vDSO */
55
44
bool vsyscall_map_r = false, vsyscall_map_x = false;
56
45
@@ -96,64 +85,6 @@ static void init_vdso(void)
96
85
printf ("[WARN]\tfailed to find getcpu in vDSO\n" );
97
86
}
98
87
99
- static int init_vsys (void )
100
- {
101
- #ifdef __x86_64__
102
- int nerrs = 0 ;
103
- FILE * maps ;
104
- char line [MAPS_LINE_LEN ];
105
- bool found = false;
106
-
107
- maps = fopen ("/proc/self/maps" , "r" );
108
- if (!maps ) {
109
- printf ("[WARN]\tCould not open /proc/self/maps -- assuming vsyscall is r-x\n" );
110
- vsyscall_map_r = true;
111
- return 0 ;
112
- }
113
-
114
- while (fgets (line , MAPS_LINE_LEN , maps )) {
115
- char r , x ;
116
- void * start , * end ;
117
- char name [MAPS_LINE_LEN ];
118
-
119
- /* sscanf() is safe here as strlen(name) >= strlen(line) */
120
- if (sscanf (line , "%p-%p %c-%cp %*x %*x:%*x %*u %s" ,
121
- & start , & end , & r , & x , name ) != 5 )
122
- continue ;
123
-
124
- if (strcmp (name , "[vsyscall]" ))
125
- continue ;
126
-
127
- printf ("\tvsyscall map: %s" , line );
128
-
129
- if (start != (void * )0xffffffffff600000 ||
130
- end != (void * )0xffffffffff601000 ) {
131
- printf ("[FAIL]\taddress range is nonsense\n" );
132
- nerrs ++ ;
133
- }
134
-
135
- printf ("\tvsyscall permissions are %c-%c\n" , r , x );
136
- vsyscall_map_r = (r == 'r' );
137
- vsyscall_map_x = (x == 'x' );
138
-
139
- found = true;
140
- break ;
141
- }
142
-
143
- fclose (maps );
144
-
145
- if (!found ) {
146
- printf ("\tno vsyscall map in /proc/self/maps\n" );
147
- vsyscall_map_r = false;
148
- vsyscall_map_x = false;
149
- }
150
-
151
- return nerrs ;
152
- #else
153
- return 0 ;
154
- #endif
155
- }
156
-
157
88
/* syscalls */
158
89
static inline long sys_gtod (struct timeval * tv , struct timezone * tz )
159
90
{
@@ -176,17 +107,6 @@ static inline long sys_getcpu(unsigned * cpu, unsigned * node,
176
107
return syscall (SYS_getcpu , cpu , node , cache );
177
108
}
178
109
179
- static jmp_buf jmpbuf ;
180
- static volatile unsigned long segv_err ;
181
-
182
- static void sigsegv (int sig , siginfo_t * info , void * ctx_void )
183
- {
184
- ucontext_t * ctx = (ucontext_t * )ctx_void ;
185
-
186
- segv_err = ctx -> uc_mcontext .gregs [REG_ERR ];
187
- siglongjmp (jmpbuf , 1 );
188
- }
189
-
190
110
static double tv_diff (const struct timeval * a , const struct timeval * b )
191
111
{
192
112
return (double )(a -> tv_sec - b -> tv_sec ) +
@@ -396,9 +316,33 @@ static int test_getcpu(int cpu)
396
316
return nerrs ;
397
317
}
398
318
319
+ #ifdef __x86_64__
320
+
321
+ static jmp_buf jmpbuf ;
322
+ static volatile unsigned long segv_err ;
323
+
324
+ static void sethandler (int sig , void (* handler )(int , siginfo_t * , void * ),
325
+ int flags )
326
+ {
327
+ struct sigaction sa ;
328
+ memset (& sa , 0 , sizeof (sa ));
329
+ sa .sa_sigaction = handler ;
330
+ sa .sa_flags = SA_SIGINFO | flags ;
331
+ sigemptyset (& sa .sa_mask );
332
+ if (sigaction (sig , & sa , 0 ))
333
+ err (1 , "sigaction" );
334
+ }
335
+
336
+ static void sigsegv (int sig , siginfo_t * info , void * ctx_void )
337
+ {
338
+ ucontext_t * ctx = (ucontext_t * )ctx_void ;
339
+
340
+ segv_err = ctx -> uc_mcontext .gregs [REG_ERR ];
341
+ siglongjmp (jmpbuf , 1 );
342
+ }
343
+
399
344
static int test_vsys_r (void )
400
345
{
401
- #ifdef __x86_64__
402
346
printf ("[RUN]\tChecking read access to the vsyscall page\n" );
403
347
bool can_read ;
404
348
if (sigsetjmp (jmpbuf , 1 ) == 0 ) {
@@ -420,14 +364,12 @@ static int test_vsys_r(void)
420
364
printf ("[OK]\tWe do not have read access: #PF(0x%lx)\n" ,
421
365
segv_err );
422
366
}
423
- #endif
424
367
425
368
return 0 ;
426
369
}
427
370
428
371
static int test_vsys_x (void )
429
372
{
430
- #ifdef __x86_64__
431
373
if (vsyscall_map_x ) {
432
374
/* We already tested this adequately. */
433
375
return 0 ;
@@ -454,8 +396,6 @@ static int test_vsys_x(void)
454
396
segv_err );
455
397
return 1 ;
456
398
}
457
- #endif
458
-
459
399
return 0 ;
460
400
}
461
401
@@ -472,7 +412,6 @@ static int test_vsys_x(void)
472
412
*/
473
413
static int test_process_vm_readv (void )
474
414
{
475
- #ifdef __x86_64__
476
415
char buf [4096 ];
477
416
struct iovec local , remote ;
478
417
int ret ;
@@ -504,12 +443,63 @@ static int test_process_vm_readv(void)
504
443
printf ("[FAIL]\tprocess_rm_readv() succeeded, but it should have failed in this configuration\n" );
505
444
return 1 ;
506
445
}
507
- #endif
508
-
509
446
return 0 ;
510
447
}
511
448
512
- #ifdef __x86_64__
449
+ static int init_vsys (void )
450
+ {
451
+ int nerrs = 0 ;
452
+ FILE * maps ;
453
+ char line [MAPS_LINE_LEN ];
454
+ bool found = false;
455
+
456
+ maps = fopen ("/proc/self/maps" , "r" );
457
+ if (!maps ) {
458
+ printf ("[WARN]\tCould not open /proc/self/maps -- assuming vsyscall is r-x\n" );
459
+ vsyscall_map_r = true;
460
+ return 0 ;
461
+ }
462
+
463
+ while (fgets (line , MAPS_LINE_LEN , maps )) {
464
+ char r , x ;
465
+ void * start , * end ;
466
+ char name [MAPS_LINE_LEN ];
467
+
468
+ /* sscanf() is safe here as strlen(name) >= strlen(line) */
469
+ if (sscanf (line , "%p-%p %c-%cp %*x %*x:%*x %*u %s" ,
470
+ & start , & end , & r , & x , name ) != 5 )
471
+ continue ;
472
+
473
+ if (strcmp (name , "[vsyscall]" ))
474
+ continue ;
475
+
476
+ printf ("\tvsyscall map: %s" , line );
477
+
478
+ if (start != (void * )0xffffffffff600000 ||
479
+ end != (void * )0xffffffffff601000 ) {
480
+ printf ("[FAIL]\taddress range is nonsense\n" );
481
+ nerrs ++ ;
482
+ }
483
+
484
+ printf ("\tvsyscall permissions are %c-%c\n" , r , x );
485
+ vsyscall_map_r = (r == 'r' );
486
+ vsyscall_map_x = (x == 'x' );
487
+
488
+ found = true;
489
+ break ;
490
+ }
491
+
492
+ fclose (maps );
493
+
494
+ if (!found ) {
495
+ printf ("\tno vsyscall map in /proc/self/maps\n" );
496
+ vsyscall_map_r = false;
497
+ vsyscall_map_x = false;
498
+ }
499
+
500
+ return nerrs ;
501
+ }
502
+
513
503
static volatile sig_atomic_t num_vsyscall_traps ;
514
504
515
505
static void sigtrap (int sig , siginfo_t * info , void * ctx_void )
@@ -559,20 +549,20 @@ int main(int argc, char **argv)
559
549
int nerrs = 0 ;
560
550
561
551
init_vdso ();
552
+ #ifdef __x86_64__
562
553
nerrs += init_vsys ();
554
+ #endif
563
555
564
556
nerrs += test_gtod ();
565
557
nerrs += test_time ();
566
558
nerrs += test_getcpu (0 );
567
559
nerrs += test_getcpu (1 );
568
560
561
+ #ifdef __x86_64__
569
562
sethandler (SIGSEGV , sigsegv , 0 );
570
563
nerrs += test_vsys_r ();
571
564
nerrs += test_vsys_x ();
572
-
573
565
nerrs += test_process_vm_readv ();
574
-
575
- #ifdef __x86_64__
576
566
nerrs += test_emulation ();
577
567
#endif
578
568
0 commit comments