master
c 1,322 lines 34 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 binfmt.c
8
9 Abstract:
10
11 This file contains tests for the binfmt file system.
12
13 --*/
14
15 #include "lxtcommon.h"
16 #include "unittests.h"
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <sys/syscall.h>
22 #include <sys/utsname.h>
23 #include <unistd.h>
24 #include <dirent.h>
25 #include <fcntl.h>
26 #include <pthread.h>
27
28 #define LXT_NAME "BinFmt"
29
30 #define BINFMT_MNT "/proc/sys/fs/binfmt_misc"
31 #define BINFMT_TEST_FILE "/data/test/lxt_binfmt_test"
32 #define BINFMT_TIMEOUT 60
33
34 #define BINFMT_DISABLE_STRING "0"
35 #define BINFMT_ENABLE_STRING "1"
36 #define BINFMT_REMOVE_STRING "-1"
37
38 #define BINFMT_REGISTER_NAME "Test"
39 #define BINFMT_INTERPRETER_SCRIPT "/data/test/lxt_binfmt_interpreter.sh"
40 #define BINFMT_REGISTER_SCRIPT_STRING ":" BINFMT_REGISTER_NAME ":M::\\xff\\xff\\xff\\xff::" BINFMT_INTERPRETER_SCRIPT ":"
41
42 #define BINFMT_INTERPRETER_SCRIPT_CONTENTS \
43 "#!/bin/bash\n" \
44 "# " BINFMT_INTERPRETER_SCRIPT " - the wrapper for WSL binfmt_misc testing\n" WSL_UNIT_TEST_BINARY " binfmt -a -i \"$@\""
45
46 #define BINFMT_INTERPRETER_BINARY "/data/test/lxt_binfmt_interpreter_binary"
47 #define BINFMT_INTERPRETER_BINARY_SOURCEFILE "/data/test/lxt_binfmt_interpreter_binary.c"
48
49 //
50 // N.B. These UID and GID values must be kept in-sync with the values in the
51 // source below.
52 //
53
54 #define BINFMT_CALLER_UID 0
55 #define BINFMT_CALLER_GID 0
56 #define BINFMT_BINARY_UID 1044
57 #define BINFMT_BINARY_GID 1044
58 #define BINFMT_P_FLAG_ARG "foo"
59
60 #define BINFMT_INTERPRETER_BINARY_SOURCE_BEGIN \
61 "#define _GNU_SOURCE\n" \
62 "#include <stdio.h>\n" \
63 "#include <string.h>\n" \
64 "#include <stdlib.h>\n" \
65 "#include <fcntl.h>\n" \
66 "#include <unistd.h>\n" \
67 "#include <errno.h>\n" \
68 "#include <sys/auxv.h>\n" \
69 "#define BINFMT_CALLER_UID 0\n" \
70 "#define BINFMT_CALLER_GID 0\n" \
71 "#define BINFMT_BINARY_UID 1044\n" \
72 "#define BINFMT_BINARY_GID 1044\n" \
73 "#define BINFMT_P_FLAG_ARG \"foo\"\n" \
74 "#define BINFMT_INTERPRETER_BINARY \"/data/test/lxt_binfmt_interpreter_binary\"\n" \
75 "#define BINFMT_TEST_FILE \"/data/test/lxt_binfmt_test\"\n" \
76 "\n" \
77 "int main(int Argc, char** Argv)\n" \
78 "{\n" \
79 " struct stat Buffer;\n" \
80 " int Fd;\n" \
81 " int Index;\n" \
82 " uid_t Real, Effective, Saved;\n" \
83 " printf(\"Pid = %d\\n\", getpid());\n" \
84 " Fd = getauxval(AT_EXECFD);\n" \
85 " printf(\"AT_EXECFD = %d errno = %d\\n\", Fd, errno);\n" \
86 " getresuid(&Real, &Effective, &Saved);\n" \
87 " printf(\"Real %d Effective %d Saved %d\\n\", Real, Effective, Saved);\n" \
88 " printf(\"Argc = %d\\n\", Argc);\n" \
89 " for (Index = 0; Index < Argc; Index += 1) {\n" \
90 " printf(\"Argv[%d] = %s\\n\", Index, Argv[Index]);\n" \
91 " }\n"
92
93 #define BINFMT_INTERPRETER_BINARY_SOURCE_VERIFY_TWO_ARGS \
94 " if (Argc != 2) {\n" \
95 " return -1;\n" \
96 " }\n" \
97 " if (strcmp(Argv[0], BINFMT_INTERPRETER_BINARY) != 0) {\n" \
98 " return -1;\n" \
99 " }\n" \
100 " if (strcmp(Argv[1], BINFMT_TEST_FILE) != 0) {\n" \
101 " return -1;\n" \
102 " }\n"
103
104 #define BINFMT_INTERPRETER_BINARY_SOURCE_MIDDLE_C_FLAG \
105 " if ((Fd == 0) && (errno == ENOENT)) {\n" \
106 " return -1;\n" \
107 " }\n" \
108 " if (fcntl(Fd, F_GETFD) != 0) {\n" \
109 " return -1;\n" \
110 " }\n" \
111 " if ((Real != BINFMT_CALLER_UID) ||\n" \
112 " (Effective != BINFMT_BINARY_UID) ||\n" \
113 " (Saved != BINFMT_BINARY_UID)) {\n" \
114 " return -1;\n" \
115 " }\n" BINFMT_INTERPRETER_BINARY_SOURCE_VERIFY_TWO_ARGS
116
117 #define BINFMT_INTERPRETER_BINARY_SOURCE_MIDDLE_O_FLAG \
118 " if ((Fd == 0) && (errno == ENOENT)) {\n" \
119 " return -1;\n" \
120 " }\n" \
121 " if (fcntl(Fd, F_GETFD) != 0) {\n" \
122 " return -1;\n" \
123 " }\n" \
124 " if ((Real != BINFMT_CALLER_UID) ||\n" \
125 " (Effective != BINFMT_CALLER_UID) ||\n" \
126 " (Saved != BINFMT_CALLER_UID)) {\n" \
127 " return -1;\n" \
128 " }\n" BINFMT_INTERPRETER_BINARY_SOURCE_VERIFY_TWO_ARGS
129
130 #define BINFMT_INTERPRETER_BINARY_SOURCE_MIDDLE_P_FLAG \
131 " if ((Fd != 0) || (errno != ENOENT)) {\n" \
132 " return -1;\n" \
133 " }\n" \
134 " if (Argc != 4) {\n" \
135 " return -1;\n" \
136 " }\n" \
137 " if (strcmp(Argv[0], BINFMT_INTERPRETER_BINARY) != 0) {\n" \
138 " return -1;\n" \
139 " }\n" \
140 " if (strcmp(Argv[1], BINFMT_TEST_FILE) != 0) {\n" \
141 " return -1;\n" \
142 " }\n" \
143 " if (strcmp(Argv[2], BINFMT_TEST_FILE) != 0) {\n" \
144 " return -1;\n" \
145 " }\n" \
146 " if (strcmp(Argv[3], BINFMT_P_FLAG_ARG) != 0) {\n" \
147 " return -1;\n" \
148 " }\n"
149
150 #define BINFMT_INTERPRETER_BINARY_SOURCE_MIDDLE_NO_FLAGS \
151 " if ((Fd != 0) || (errno != ENOENT)) {\n" \
152 " return -1;\n" \
153 " }\n"
154
155 #define BINFMT_INTERPRETER_BINARY_SOURCE_END \
156 " return 0;\n" \
157 "}"
158
159 #define BINFMT_INTERPRETER_BINARY_SOURCE_C_FLAG \
160 BINFMT_INTERPRETER_BINARY_SOURCE_BEGIN \
161 BINFMT_INTERPRETER_BINARY_SOURCE_MIDDLE_C_FLAG \
162 BINFMT_INTERPRETER_BINARY_SOURCE_END
163
164 #define BINFMT_INTERPRETER_BINARY_SOURCE_O_FLAG \
165 BINFMT_INTERPRETER_BINARY_SOURCE_BEGIN \
166 BINFMT_INTERPRETER_BINARY_SOURCE_MIDDLE_O_FLAG \
167 BINFMT_INTERPRETER_BINARY_SOURCE_END
168
169 #define BINFMT_INTERPRETER_BINARY_SOURCE_P_FLAG \
170 BINFMT_INTERPRETER_BINARY_SOURCE_BEGIN \
171 BINFMT_INTERPRETER_BINARY_SOURCE_MIDDLE_P_FLAG \
172 BINFMT_INTERPRETER_BINARY_SOURCE_END
173
174 #define BINFMT_INTERPRETER_BINARY_SOURCE_NO_FLAGS \
175 BINFMT_INTERPRETER_BINARY_SOURCE_BEGIN \
176 BINFMT_INTERPRETER_BINARY_SOURCE_MIDDLE_NO_FLAGS \
177 BINFMT_INTERPRETER_BINARY_SOURCE_END
178
179 #define BINFMT_OFFSET_TEST "/data/test/binfmt_offset"
180 #define BINFMT_OFFSET_TEST_PATTERN "GSH"
181
182 #define BINFMT_REGISTER_BINARY_STRING ":" BINFMT_REGISTER_NAME ":M::\\xff\\xff\\xff\\xff::" BINFMT_INTERPRETER_BINARY ":"
183 #define BINFMT_REGISTER_BINARY_STRING_C BINFMT_REGISTER_BINARY_STRING "C"
184 #define BINFMT_REGISTER_BINARY_STRING_O BINFMT_REGISTER_BINARY_STRING "O"
185 #define BINFMT_REGISTER_BINARY_STRING_P BINFMT_REGISTER_BINARY_STRING "P"
186
187 #define BINFMT_STATUS_ENABLED "enabled\n"
188 #define BINFMT_STATUS_DISABLED "disabled\n"
189
190 #define BINFMT_REGISTRATION_ENABLED_STRING \
191 BINFMT_STATUS_ENABLED \
192 "interpreter " BINFMT_INTERPRETER_SCRIPT \
193 "\n" \
194 "flags: \n" \
195 "offset 0\n" \
196 "magic ffffffff\n"
197
198 #define BINFMT_REGISTRATION_DISABLED_STRING \
199 BINFMT_STATUS_DISABLED \
200 "interpreter " BINFMT_INTERPRETER_SCRIPT \
201 "\n" \
202 "flags: \n" \
203 "offset 0\n" \
204 "magic ffffffff\n"
205
206 typedef struct _LXT_BINFMT_REGISTRATION
207 {
208 char* RegistrationString;
209 char Magic[4];
210 char* TestFile;
211 } LXT_BINFMT_REGISTRATION, PLXT_BINFMT_REGISTRATION;
212
213 LXT_BINFMT_REGISTRATION g_BinfmtRegistrations[] = {
214 {":binfmt_1:M::\\x01\x01\x01\x01::/data/test/lxt_binfmt_2:", {0x1, 0x1, 0x1, 0x1}, "/data/test/lxt_binfmt_1"},
215 {":binfmt_2:M::\\x02\x02\x02\x02::/data/test/lxt_binfmt_3:", {0x2, 0x2, 0x2, 0x2}, "/data/test/lxt_binfmt_2"},
216 {":binfmt_3:M::\\x03\x03\x03\x03::/data/test/lxt_binfmt_4:", {0x3, 0x3, 0x3, 0x3}, "/data/test/lxt_binfmt_3"},
217 {":binfmt_4:M::\\x04\x04\x04\x04::/data/test/lxt_binfmt_5:", {0x4, 0x4, 0x4, 0x4}, "/data/test/lxt_binfmt_4"},
218 {":binfmt_5:M::\\x05\x05\x05\x05::/data/test/lxt_binfmt_6:", {0x5, 0x5, 0x5, 0x5}, "/data/test/lxt_binfmt_5"},
219 {":binfmt_6:M::\\x06\x06\x06\x06::/data/test/lxt_binfmt_7:", {0x6, 0x6, 0x6, 0x6}, "/data/test/lxt_binfmt_6"},
220 {":binfmt_7:M::\\x07\x07\x07\x07::/bin/echo:", {0x7, 0x7, 0x7, 0x7}, "/data/test/lxt_binfmt_7"}};
221
222 void BimFmtCleanup(void);
223
224 int BinFmtExtension(PLXT_ARGS Args);
225
226 int BinFmtInvalidParam(PLXT_ARGS Args);
227
228 int BinFmtOffset(PLXT_ARGS Args);
229
230 int BinFmtOptions(PLXT_ARGS Args);
231
232 int BinFmtRegister(PLXT_ARGS Args);
233
234 int BinFmtRoot(PLXT_ARGS Args);
235
236 int BinFmtStatus(PLXT_ARGS Args);
237
238 int BinFmtInterpreterEntry(PLXT_ARGS Args);
239
240 //
241 // Global constants
242 //
243
244 static const LXT_VARIATION g_LxtVariations[] = {
245 {"BinFmt - " BINFMT_MNT " root", BinFmtRoot},
246 {"BinFmt - " BINFMT_MNT "/register", BinFmtRegister},
247 {"BinFmt - " BINFMT_MNT "/status", BinFmtStatus},
248 {"BinFmt - Extensions", BinFmtExtension},
249 {"BinFmt - Options", BinFmtOptions},
250 {"BinFmt - Offset", BinFmtOffset},
251 {"BinFmt - Invalid Parameter", BinFmtInvalidParam}};
252
253 static const LXT_CHILD_INFO g_BinFmtRootChildren[] = {{"register", DT_REG}, {"status", DT_REG}};
254
255 static const char* g_BinFmtRegisterInvalid[] = {
256 "::M::BACON::/usr/bin/test:",
257 ":Test:B::BACON::/usr/bin/test:",
258 ":Test:M::BACON:BACONISAWESOME:/usr/bin/test:",
259 ":Test:M::BACON:\\xff:/usr/bin/test:",
260 ":Test:M::BACON:\\xff\\xff\\xff\\xff\\xf:/usr/bin/test:",
261 ":Test:M::BACON:::",
262 ":Test:M::BACON::/usr/bin/test:B",
263 ":Test:M::BACON::/usr/bin/test: ",
264 ":Test:M::BACON::/usr/bin/test:\nO",
265 ":Test:E::B/ACON::/usr/bin/test:",
266
267 /*
268 ":aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:M::BACON::/usr/bin/aaaaaaaaa:",
269 ":aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:M::BACON::/usr/bin/aaaaaaaaaaaaaaa:",
270 ":aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:M::BACON::/usr/bin/aaaaaaaaaaaaaaaaaaaaaaaa:",
271 ":aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:M::BACON::/usr/bin/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:",
272 ":aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:M::BACON::/usr/bin/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:",
273 */
274
275 ":::::::::::::::::",
276 "",
277 "\0"};
278
279 int BinFmtTestEntry(int Argc, char* Argv[])
280
281 /*++
282
283 Routine Description:
284
285 This routine is the main entry point for the binfmt tests.
286
287 Arguments:
288
289 Argc - Supplies the number of command line arguments.
290
291 Argv - Supplies the command line arguments.
292
293 Return Value: LxtCheckResult(LxtInitialize(Argc, Argv, &Args, LXT_NAME));
294
295 Returns 0 on success, -1 on failure.
296
297 --*/
298
299 {
300
301 LXT_ARGS Args;
302 int Opt;
303 int Result;
304
305 LxtCheckResult(LxtInitialize(Argc, Argv, &Args, LXT_NAME));
306 optind = 0;
307 opterr = 0;
308 while ((Opt = getopt(Argc, Argv, "i")) != -1)
309 {
310 switch (Opt)
311 {
312 case 'i':
313 Result = BinFmtInterpreterEntry(&Args);
314 goto ErrorExit;
315 }
316 }
317
318 LxtCheckResult(LxtRunVariations(&Args, g_LxtVariations, LXT_COUNT_OF(g_LxtVariations)));
319
320 ErrorExit:
321 LxtUninitialize();
322 return !LXT_SUCCESS(Result);
323 }
324
325 void BimFmtCleanup(void)
326
327 {
328
329 int Fd;
330 int Result;
331 int Size;
332
333 //
334 // Remove the test entry via the registration file.
335 //
336
337 Fd = open(BINFMT_MNT "/" BINFMT_REGISTER_NAME, O_RDWR);
338 if (Fd >= 0)
339 {
340 Size = strlen(BINFMT_REMOVE_STRING);
341 LxtCheckErrno(Size = write(Fd, BINFMT_REMOVE_STRING, Size));
342 }
343
344 ErrorExit:
345 if (Fd != -1)
346 {
347 LxtClose(Fd);
348 }
349
350 return;
351 }
352
353 int BinFmtExtension(PLXT_ARGS Args)
354
355 /*++
356
357 Description:
358
359 This routine tests binformat extensions.
360
361 Arguments:
362
363 Args - Supplies the command line arguments.
364
365 Return Value:
366
367 Returns 0 on success, -1 on failure.
368
369 --*/
370
371 {
372
373 char Buffer[16];
374 size_t BytesWritten;
375 int ChildPid;
376 char* ExecArgs[2];
377 int Fd = -1;
378 int Index;
379 int RegisterFd;
380 LXT_CHILD_INFO Registration;
381 int Result;
382 ssize_t Size;
383 int Status;
384
385 //
386 // Clean any binfmt interpreters from a previous iteration of the test.
387 //
388
389 BimFmtCleanup();
390
391 //
392 // Create the binfmt interpreter.
393 //
394
395 LxtCheckErrno(Fd = creat(BINFMT_INTERPRETER_SCRIPT, 0777));
396 LxtCheckErrno(BytesWritten = write(Fd, BINFMT_INTERPRETER_SCRIPT_CONTENTS, (sizeof(BINFMT_INTERPRETER_SCRIPT_CONTENTS) - 1)));
397
398 LxtClose(Fd);
399 Fd = -1;
400
401 //
402 // Register a binfmt extension.
403 //
404
405 LxtCheckErrno(RegisterFd = open(BINFMT_MNT "/register", O_WRONLY));
406 Size = strlen(BINFMT_REGISTER_SCRIPT_STRING);
407 LxtCheckErrno(Size = write(RegisterFd, BINFMT_REGISTER_SCRIPT_STRING, Size));
408
409 //
410 // Create a file that will be handled by the binfmt extension.
411 //
412
413 LxtCheckErrno(Fd = creat(BINFMT_TEST_FILE, 0777));
414 memset(Buffer, 0xff, sizeof(Buffer));
415 LxtCheckErrno(BytesWritten = write(Fd, Buffer, sizeof(Buffer)));
416 LxtClose(Fd);
417 Fd = -1;
418
419 //
420 // Fork and exec the file.
421 //
422
423 LxtCheckResult(ChildPid = fork());
424 if (ChildPid == 0)
425 {
426 ExecArgs[0] = BINFMT_TEST_FILE;
427 ExecArgs[1] = NULL;
428 LxtCheckErrno(LxtExecve(ExecArgs[0], ExecArgs, NULL));
429
430 //
431 // The parent waits for the child to exit successfully.
432 //
433 }
434 else
435 {
436 LxtCheckResult(LxtWaitPidPoll(ChildPid, 0));
437 }
438
439 //
440 // Remove the new entry via the registration file.
441 //
442
443 LxtCheckErrno(Fd = open(BINFMT_MNT "/" BINFMT_REGISTER_NAME, O_RDWR));
444 Size = strlen(BINFMT_REMOVE_STRING);
445 LxtCheckErrno(Size = write(Fd, BINFMT_REMOVE_STRING, Size));
446 LxtClose(Fd);
447 Fd = -1;
448
449 //
450 // Create many registrations and test files.
451 //
452
453 for (Index = 0; Index < LXT_COUNT_OF(g_BinfmtRegistrations); Index += 1)
454 {
455 Size = strlen(g_BinfmtRegistrations[Index].RegistrationString);
456 LxtCheckErrno(Size = write(RegisterFd, g_BinfmtRegistrations[Index].RegistrationString, Size));
457 LxtCheckErrno(Fd = creat(g_BinfmtRegistrations[Index].TestFile, 0777));
458 LxtCheckErrno(BytesWritten = write(Fd, g_BinfmtRegistrations[Index].Magic, sizeof(g_BinfmtRegistrations[Index].Magic)));
459 LxtClose(Fd);
460 Fd = -1;
461 }
462
463 //
464 // Fork and exec the file to test the interpreter depth.
465 //
466
467 Index = 2;
468 LxtCheckResult(ChildPid = fork());
469 if (ChildPid == 0)
470 {
471 ExecArgs[0] = g_BinfmtRegistrations[Index].TestFile;
472 ExecArgs[1] = NULL;
473 LxtCheckErrno(LxtExecve(ExecArgs[0], ExecArgs, NULL));
474
475 //
476 // The parent waits for the child to exit successfully.
477 //
478 }
479 else
480 {
481 LxtCheckResult(LxtWaitPidPoll(ChildPid, 0));
482 }
483
484 //
485 // Test max interpreter link depth (should fail).
486 //
487
488 Index = 1;
489 LxtCheckResult(ChildPid = fork());
490 if (ChildPid == 0)
491 {
492 ExecArgs[0] = g_BinfmtRegistrations[Index].TestFile;
493 ExecArgs[1] = NULL;
494 LxtCheckErrnoFailure(LxtExecve(ExecArgs[0], ExecArgs, NULL), ELOOP);
495 exit(0);
496
497 //
498 // The parent waits for the child to exit.
499 //
500 }
501 else
502 {
503 LxtCheckResult(LxtWaitPidPoll(ChildPid, 0));
504 }
505
506 //
507 // Remove the entries via the status file.
508 //
509
510 LxtCheckErrno(Fd = open(BINFMT_MNT "/status", O_RDWR));
511 Size = strlen(BINFMT_REMOVE_STRING);
512 LxtCheckErrno(Size = write(Fd, BINFMT_REMOVE_STRING, Size));
513 LxtClose(Fd);
514 Fd = -1;
515
516 ErrorExit:
517 if (RegisterFd > 0)
518 {
519 LxtClose(RegisterFd);
520 }
521
522 if (Fd > 0)
523 {
524 LxtClose(Fd);
525 }
526
527 if (ChildPid == 0)
528 {
529 _exit(Result);
530 }
531
532 return Result;
533 }
534
535 int BinFmtInvalidParam(PLXT_ARGS Args)
536
537 /*++
538
539 Description:
540
541 This routine tests invalid argument handling for the binfmt register file.
542
543 Arguments:
544
545 Args - Supplies the command line arguments.
546
547 Return Value:
548
549 Returns 0 on success, -1 on failure.
550
551 --*/
552
553 {
554
555 int Fd;
556 int Index;
557 int Result;
558 ssize_t Size;
559
560 LxtCheckErrno(Fd = open(BINFMT_MNT "/register", O_WRONLY));
561 for (Index = 0; Index < LXT_COUNT_OF(g_BinFmtRegisterInvalid); Index += 1)
562 {
563 LxtLogInfo("Index[%d] %s", Index, g_BinFmtRegisterInvalid[Index]);
564 Size = strlen(g_BinFmtRegisterInvalid[Index]);
565 LxtCheckErrnoFailure(Size = write(Fd, g_BinFmtRegisterInvalid[Index], Size), EINVAL);
566 }
567
568 ErrorExit:
569 if (Fd > 0)
570 {
571 LxtClose(Fd);
572 }
573
574 return Result;
575 }
576
577 int BinFmtOffset(PLXT_ARGS Args)
578
579 /*++
580
581 Description:
582
583 This routine tests binformat interpreter options.
584
585 Arguments:
586
587 Args - Supplies the command line arguments.
588
589 Return Value:
590
591 Returns 0 on success, -1 on failure.
592
593 --*/
594
595 {
596
597 int ChildPid;
598 char* ExecArgs[2];
599 int Fd;
600 char RegisterString[] = ":" BINFMT_REGISTER_NAME ":M:2:" BINFMT_OFFSET_TEST_PATTERN "::/bin/true:";
601 int Result;
602 ssize_t Size;
603
604 //
605 // Register an interpreter with a known string at a two byte offset.
606 //
607
608 LxtCheckErrno(Fd = open(BINFMT_MNT "/register", O_WRONLY));
609 Size = strlen(RegisterString);
610 LxtCheckErrno(Size = write(Fd, RegisterString, Size));
611
612 //
613 // Create a test file that matches this pattern.
614 //
615
616 LxtClose(Fd);
617 LxtCheckErrno(Fd = creat(BINFMT_OFFSET_TEST, 0777));
618 LxtCheckErrno(Size = write(Fd, "00" BINFMT_OFFSET_TEST_PATTERN, sizeof(BINFMT_OFFSET_TEST_PATTERN) + 2));
619 LxtClose(Fd);
620 Fd = -1;
621
622 //
623 // Fork and exec the file and ensure that the binfmt interpreter is invoked.
624 //
625
626 LxtCheckResult(ChildPid = fork());
627 if (ChildPid == 0)
628 {
629 ExecArgs[0] = BINFMT_OFFSET_TEST;
630 ExecArgs[1] = NULL;
631 LxtCheckErrno(LxtExecve(ExecArgs[0], ExecArgs, NULL));
632 goto ErrorExit;
633 }
634
635 //
636 // Wait for the child to exit.
637 //
638
639 LxtCheckResult(LxtWaitPidPoll(ChildPid, 0));
640
641 //
642 // Create a test file that does not match the pattern.
643 //
644
645 LxtCheckErrno(Fd = creat(BINFMT_OFFSET_TEST, 0777));
646 LxtCheckErrno(Size = write(Fd, BINFMT_OFFSET_TEST_PATTERN, sizeof(BINFMT_OFFSET_TEST_PATTERN)));
647 LxtClose(Fd);
648 Fd = -1;
649
650 //
651 // Fork and exec the file and ensure that the exec fails.
652 //
653
654 LxtCheckResult(ChildPid = fork());
655 if (ChildPid == 0)
656 {
657 ExecArgs[0] = BINFMT_OFFSET_TEST;
658 ExecArgs[1] = NULL;
659 LxtCheckErrnoFailure(LxtExecve(ExecArgs[0], ExecArgs, NULL), ENOEXEC);
660 goto ErrorExit;
661 }
662
663 //
664 // Wait for the child to exit.
665 //
666
667 LxtCheckResult(LxtWaitPidPoll(ChildPid, 0));
668
669 Result = LXT_RESULT_SUCCESS;
670
671 ErrorExit:
672 if (Fd > 0)
673 {
674 LxtClose(Fd);
675 }
676
677 if (ChildPid == 0)
678 {
679 _exit(Result);
680 }
681
682 //
683 // Unregister the interpreter and delete the test file.
684 //
685
686 BimFmtCleanup();
687 unlink(BINFMT_OFFSET_TEST);
688
689 return Result;
690 }
691
692 int BinFmtOptions(PLXT_ARGS Args)
693
694 /*++
695
696 Description:
697
698 This routine tests binformat interpreter options.
699
700 Arguments:
701
702 Args - Supplies the command line arguments.
703
704 Return Value:
705
706 Returns 0 on success, -1 on failure.
707
708 --*/
709
710 {
711
712 char* Argv[5];
713 char Buffer[16];
714 size_t BytesWritten;
715 int ChildPid;
716 char* ExecArgs[3];
717 int Fd = -1;
718 int Index;
719 int RegisterFd;
720 LXT_CHILD_INFO Registration;
721 int Result;
722 ssize_t Size;
723 int Status;
724
725 //
726 // Clean any binfmt interpreters from a previous iteration of the test.
727 //
728
729 BimFmtCleanup();
730
731 //
732 // Create a file that will be handled by the binfmt extension.
733 //
734
735 LxtCheckErrno(Fd = creat(BINFMT_TEST_FILE, 0777));
736 memset(Buffer, 0xff, sizeof(Buffer));
737 LxtCheckErrno(BytesWritten = write(Fd, Buffer, sizeof(Buffer)));
738 LxtCheckErrno(fchown(Fd, BINFMT_BINARY_UID, BINFMT_BINARY_GID));
739 LxtCheckErrno(fchmod(Fd, 0777 | S_ISUID));
740 LxtClose(Fd);
741 Fd = -1;
742
743 //
744 // Create a binfmt interpreter without any flags.
745 //
746
747 LxtLogInfo("Testing no flags");
748 LxtCheckErrno(Fd = creat(BINFMT_INTERPRETER_BINARY_SOURCEFILE, 0777));
749 LxtCheckErrno(BytesWritten = write(Fd, BINFMT_INTERPRETER_BINARY_SOURCE_NO_FLAGS, (sizeof(BINFMT_INTERPRETER_BINARY_SOURCE_NO_FLAGS) - 1)));
750
751 LxtClose(Fd);
752 Fd = -1;
753
754 //
755 // Compile the binary
756 //
757
758 LxtCheckErrno(ChildPid = fork());
759 if (ChildPid == 0)
760 {
761 Argv[0] = "gcc";
762 Argv[1] = BINFMT_INTERPRETER_BINARY_SOURCEFILE;
763 Argv[2] = "-o";
764 Argv[3] = BINFMT_INTERPRETER_BINARY;
765 Argv[4] = NULL;
766 LxtCheckErrno(execv("/usr/bin/gcc", Argv));
767 goto ErrorExit;
768 }
769
770 //
771 // Wait for the child to exit.
772 //
773
774 LxtCheckResult(LxtWaitPidPollOptions(ChildPid, LXT_RESULT_SUCCESS, 0, BINFMT_TIMEOUT));
775
776 //
777 // Register a binfmt extension without flags.
778 //
779
780 LxtCheckErrno(RegisterFd = open(BINFMT_MNT "/register", O_WRONLY));
781 Size = strlen(BINFMT_REGISTER_BINARY_STRING);
782 LxtCheckErrno(Size = write(RegisterFd, BINFMT_REGISTER_BINARY_STRING, Size));
783
784 //
785 // Fork and exec the file.
786 //
787
788 LxtCheckResult(ChildPid = fork());
789 if (ChildPid == 0)
790 {
791 LxtCheckErrno(LxtSetresuid(BINFMT_CALLER_UID, BINFMT_CALLER_UID, BINFMT_CALLER_UID));
792 ExecArgs[0] = BINFMT_TEST_FILE;
793 ExecArgs[1] = NULL;
794 LxtCheckErrno(LxtExecve(ExecArgs[0], ExecArgs, NULL));
795 }
796
797 //
798 // Wait for the child to exit.
799 //
800
801 LxtCheckResult(LxtWaitPidPollOptions(ChildPid, 0, 0, BINFMT_TIMEOUT));
802
803 //
804 // Unregister the interpreter.
805 //
806
807 BimFmtCleanup();
808
809 //
810 // Create the binfmt interpreter that handles the 'O' flag.
811 //
812
813 LxtLogInfo("Testing 'O' flag");
814 LxtCheckErrno(Fd = creat(BINFMT_INTERPRETER_BINARY_SOURCEFILE, 0777));
815 LxtCheckErrno(BytesWritten = write(Fd, BINFMT_INTERPRETER_BINARY_SOURCE_O_FLAG, (sizeof(BINFMT_INTERPRETER_BINARY_SOURCE_O_FLAG) - 1)));
816
817 LxtClose(Fd);
818 Fd = -1;
819
820 //
821 // Compile the binary
822 //
823
824 LxtCheckErrno(ChildPid = fork());
825 if (ChildPid == 0)
826 {
827 Argv[0] = "gcc";
828 Argv[1] = BINFMT_INTERPRETER_BINARY_SOURCEFILE;
829 Argv[2] = "-o";
830 Argv[3] = BINFMT_INTERPRETER_BINARY;
831 Argv[4] = NULL;
832 LxtCheckErrno(execv("/usr/bin/gcc", Argv));
833 goto ErrorExit;
834 }
835
836 //
837 // Wait for the child to exit.
838 //
839
840 LxtCheckResult(LxtWaitPidPollOptions(ChildPid, LXT_RESULT_SUCCESS, 0, BINFMT_TIMEOUT));
841
842 //
843 // Register a binfmt extension.
844 //
845
846 LxtCheckErrno(RegisterFd = open(BINFMT_MNT "/register", O_WRONLY));
847 Size = strlen(BINFMT_REGISTER_BINARY_STRING_O);
848 LxtCheckErrno(Size = write(RegisterFd, BINFMT_REGISTER_BINARY_STRING_O, Size));
849
850 //
851 // Fork and exec the file.
852 //
853
854 LxtCheckResult(ChildPid = fork());
855 if (ChildPid == 0)
856 {
857 LxtCheckErrno(LxtSetresuid(BINFMT_CALLER_UID, BINFMT_CALLER_UID, BINFMT_CALLER_UID));
858 ExecArgs[0] = BINFMT_TEST_FILE;
859 ExecArgs[1] = NULL;
860 LxtCheckErrno(LxtExecve(ExecArgs[0], ExecArgs, NULL));
861 }
862
863 //
864 // Wait for the child to exit.
865 //
866
867 LxtCheckResult(LxtWaitPidPollOptions(ChildPid, 0, 0, BINFMT_TIMEOUT));
868
869 //
870 // Unregister the interpreter.
871 //
872
873 BimFmtCleanup();
874
875 //
876 // Create the binfmt interpreter that handles the 'C' flag.
877 //
878
879 LxtLogInfo("Testing 'C' flag");
880 LxtCheckErrno(Fd = creat(BINFMT_INTERPRETER_BINARY_SOURCEFILE, 0777));
881 LxtCheckErrno(BytesWritten = write(Fd, BINFMT_INTERPRETER_BINARY_SOURCE_C_FLAG, (sizeof(BINFMT_INTERPRETER_BINARY_SOURCE_C_FLAG) - 1)));
882
883 LxtClose(Fd);
884 Fd = -1;
885
886 //
887 // Compile the binary
888 //
889
890 LxtCheckErrno(ChildPid = fork());
891 if (ChildPid == 0)
892 {
893 Argv[0] = "gcc";
894 Argv[1] = BINFMT_INTERPRETER_BINARY_SOURCEFILE;
895 Argv[2] = "-o";
896 Argv[3] = BINFMT_INTERPRETER_BINARY;
897 Argv[4] = NULL;
898 LxtCheckErrno(execv("/usr/bin/gcc", Argv));
899 goto ErrorExit;
900 }
901
902 //
903 // Wait for the child to exit.
904 //
905
906 LxtCheckResult(LxtWaitPidPollOptions(ChildPid, LXT_RESULT_SUCCESS, 0, BINFMT_TIMEOUT));
907
908 //
909 // Register a binfmt extension.
910 //
911
912 LxtCheckErrno(RegisterFd = open(BINFMT_MNT "/register", O_WRONLY));
913 Size = strlen(BINFMT_REGISTER_BINARY_STRING_C);
914 LxtCheckErrno(Size = write(RegisterFd, BINFMT_REGISTER_BINARY_STRING_C, Size));
915
916 //
917 // Fork and exec the file.
918 //
919
920 LxtCheckResult(ChildPid = fork());
921 if (ChildPid == 0)
922 {
923 LxtCheckErrno(LxtSetresuid(BINFMT_CALLER_UID, BINFMT_CALLER_UID, BINFMT_CALLER_UID));
924 ExecArgs[0] = BINFMT_TEST_FILE;
925 ExecArgs[1] = NULL;
926 LxtCheckErrno(LxtExecve(ExecArgs[0], ExecArgs, NULL));
927 }
928
929 //
930 // Wait for the child to exit.
931 //
932
933 LxtCheckResult(LxtWaitPidPollOptions(ChildPid, 0, 0, BINFMT_TIMEOUT));
934
935 //
936 // Unregister the interpreter.
937 //
938
939 BimFmtCleanup();
940
941 //
942 // Create the binfmt interpreter that handles the 'P' flag.
943 //
944
945 LxtLogInfo("Testing 'P' flag");
946 LxtCheckErrno(Fd = creat(BINFMT_INTERPRETER_BINARY_SOURCEFILE, 0777));
947 LxtCheckErrno(BytesWritten = write(Fd, BINFMT_INTERPRETER_BINARY_SOURCE_P_FLAG, (sizeof(BINFMT_INTERPRETER_BINARY_SOURCE_P_FLAG) - 1)));
948
949 LxtClose(Fd);
950 Fd = -1;
951
952 //
953 // Compile the binary
954 //
955
956 LxtCheckErrno(ChildPid = fork());
957 if (ChildPid == 0)
958 {
959 Argv[0] = "gcc";
960 Argv[1] = BINFMT_INTERPRETER_BINARY_SOURCEFILE;
961 Argv[2] = "-o";
962 Argv[3] = BINFMT_INTERPRETER_BINARY;
963 Argv[4] = NULL;
964 LxtCheckErrno(execv("/usr/bin/gcc", Argv));
965 goto ErrorExit;
966 }
967
968 //
969 // Wait for the child to exit.
970 //
971
972 LxtCheckResult(LxtWaitPidPollOptions(ChildPid, LXT_RESULT_SUCCESS, 0, BINFMT_TIMEOUT));
973
974 //
975 // Register a binfmt extension.
976 //
977
978 LxtCheckErrno(RegisterFd = open(BINFMT_MNT "/register", O_WRONLY));
979 Size = strlen(BINFMT_REGISTER_BINARY_STRING_P);
980 LxtCheckErrno(Size = write(RegisterFd, BINFMT_REGISTER_BINARY_STRING_P, Size));
981
982 //
983 // Fork and exec the file.
984 //
985
986 LxtCheckResult(ChildPid = fork());
987 if (ChildPid == 0)
988 {
989 ExecArgs[0] = BINFMT_TEST_FILE;
990 ExecArgs[1] = BINFMT_P_FLAG_ARG;
991 ExecArgs[2] = NULL;
992 LxtCheckErrno(LxtExecve(ExecArgs[0], ExecArgs, NULL));
993 }
994
995 //
996 // Wait for the child to exit.
997 //
998
999 LxtCheckResult(LxtWaitPidPollOptions(ChildPid, 0, 0, BINFMT_TIMEOUT));
1000
1001 //
1002 // Unregister the interpreter.
1003 //
1004
1005 BimFmtCleanup();
1006
1007 ErrorExit:
1008 if (RegisterFd > 0)
1009 {
1010 LxtClose(RegisterFd);
1011 }
1012
1013 if (Fd > 0)
1014 {
1015 LxtClose(Fd);
1016 }
1017
1018 if (ChildPid == 0)
1019 {
1020 _exit(Result);
1021 }
1022
1023 return Result;
1024 }
1025
1026 int BinFmtRoot(PLXT_ARGS Args)
1027
1028 /*++
1029
1030 Description:
1031
1032 This routine tests the contents of the binfmt directory.
1033
1034 Arguments:
1035
1036 Args - Supplies the command line arguments.
1037
1038 Return Value:
1039
1040 Returns 0 on success, -1 on failure.
1041
1042 --*/
1043
1044 {
1045
1046 int Result;
1047
1048 // LxtCheckResult(LxtCheckStat(BINFMT_MNT, 1, DT_DIR));
1049 LxtCheckResult(LxtCheckDirectoryContents(BINFMT_MNT, g_BinFmtRootChildren, LXT_COUNT_OF(g_BinFmtRootChildren)));
1050
1051 ErrorExit:
1052 return Result;
1053 }
1054
1055 int BinFmtRegister(PLXT_ARGS Args)
1056
1057 /*++
1058
1059 Description:
1060
1061 This routine tests the binfmt register file.
1062
1063 Arguments:
1064
1065 Args - Supplies the command line arguments.
1066
1067 Return Value:
1068
1069 Returns 0 on success, -1 on failure.
1070
1071 --*/
1072
1073 {
1074
1075 char Buffer[128];
1076 int Fd;
1077 LXT_CHILD_INFO Registration;
1078 int Result;
1079 ssize_t Size;
1080
1081 //
1082 // Clean up any previously registered interpreters.
1083 //
1084
1085 BimFmtCleanup();
1086
1087 //
1088 // Open the register file and verify that binfmt registrations are able to be registered.
1089 //
1090
1091 LxtCheckErrno(Fd = open(BINFMT_MNT "/register", O_WRONLY));
1092
1093 Size = strlen(BINFMT_REGISTER_SCRIPT_STRING);
1094 LxtCheckErrno(Size = write(Fd, BINFMT_REGISTER_SCRIPT_STRING, Size));
1095 LxtClose(Fd);
1096 Fd = -1;
1097
1098 Registration.Name = BINFMT_REGISTER_NAME;
1099 Registration.FileType = DT_REG;
1100
1101 LxtCheckResult(LxtCheckDirectoryContents(BINFMT_MNT, &Registration, 1));
1102
1103 //
1104 // Open the registration file and verify that it behaves as expected.
1105 // Status should initially be enabled.
1106 //
1107
1108 LxtCheckErrno(Fd = open(BINFMT_MNT "/" BINFMT_REGISTER_NAME, O_RDWR));
1109 LxtCheckErrno(Size = read(Fd, Buffer, sizeof(Buffer) - 1));
1110 Buffer[Size] = '\0';
1111 LxtClose(Fd);
1112 Fd = -1;
1113
1114 LxtCheckStringEqual(Buffer, BINFMT_REGISTRATION_ENABLED_STRING);
1115
1116 //
1117 // Disable the registration and verify the string changes.
1118 //
1119
1120 LxtCheckErrno(Fd = open(BINFMT_MNT "/" BINFMT_REGISTER_NAME, O_RDWR));
1121 Size = strlen(BINFMT_DISABLE_STRING);
1122 LxtCheckErrno(Size = write(Fd, BINFMT_DISABLE_STRING, Size));
1123 LxtClose(Fd);
1124 Fd = -1;
1125
1126 LxtCheckErrno(Fd = open(BINFMT_MNT "/" BINFMT_REGISTER_NAME, O_RDWR));
1127 LxtCheckErrno(Size = read(Fd, Buffer, sizeof(Buffer) - 1));
1128 Buffer[Size] = '\0';
1129 LxtClose(Fd);
1130 Fd = -1;
1131
1132 LxtCheckStringEqual(Buffer, BINFMT_REGISTRATION_DISABLED_STRING);
1133
1134 //
1135 // Enable and verify the string changes.
1136 //
1137
1138 LxtCheckErrno(Fd = open(BINFMT_MNT "/" BINFMT_REGISTER_NAME, O_RDWR));
1139 Size = strlen(BINFMT_ENABLE_STRING);
1140 LxtCheckErrno(Size = write(Fd, BINFMT_ENABLE_STRING, Size));
1141 LxtClose(Fd);
1142 Fd = -1;
1143
1144 LxtCheckErrno(Fd = open(BINFMT_MNT "/" BINFMT_REGISTER_NAME, O_RDWR));
1145 LxtCheckErrno(Size = read(Fd, Buffer, sizeof(Buffer) - 1));
1146 Buffer[Size] = '\0';
1147 LxtClose(Fd);
1148 Fd = -1;
1149
1150 LxtCheckStringEqual(Buffer, BINFMT_REGISTRATION_ENABLED_STRING);
1151
1152 //
1153 // Remove the new entry via the registration file.
1154 //
1155
1156 LxtCheckErrno(Fd = open(BINFMT_MNT "/" BINFMT_REGISTER_NAME, O_RDWR));
1157 Size = strlen(BINFMT_REMOVE_STRING);
1158 LxtCheckErrno(Size = write(Fd, BINFMT_REMOVE_STRING, Size));
1159 LxtClose(Fd);
1160 Fd = -1;
1161
1162 //
1163 // Attempt to open the file (should fail);
1164 //
1165
1166 LxtCheckErrnoFailure(Fd = open(BINFMT_MNT "/" BINFMT_REGISTER_NAME, O_RDWR), ENOENT);
1167
1168 ErrorExit:
1169 if (Fd > 0)
1170 {
1171 LxtClose(Fd);
1172 }
1173
1174 return Result;
1175 }
1176
1177 int BinFmtStatus(PLXT_ARGS Args)
1178
1179 /*++
1180
1181 Description:
1182
1183 This routine tests the binfmt status file.
1184
1185 Arguments:
1186
1187 Args - Supplies the command line arguments.
1188
1189 Return Value:
1190
1191 Returns 0 on success, -1 on failure.
1192
1193 --*/
1194
1195 {
1196
1197 char Buffer[64];
1198 int Fd;
1199 LXT_CHILD_INFO Registration;
1200 int Result;
1201 ssize_t Size;
1202
1203 //
1204 // Open the status file and verify that status behaves as expected.
1205 // Status should initially be enabled.
1206 //
1207
1208 LxtCheckErrno(Fd = open(BINFMT_MNT "/status", O_RDWR));
1209 LxtCheckErrno(Size = read(Fd, Buffer, sizeof(Buffer) - 1));
1210 Buffer[Size] = '\0';
1211 LxtClose(Fd);
1212 Fd = -1;
1213
1214 LxtCheckStringEqual(Buffer, BINFMT_STATUS_ENABLED);
1215
1216 //
1217 // Disable status and verify the string changes.
1218 //
1219
1220 LxtCheckErrno(Fd = open(BINFMT_MNT "/status", O_RDWR));
1221 Size = strlen(BINFMT_DISABLE_STRING);
1222 LxtCheckErrno(Size = write(Fd, BINFMT_DISABLE_STRING, Size));
1223 LxtClose(Fd);
1224 Fd = -1;
1225
1226 LxtCheckErrno(Fd = open(BINFMT_MNT "/status", O_RDWR));
1227 LxtCheckErrno(Size = read(Fd, Buffer, sizeof(Buffer) - 1));
1228 Buffer[Size] = '\0';
1229 LxtClose(Fd);
1230 Fd = -1;
1231
1232 LxtCheckStringEqual(Buffer, BINFMT_STATUS_DISABLED);
1233
1234 //
1235 // Enable and verify the string changes.
1236 //
1237
1238 LxtCheckErrno(Fd = open(BINFMT_MNT "/status", O_RDWR));
1239 Size = strlen(BINFMT_ENABLE_STRING);
1240 LxtCheckErrno(Size = write(Fd, BINFMT_ENABLE_STRING, Size));
1241 LxtClose(Fd);
1242 Fd = -1;
1243
1244 LxtCheckErrno(Fd = open(BINFMT_MNT "/status", O_RDWR));
1245 LxtCheckErrno(Size = read(Fd, Buffer, sizeof(Buffer) - 1));
1246 Buffer[Size] = '\0';
1247 LxtClose(Fd);
1248 Fd = -1;
1249
1250 LxtCheckStringEqual(Buffer, BINFMT_STATUS_ENABLED);
1251
1252 //
1253 // Register a binfmt extension and verify that it is removed when
1254 // -1 is written to the status file.
1255 //
1256
1257 LxtCheckErrno(Fd = open(BINFMT_MNT "/register", O_RDWR));
1258 Size = strlen(BINFMT_REGISTER_SCRIPT_STRING);
1259 LxtCheckErrno(Size = write(Fd, BINFMT_REGISTER_SCRIPT_STRING, Size));
1260 LxtClose(Fd);
1261 Fd = -1;
1262
1263 Registration.Name = BINFMT_REGISTER_NAME;
1264 Registration.FileType = DT_REG;
1265
1266 LxtCheckResult(LxtCheckDirectoryContents(BINFMT_MNT, &Registration, 1));
1267
1268 //
1269 // Remove the new entry via the status file.
1270 //
1271
1272 LxtCheckErrno(Fd = open(BINFMT_MNT "/status", O_RDWR));
1273 Size = strlen(BINFMT_REMOVE_STRING);
1274 LxtCheckErrno(Size = write(Fd, BINFMT_REMOVE_STRING, Size));
1275 LxtClose(Fd);
1276 Fd = -1;
1277
1278 //
1279 // Attempt to open the file (should fail);
1280 //
1281
1282 LxtCheckErrnoFailure(Fd = open(BINFMT_MNT "/" BINFMT_REGISTER_NAME, O_RDWR), ENOENT);
1283
1284 ErrorExit:
1285 if (Fd > 0)
1286 {
1287 LxtClose(Fd);
1288 }
1289
1290 return Result;
1291 }
1292
1293 int BinFmtInterpreterEntry(PLXT_ARGS Args)
1294
1295 /*++
1296
1297 Description:
1298
1299 This routine implements the entry point for the test binfmt interpreter.
1300
1301 Arguments:
1302
1303 Args - Supplies the command line arguments.
1304
1305 Return Value:
1306
1307 Returns 0 on success, -1 on failure.
1308
1309 --*/
1310
1311 {
1312
1313 int Index;
1314 int Result;
1315 printf("Pid = %d\n", getpid());
1316 for (Index = 0; Index < Args->Argc; Index += 1)
1317 {
1318 printf("Argv[%d]: %s\n", Index, Args->Argv[Index]);
1319 }
1320
1321 return 0;
1322 }