41
41
* program that will verify everything is correctly honored after an exec.
42
42
*/
43
43
44
- #include <stdlib.h>
45
- #include <unistd.h>
46
- #include <stdbool.h>
47
- #include <err.h>
48
- #include <sys/types.h>
44
+ #include <sys/param.h>
45
+ #include <sys/sysctl.h>
49
46
#include <sys/stat.h>
50
- #include <fcntl.h>
51
- #include <sys/sysmacros.h>
52
- #include <sys/fork.h>
53
- #include <wait.h>
47
+ #include <sys/wait.h>
48
+
49
+ #include <netinet/in.h>
50
+ #include <sys/socket.h>
51
+
52
+ #include <err.h>
54
53
#include <errno.h>
55
- #include <string .h>
54
+ #include <fcntl .h>
56
55
#include <limits.h>
57
- #include <libgen.h>
58
- #include <sys/socket.h>
56
+ #include <signal.h>
57
+ #include <stdbool.h>
58
+ #include <stdint.h>
59
+ #include <stdio.h>
60
+ #include <stdlib.h>
61
+ #include <string.h>
62
+ #include <unistd.h>
63
+
64
+ #define strerrorname_np (e ) (sys_errlist[e])
65
+
66
+ #ifndef FORK_NOSIGCHLD
67
+ #define FORK_NOSIGCHLD 0x01
68
+ #endif
69
+
70
+ #ifndef FORK_WAITPID
71
+ #define FORK_WAITPID 0x02
72
+ #endif
73
+
74
+ /*
75
+ * Simulate Solaris' forkx() with POSIX fork()
76
+ */
77
+ static pid_t
78
+ forkx (int flags )
79
+ {
80
+ struct sigaction oldact , ign ;
81
+ pid_t pid ;
82
+
83
+ if ((flags & ~(FORK_NOSIGCHLD | FORK_WAITPID )) != 0 ) {
84
+ errno = EINVAL ;
85
+ return (-1 );
86
+ }
87
+
88
+ memset (& ign , 0 , sizeof (ign ));
89
+ if (flags & FORK_NOSIGCHLD )
90
+ ign .sa_handler = SIG_IGN ;
91
+ sigemptyset (& ign .sa_mask );
92
+
93
+ sigaction (SIGCHLD , NULL , & oldact );
94
+ sigaction (SIGCHLD , & ign , NULL );
95
+
96
+ pid = fork ();
97
+
98
+ sigaction (SIGCHLD , & oldact , NULL );
99
+
100
+ return pid ;
101
+ }
59
102
60
103
/*
61
104
* Verification program name.
@@ -89,8 +132,8 @@ typedef struct clo_rtdata {
89
132
} clo_rtdata_t ;
90
133
91
134
static clo_rtdata_t * oclo_rtdata ;
92
- size_t oclo_rtdata_nents = 0 ;
93
- size_t oclo_rtdata_next = 0 ;
135
+ static size_t oclo_rtdata_nents = 0 ;
136
+ static size_t oclo_rtdata_next = 0 ;
94
137
static int oclo_nextfd = STDERR_FILENO + 1 ;
95
138
96
139
static bool
@@ -261,14 +304,24 @@ oclo_fdup_common(const clo_create_t *c, int targ_flags, int cmd)
261
304
case F_DUPFD_CLOFORK :
262
305
dup = fcntl (fd , cmd , fd );
263
306
break ;
307
+ #ifdef F_DUP2FD
264
308
case F_DUP2FD :
309
+ #endif
310
+ #ifdef F_DUP2FD_CLOEXEC
265
311
case F_DUP2FD_CLOEXEC :
312
+ #endif
313
+ #ifdef F_DUP2FD_CLOFORK
266
314
case F_DUP2FD_CLOFORK :
315
+ #endif
316
+ #if defined(F_DUP2FD ) || defined(F_DUP2FD_CLOEXEC ) || defined(F_DUP2FD_CLOFORK )
267
317
dup = fcntl (fd , cmd , fd + 1 );
268
318
break ;
319
+ #endif
320
+ #ifdef F_DUP3FD
269
321
case F_DUP3FD :
270
- dup = fcntl (fd , cmd , fd + 1 , targ_flags );
322
+ dup = fcntl (fd , cmd | ( targ_flags << F_DUP3FD_SHIFT ) , fd + 1 );
271
323
break ;
324
+ #endif
272
325
default :
273
326
errx (EXIT_FAILURE , "TEST FAILURE: %s: internal error: "
274
327
"unexpected fcntl cmd: 0x%x" , c -> clo_desc , cmd );
@@ -300,24 +353,31 @@ oclo_fdupfd_exec(const clo_create_t *c)
300
353
oclo_fdup_common (c , FD_CLOEXEC , F_DUPFD_CLOEXEC );
301
354
}
302
355
356
+ #ifdef F_DUP2FD
303
357
static void
304
358
oclo_fdup2fd (const clo_create_t * c )
305
359
{
306
360
oclo_fdup_common (c , 0 , F_DUP2FD );
307
361
}
362
+ #endif
308
363
364
+ #ifdef F_DUP2FD_CLOFORK
309
365
static void
310
366
oclo_fdup2fd_fork (const clo_create_t * c )
311
367
{
312
368
oclo_fdup_common (c , FD_CLOFORK , F_DUP2FD_CLOFORK );
313
369
}
370
+ #endif
314
371
372
+ #ifdef F_DUP2FD_CLOEXEC
315
373
static void
316
374
oclo_fdup2fd_exec (const clo_create_t * c )
317
375
{
318
376
oclo_fdup_common (c , FD_CLOEXEC , F_DUP2FD_CLOEXEC );
319
377
}
378
+ #endif
320
379
380
+ #ifdef F_DUP3FD
321
381
static void
322
382
oclo_fdup3fd_none (const clo_create_t * c )
323
383
{
@@ -341,6 +401,7 @@ oclo_fdup3fd_both(const clo_create_t *c)
341
401
{
342
402
oclo_fdup_common (c , FD_CLOEXEC | FD_CLOFORK , F_DUP3FD );
343
403
}
404
+ #endif
344
405
345
406
static void
346
407
oclo_dup_common (const clo_create_t * c , int targ_flags , bool v3 )
@@ -598,9 +659,14 @@ oclo_rights_common(const clo_create_t *c, int targ_flags)
598
659
"data: expected 0x7777, found 0x%x" , c -> clo_desc , data );
599
660
}
600
661
601
- if (msg .msg_controllen < CMSG_SPACE (sizeof (int ))) {
662
+ /*
663
+ * XXX
664
+ * We have to add 4 here to avoid this error message:
665
+ * found insufficient message control length: expected at least 0x18, found 0x14
666
+ */
667
+ if (msg .msg_controllen + 4 < CMSG_SPACE (sizeof (int ))) {
602
668
errx (EXIT_FAILURE , "TEST FAILED: %s: found insufficient "
603
- "message control length: expected at least 0x%x , found "
669
+ "message control length: expected at least 0x%lx , found "
604
670
"0x%x" , c -> clo_desc , CMSG_SPACE (sizeof (int )),
605
671
msg .msg_controllen );
606
672
}
@@ -775,6 +841,7 @@ static const clo_create_t oclo_create[] = { {
775
841
.clo_flags = FD_CLOEXEC | FD_CLOFORK ,
776
842
.clo_func = oclo_fdupfd_exec
777
843
}, {
844
+ #ifdef F_DUP2FD
778
845
.clo_desc = "fcntl(F_DUP2FD) none->none" ,
779
846
.clo_flags = 0 ,
780
847
.clo_func = oclo_fdup2fd
@@ -807,6 +874,8 @@ static const clo_create_t oclo_create[] = { {
807
874
.clo_flags = FD_CLOEXEC | FD_CLOFORK ,
808
875
.clo_func = oclo_fdup2fd_fork
809
876
}, {
877
+ #endif
878
+ #ifdef F_DUP2FD_CLOEXEC
810
879
.clo_desc = "fcntl(F_DUP2FD_CLOEXEC) none" ,
811
880
.clo_flags = 0 ,
812
881
.clo_func = oclo_fdup2fd_exec
@@ -823,6 +892,8 @@ static const clo_create_t oclo_create[] = { {
823
892
.clo_flags = FD_CLOEXEC | FD_CLOFORK ,
824
893
.clo_func = oclo_fdup2fd_exec
825
894
}, {
895
+ #endif
896
+ #ifdef F_DUP3FD
826
897
.clo_desc = "fcntl(F_DUP3FD) none->none" ,
827
898
.clo_flags = 0 ,
828
899
.clo_func = oclo_fdup3fd_none
@@ -888,6 +959,7 @@ static const clo_create_t oclo_create[] = { {
888
959
.clo_flags = FD_CLOEXEC | FD_CLOFORK ,
889
960
.clo_func = oclo_fdup3fd_fork
890
961
}, {
962
+ #endif
891
963
.clo_desc = "dup2() none->none" ,
892
964
.clo_flags = 0 ,
893
965
.clo_func = oclo_dup2
@@ -1204,24 +1276,19 @@ oclo_child_reopen(void)
1204
1276
static void
1205
1277
oclo_exec (void )
1206
1278
{
1207
- ssize_t ret ;
1208
1279
char dir [PATH_MAX ], file [PATH_MAX ];
1209
1280
char * * argv ;
1210
1281
1211
- ret = readlink ("/proc/self/path/a.out" , dir , sizeof (dir ));
1212
- if (ret < 0 ) {
1213
- err (EXIT_FAILURE , "TEST FAILED: failed to read our a.out path "
1214
- "from /proc" );
1215
- } else if (ret == 0 ) {
1216
- errx (EXIT_FAILURE , "TEST FAILED: reading /proc/self/path/a.out "
1217
- "returned 0 bytes" );
1218
- } else if (ret == sizeof (dir )) {
1219
- errx (EXIT_FAILURE , "TEST FAILED: Using /proc/self/path/a.out "
1220
- "requires truncation" );
1221
- }
1282
+ /*
1283
+ * XXX
1284
+ * There's no way to get the full pathname to an executable in OpenBSD
1285
+ * so use the cwd here.
1286
+ */
1287
+ if (getcwd (dir , sizeof (dir )) == NULL )
1288
+ err (1 , "getcwd" );
1222
1289
1223
- if (snprintf (file , sizeof (file ), "%s/%s" , dirname ( dir ) , OCLO_VERIFY ) >=
1224
- sizeof (file )) {
1290
+ if (snprintf (file , sizeof (file ), "%s/%s" , dir , OCLO_VERIFY ) >=
1291
+ ( int ) sizeof (file )) {
1225
1292
errx (EXIT_FAILURE , "TEST FAILED: cannot assemble exec path "
1226
1293
"name: internal buffer overflow" );
1227
1294
}
@@ -1262,7 +1329,7 @@ main(void)
1262
1329
* Treat failure during this set up phase as a hard failure. There's no
1263
1330
* reason to continue if we can't successfully create the FDs we expect.
1264
1331
*/
1265
- for (size_t i = 0 ; i < ARRAY_SIZE (oclo_create ); i ++ ) {
1332
+ for (long unsigned int i = 0 ; i < nitems (oclo_create ); i ++ ) {
1266
1333
oclo_create [i ].clo_func (& oclo_create [i ]);
1267
1334
}
1268
1335
0 commit comments