master
c 1,161 lines 26.9 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 get_set_id.c
8
9 Abstract:
10
11 This file is a test for the get*id and set*id system calls.
12
13 --*/
14
15 #include "lxtcommon.h"
16 #include "unittests.h"
17 #include <stdio.h>
18 #include <errno.h>
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <sys/syscall.h>
22 #include <sys/wait.h>
23 #include <sys/un.h>
24 #include <limits.h>
25
26 #define LXT_NAME "get_set_id"
27
28 #if !defined(__amd64__) && !defined(__aarch64__)
29
30 #define __NR_getuid16 24
31 #define __NR_geteuid16 49
32 #define __NR_getgid16 47
33 #define __NR_getegid16 50
34 #define __NR_getresuid16 165
35 #define __NR_getresgid16 171
36
37 int GetSetId16Bit(PLXT_ARGS Args);
38
39 #endif
40
41 typedef unsigned short USHORT;
42
43 //
44 // uid16_t and gid16_t are unsigned 16-bit integers.
45 //
46
47 typedef USHORT uid16_t;
48
49 #define MAX_UID16_T USHRT_MAX
50
51 typedef USHORT gid16_t;
52
53 #define MAX_GID16_T USHRT_MAX
54
55 int GetSetId0(PLXT_ARGS Args);
56
57 int GetSetId1(PLXT_ARGS Args);
58
59 int GetSetIdParseArgs(int Argc, char* Argv[], LXT_ARGS* Args);
60
61 int GetSetPgid(PLXT_ARGS Args);
62
63 int GetSetPgidChildProcess(void);
64
65 int GetSetPgidChildProcess2(pid_t GroupId);
66
67 int GetSetPgidExecve(PLXT_ARGS Args);
68
69 int GetSetPgidExecveChild(void);
70
71 int GetSetSid(PLXT_ARGS Args);
72
73 //
74 // Global constants
75 //
76
77 static const LXT_VARIATION g_LxtVariations[] = {
78 {"GetSetId Basic", GetSetId0},
79 {"GetResuid-GetResgid Basic", GetSetId1},
80
81 #if !defined(__amd64__) && !defined(__aarch64__)
82 {"GetSetId 16-bit versions", GetSetId16Bit},
83 #endif
84 {"GetSetPgid Basic", GetSetPgid},
85 {"GetSetPgid with execve", GetSetPgidExecve},
86 {"GetSetSid Basic", GetSetSid}};
87
88 static const char* g_SocketPath = "/data/test/lxt_get_set_id_sock";
89
90 int GetSetIdTestEntry(int Argc, char* Argv[])
91
92 /*++
93
94 Routine Description:
95
96 This routine main entry point for the test for get*id,set*id system call.
97
98 Arguments:
99
100 Argc - Supplies the number of command line arguments.
101
102 Argv - Supplies the command line arguments.
103
104 Return Value:
105
106 Returns 0 on success, -1 on failure.
107
108 --*/
109
110 {
111
112 LXT_ARGS Args;
113 int Result;
114
115 LxtCheckResult(GetSetIdParseArgs(Argc, Argv, &Args));
116 ErrorExit:
117 LxtUninitialize();
118 return !LXT_SUCCESS(Result);
119 }
120
121 int GetSetId0(PLXT_ARGS Args)
122
123 /*++
124
125 Routine Description:
126
127 This routine validates the various get*id and set*id system
128 calls.
129
130 Arguments:
131
132 Args - Supplies the command line arguments.
133
134 Return Value:
135
136 Returns 0 on success, -1 on failure.
137
138 --*/
139
140 {
141
142 gid_t Egid;
143 gid_t EgidFromGetResgid;
144 uid_t Euid;
145 uid_t EuidFromGetResuid;
146 gid_t Gid;
147 gid_t GidFromGetResgid;
148 pid_t Pgid;
149 pid_t Pgid0;
150 pid_t Pid;
151 pid_t Ppid;
152 int Result;
153 uid_t SuidFromGetResuid;
154 gid_t SgidFromGetResgid;
155 pid_t Tid;
156 uid_t Uid;
157 uid_t UidFromGetResuid;
158
159 Pid = getpid();
160 Ppid = getppid();
161 Gid = getgid();
162 Egid = getegid();
163 Uid = getuid();
164 Euid = geteuid();
165 Tid = gettid();
166 LxtCheckResult((Pgid0 = getpgid(0)));
167 LxtCheckResult((Pgid = getpgid(Pid)));
168 LxtCheckErrnoFailure(getpgid(-1), ESRCH);
169 LxtCheckResult(getresuid(&UidFromGetResuid, &EuidFromGetResuid, &SuidFromGetResuid));
170
171 LxtCheckResult(getresgid(&GidFromGetResgid, &EgidFromGetResgid, &SgidFromGetResgid));
172
173 LxtLogInfo(
174 "ID Details. Pid:%d, Ppid:%d, Gid:%u, Egid:%u, Uid:%u, "
175 "Euid:%u, Tid:%u, Pgid:%d, Uid From GetResuid:%u, "
176 "Euid From GetResuid:%u, Suid From GetResuid:%u, Gid From "
177 "GetResgid:%u, Egid From GetResgid:%u, Sgid From GetResgid:%u",
178 Pid,
179 Ppid,
180 Gid,
181 Egid,
182 Uid,
183 Euid,
184 Tid,
185 Pgid,
186 UidFromGetResuid,
187 EuidFromGetResuid,
188 SuidFromGetResuid,
189 GidFromGetResgid,
190 EgidFromGetResgid,
191 SgidFromGetResgid);
192
193 //
194 // getpgid(Pid) == getpgid(0)
195 //
196
197 if (Pgid != Pgid0)
198 {
199 LxtLogError(
200 "getpgid(<self>) == getpgid(0). getpgid(<self>):%d, "
201 "getpgid(0): %d",
202 Pgid,
203 Pgid0);
204 Result = LXT_RESULT_FAILURE;
205 goto ErrorExit;
206 }
207
208 //
209 // For a single threaded process, Thread ID == Process ID
210 //
211
212 if (Pid != Tid)
213 {
214 LxtLogError(
215 "For a single threaded process, Process ID == Thread ID. "
216 "Process ID:%u, Thread ID:%u",
217 Pid,
218 Tid);
219 Result = LXT_RESULT_FAILURE;
220 goto ErrorExit;
221 }
222
223 //
224 // ID's from get*id and getresuid/getresgid should match
225 //
226
227 if (Uid != UidFromGetResuid)
228 {
229 LxtLogError(
230 "UID from getuid and getresuid do not match. "
231 "uid from getuid:%u, uid from getresuid:%u",
232 Uid,
233 UidFromGetResuid);
234 Result = LXT_RESULT_FAILURE;
235 goto ErrorExit;
236 }
237
238 if (Euid != EuidFromGetResuid)
239 {
240 LxtLogError(
241 "EUID from geteuid and getresuid do not match. "
242 "euid from getuid:%u, euid from getresuid:%u",
243 Euid,
244 EuidFromGetResuid);
245 Result = LXT_RESULT_FAILURE;
246 goto ErrorExit;
247 }
248
249 if (Gid != GidFromGetResgid)
250 {
251 LxtLogError(
252 "GID from getgid and getresgid do not match. "
253 "gid from getgid:%u, gid from getresgid:%u",
254 Gid,
255 GidFromGetResgid);
256 Result = LXT_RESULT_FAILURE;
257 goto ErrorExit;
258 }
259
260 if ((Egid != EgidFromGetResgid))
261 {
262 LxtLogError(
263 "EGID from getegid and getresgid do not match. "
264 "egid from getegid:%u, egid from getresgid:%u",
265 Egid,
266 EgidFromGetResgid);
267 Result = LXT_RESULT_FAILURE;
268 goto ErrorExit;
269 }
270
271 Result = LXT_RESULT_SUCCESS;
272
273 ErrorExit:
274 return Result;
275 }
276
277 int GetSetId1(PLXT_ARGS Args)
278
279 /*++
280
281 Routine Description:
282
283 This routine validates the GetResuid/GetResgid system calls.
284
285 Arguments:
286
287 Args - Supplies the command line arguments.
288
289 Return Value:
290
291 Returns 0 on success, -1 on failure.
292
293 --*/
294
295 {
296
297 gid_t EgidFromGetResgid;
298 uid_t EuidFromGetResuid;
299 gid_t GidFromGetResgid;
300 int Result;
301 uid_t SuidFromGetResuid;
302 gid_t SgidFromGetResgid;
303 uid_t UidFromGetResuid;
304
305 LxtCheckErrnoFailure(getresuid(NULL, NULL, NULL), EFAULT);
306
307 LxtCheckErrnoFailure(getresuid(&UidFromGetResuid, NULL, NULL), EFAULT);
308
309 LxtCheckErrnoFailure(getresuid(NULL, &EuidFromGetResuid, &SuidFromGetResuid), EFAULT);
310
311 LxtCheckResult(getresuid(&UidFromGetResuid, &EuidFromGetResuid, &SuidFromGetResuid));
312 LxtCheckErrnoFailure(getresgid(NULL, NULL, NULL), EFAULT);
313
314 LxtCheckErrnoFailure(getresgid(&GidFromGetResgid, NULL, NULL), EFAULT);
315
316 LxtCheckErrnoFailure(getresgid(NULL, &EgidFromGetResgid, &SgidFromGetResgid), EFAULT);
317
318 LxtCheckResult(getresgid(&GidFromGetResgid, &EgidFromGetResgid, &SgidFromGetResgid));
319
320 Result = LXT_RESULT_SUCCESS;
321
322 ErrorExit:
323 return Result;
324 }
325
326 #if !defined(__amd64__) && !defined(__aarch64__)
327
328 int GetSetId16Bit(PLXT_ARGS Args)
329
330 /*++
331
332 Routine Description:
333
334 This routine validates the various 16-bit versions of the
335 get*id and set*id system calls.
336
337 Arguments:
338
339 Args - Supplies the command line arguments.
340
341 Return Value:
342
343 Returns 0 on success, -1 on failure.
344
345 --*/
346
347 {
348
349 gid_t Egid;
350 gid16_t Egid16;
351 gid16_t EgidFromGetResgid16;
352 uid_t Euid;
353 uid16_t Euid16;
354 uid16_t EuidFromGetResuid16;
355 gid_t Gid;
356 gid16_t Gid16;
357 gid16_t GidFromGetResgid16;
358 int Result;
359 uid16_t SuidFromGetResuid16;
360 gid16_t SgidFromGetResgid16;
361 uid_t Uid;
362 uid16_t Uid16;
363 uid16_t UidFromGetResuid16;
364
365 Gid = getgid();
366 Gid16 = 0;
367 Egid = getegid();
368 Uid = getuid();
369 Uid16 = 0;
370 Euid = geteuid();
371
372 LxtLogInfo("UID and GID Details. Gid:%d, Egid:%d, Uid:%u, Euid:%u", Gid, Egid, Uid, Euid);
373
374 //
375 // Before calling the 16-bit versions, make sure the IDs are
376 // within the range.
377 //
378
379 if (Gid <= MAX_GID16_T)
380 {
381 Gid16 = syscall(__NR_getgid16);
382 if (Gid != Gid16)
383 {
384 LxtLogError(
385 "GID from getgid and getgid16 do not match. "
386 "gid from getgid:%d, gid from getgid16:%d",
387 Gid,
388 Gid16);
389 Result = LXT_RESULT_FAILURE;
390 goto ErrorExit;
391 }
392 }
393
394 if (Egid <= MAX_GID16_T)
395 {
396 Egid16 = syscall(__NR_getegid16);
397 if (Egid != Egid16)
398 {
399 LxtLogError(
400 "EGID from getegid and getegid16 do not match. "
401 "egid from getegid:%d, egid from getegid16:%d",
402 Egid,
403 Egid16);
404 Result = LXT_RESULT_FAILURE;
405 goto ErrorExit;
406 }
407 }
408
409 if ((Gid <= MAX_GID16_T) && (Egid <= MAX_GID16_T))
410 {
411 LxtCheckResult(syscall(__NR_getresgid16, &GidFromGetResgid16, &EgidFromGetResgid16, &SgidFromGetResgid16));
412
413 LxtLogInfo("SGID16:%d", SgidFromGetResgid16);
414
415 if (Gid16 != GidFromGetResgid16)
416 {
417 LxtLogError(
418 "GID from getgid16 and getresgid16 do not match. "
419 "gid from getgid16:%d, gid from getresgid16:%d",
420 Gid16,
421 GidFromGetResgid16);
422 Result = LXT_RESULT_FAILURE;
423 goto ErrorExit;
424 }
425
426 if ((Egid16 != EgidFromGetResgid16))
427 {
428 LxtLogError(
429 "EGID from getegid16 and getresgid16 do not match. "
430 "egid from getegid16:%d, egid from getresgid16:%d",
431 Egid16,
432 EgidFromGetResgid16);
433 Result = LXT_RESULT_FAILURE;
434 goto ErrorExit;
435 }
436
437 LxtCheckErrnoFailure(syscall(__NR_getresgid16, NULL, NULL, NULL), EFAULT);
438
439 LxtCheckErrnoFailure(syscall(__NR_getresgid16, &GidFromGetResgid16, NULL, NULL), EFAULT);
440
441 LxtCheckErrnoFailure(syscall(__NR_getresgid16, NULL, &EgidFromGetResgid16, &SgidFromGetResgid16), EFAULT);
442 }
443
444 if (Uid <= MAX_UID16_T)
445 {
446 Uid16 = syscall(__NR_getuid16);
447 if (Uid != Uid16)
448 {
449 LxtLogError(
450 "UID from getuid and getuid16 do not match. "
451 "uid from getuid:%d, uid from getuid16:%d",
452 Uid,
453 Uid16);
454 Result = LXT_RESULT_FAILURE;
455 goto ErrorExit;
456 }
457 }
458
459 if (Euid <= MAX_UID16_T)
460 {
461 Euid16 = syscall(__NR_geteuid16);
462 if (Euid != Euid16)
463 {
464 LxtLogError(
465 "EUID from geteuid and geteuid16 do not match. "
466 "egid from geteuid:%d, egid from geteuid16:%d",
467 Euid,
468 Euid16);
469 Result = LXT_RESULT_FAILURE;
470 goto ErrorExit;
471 }
472 }
473
474 if ((Uid <= MAX_UID16_T) && (Euid <= MAX_UID16_T))
475 {
476 LxtCheckResult(syscall(__NR_getresuid16, &UidFromGetResuid16, &EuidFromGetResuid16, &SuidFromGetResuid16));
477
478 LxtLogInfo("SUID16:%d", SuidFromGetResuid16);
479
480 if (Uid16 != UidFromGetResuid16)
481 {
482 LxtLogError(
483 "UID from getuid16 and getresuid16 do not match. "
484 "uid from getuid16:%d, uid from getresuid16:%d",
485 Uid16,
486 UidFromGetResuid16);
487 Result = LXT_RESULT_FAILURE;
488 goto ErrorExit;
489 }
490
491 if (Euid16 != EuidFromGetResuid16)
492 {
493 LxtLogError(
494 "EUID from geteuid16 and getresuid16 do not match. "
495 "euid from getuid16:%d, euid from getresuid16:%d",
496 Euid16,
497 EuidFromGetResuid16);
498 Result = LXT_RESULT_FAILURE;
499 goto ErrorExit;
500 }
501
502 LxtCheckErrnoFailure(syscall(__NR_getresuid16, NULL, NULL, NULL), EFAULT);
503
504 LxtCheckErrnoFailure(syscall(__NR_getresuid16, &UidFromGetResuid16, NULL, NULL), EFAULT);
505
506 LxtCheckErrnoFailure(syscall(__NR_getresuid16, NULL, &EuidFromGetResuid16, &SuidFromGetResuid16), EFAULT);
507 }
508
509 Result = LXT_RESULT_SUCCESS;
510
511 ErrorExit:
512 return Result;
513 }
514
515 #endif
516
517 int GetSetIdParseArgs(int Argc, char* Argv[], LXT_ARGS* Args)
518
519 /*++
520
521 Routine Description:
522
523 This routine parses command line arguments for the get_set_id tests.
524
525 Arguments:
526
527 Argc - Supplies the number of arguments.
528
529 Argv - Supplies an array of arguments.
530
531 Return Value:
532
533 Returns 0 on success, -1 on failure.
534
535 --*/
536
537 {
538
539 int ArgvIndex;
540 int Result;
541 int ValidArguments;
542
543 Result = LXT_RESULT_FAILURE;
544 ValidArguments = 0;
545
546 if (Argc < 1)
547 {
548 goto ErrorExit;
549 }
550
551 for (ArgvIndex = 1; ArgvIndex < Argc; ++ArgvIndex)
552 {
553 if (Argv[ArgvIndex][0] != '-')
554 {
555 printf("Unexpected character %s", Argv[ArgvIndex]);
556 goto ErrorExit;
557 }
558
559 switch (Argv[ArgvIndex][1])
560 {
561 case 'c':
562
563 //
564 // Run the setpgid execve test child
565 //
566
567 ValidArguments = 1;
568 Result = GetSetPgidExecveChild();
569 goto ErrorExit;
570
571 case 'v':
572
573 //
574 // This was already taken care of by LxtInitialize.
575 //
576
577 ++ArgvIndex;
578
579 break;
580
581 default:
582 goto ErrorExit;
583 }
584 }
585
586 //
587 // If -c was not specified, just run the tests
588 //
589
590 ValidArguments = 1;
591 LxtCheckResult(LxtInitialize(Argc, Argv, Args, LXT_NAME));
592 LxtCheckResult(LxtRunVariations(Args, g_LxtVariations, LXT_COUNT_OF(g_LxtVariations)));
593
594 ErrorExit:
595 if (ValidArguments == 0)
596 {
597 printf("\nuse: get_set_id <One of the below arguments>");
598 printf("\t-c : Run getsetpgid execve test child (don't use directly)");
599 }
600
601 return Result;
602 }
603
604 int GetSetPgid(PLXT_ARGS Args)
605
606 /*++
607
608 Routine Description:
609
610 This routine validates the getpgid and setpgid system calls.
611
612 Arguments:
613
614 Args - Supplies the command line arguments.
615
616 Return Value:
617
618 Returns 0 on success, -1 on failure.
619
620 --*/
621
622 {
623
624 const int Processes = 2;
625
626 pid_t Child;
627 pid_t GroupId;
628 pid_t NewGroup;
629 int Process;
630 pid_t ProcessIds[2];
631 int Result;
632 int Status;
633
634 //
635 // Check that a child process initially inherits our process group ID.
636 //
637
638 LxtCheckErrno(Child = fork());
639 if (Child == 0)
640 {
641 _exit(GetSetPgidChildProcess());
642 }
643
644 LxtCheckResult(LxtWaitPidPoll(Child, 0));
645
646 //
647 // Create two processes; the first will be the group leader and the second
648 // will use the group id of the first. The method used here reflects how
649 // job control shells create groups for pipelines.
650 //
651
652 GroupId = 0;
653 for (Process = 0; Process < Processes; Process += 1)
654 {
655 LxtCheckErrno(Child = fork());
656 ProcessIds[Process] = Child;
657 if (Child == 0)
658 {
659 _exit(GetSetPgidChildProcess2(GroupId));
660 }
661
662 if (GroupId == 0)
663 {
664 GroupId = Child;
665 }
666
667 LxtCheckErrnoZeroSuccess(setpgid(Child, GroupId));
668 LxtCheckErrno(NewGroup = getpgid(Child));
669 if (NewGroup != GroupId)
670 {
671 LxtLogError(
672 "getpgid() return value does not match the "
673 "value set by setpgid. Expected: %i; actual: %i",
674 GroupId,
675 NewGroup);
676
677 Result = LXT_RESULT_FAILURE;
678 goto ErrorExit;
679 }
680 }
681
682 for (Process = 0; Process < Processes; Process += 1)
683 {
684 LxtCheckResult(LxtWaitPidPoll(ProcessIds[Process], 0));
685 }
686
687 //
688 // After the child processes were waited on, the process group is no longer
689 // valid, nor are the children pids. There is currently a race condition
690 // that causes waitpid to return before the process group is cleaned up
691 // so sleep before trying this.
692 //
693
694 sleep(1);
695 LxtCheckErrnoFailure(setpgid(0, GroupId), EPERM);
696 LxtCheckErrnoFailure(setpgid(ProcessIds[0], 0), ESRCH);
697 LxtCheckErrnoFailure(getpgid(ProcessIds[0]), ESRCH);
698
699 //
700 // Getpgid for non-child process should succeed, setpgid should fail
701 //
702
703 LxtCheckErrno(getpgid(getppid()));
704 LxtCheckErrnoFailure(setpgid(getppid(), 0), ESRCH);
705
706 //
707 // Cannot change process group of session leader.
708 //
709
710 LxtCheckResult(LxtSignalBlock(SIGUSR1));
711 LxtCheckErrno(Child = fork());
712 if (Child == 0)
713 {
714 LxtCheckErrno(setsid());
715 LxtCheckErrnoFailure(setpgid(0, getppid()), EPERM);
716 LxtCheckErrnoFailure(setpgid(0, 0), EPERM);
717 LxtCheckErrnoZeroSuccess(kill(getppid(), SIGUSR1));
718 LxtCheckResult(LxtSignalWaitBlocked(SIGUSR1, getppid(), 2));
719 _exit(LXT_RESULT_SUCCESS);
720 }
721
722 LxtCheckResult(LxtSignalWaitBlocked(SIGUSR1, Child, 2));
723 LxtCheckErrnoFailure(setpgid(Child, 0), EPERM);
724 LxtCheckErrnoFailure(setpgid(Child, getpgid(0)), EPERM);
725
726 //
727 // Cannot change to process group which is in a different session.
728 //
729
730 LxtCheckErrnoFailure(setpgid(0, Child), EPERM);
731
732 //
733 // Tell the child to exit.
734 //
735
736 LxtCheckErrnoZeroSuccess(kill(Child, SIGUSR1));
737 LxtCheckResult(LxtWaitPidPoll(Child, 0));
738
739 //
740 // Bogus pid and pgid values. The fact that setpgid returns different
741 // errors for a negative pid if pgid==0 is consistent with Linux.
742 //
743
744 LxtCheckErrnoFailure(getpgid(-1), ESRCH);
745 LxtCheckErrnoFailure(setpgid(-1, 1), ESRCH);
746 LxtCheckErrnoFailure(setpgid(-1, 0), EINVAL);
747 LxtCheckErrnoFailure(setpgid(0, -1), EINVAL);
748
749 ErrorExit:
750 return Result;
751 }
752
753 int GetSetPgidChildProcess(void)
754
755 /*++
756
757 Routine Description:
758
759 This routine runs the child process for GetSetPgid that checks its pgid.
760
761 Arguments:
762
763 None.
764
765 Return Value:
766
767 Returns 0 on success, -1 on failure.
768
769 --*/
770
771 {
772
773 pid_t Parent;
774 pid_t ParentGroupId;
775 pid_t GroupId;
776 int Result;
777
778 Parent = getppid();
779 LxtCheckErrno(ParentGroupId = getpgid(Parent));
780 LxtCheckErrno(GroupId = getpgid(0));
781 LxtLogInfo("Process %i pgid: %i, parent %i pgid: %i", getpid(), GroupId, Parent, ParentGroupId);
782
783 Result = LXT_RESULT_FAILURE;
784 if (GroupId == 0)
785 {
786 LxtLogError("Group ID should never be zero.");
787 goto ErrorExit;
788 }
789
790 if (GroupId != ParentGroupId)
791 {
792 LxtLogError("Pgid %i did not match parent pgid %i", GroupId, ParentGroupId);
793
794 goto ErrorExit;
795 }
796
797 Result = LXT_RESULT_SUCCESS;
798
799 ErrorExit:
800 return Result;
801 }
802
803 int GetSetPgidChildProcess2(pid_t GroupId)
804
805 /*++
806
807 Routine Description:
808
809 This routine runs the child processes for GetSetPgid that set their pgid.
810
811 Arguments:
812
813 GroupId - The process group ID for this child process (0 if this is the
814 new leader)
815
816 Return Value:
817
818 Returns 0 on success, -1 on failure.
819
820 --*/
821
822 {
823
824 int NewGroup;
825 int Pid;
826 int Result;
827 LxtCheckErrnoZeroSuccess(setpgid(0, GroupId));
828
829 //
830 // If we were passed 0, the expected result should match the process ID.
831 //
832
833 Pid = getpid();
834 if (GroupId == 0)
835 {
836 GroupId = Pid;
837 }
838
839 LxtCheckErrno(NewGroup = getpgid(0));
840 if (NewGroup != GroupId)
841 {
842 LxtLogError(
843 "getpgid(0) return value does not match the value set by "
844 "setpgid. Expected: %i; actual: %i",
845 GroupId,
846 NewGroup);
847
848 Result = LXT_RESULT_FAILURE;
849 goto ErrorExit;
850 }
851
852 LxtLogInfo("Process %i pgid: %i", Pid, NewGroup);
853
854 LxtCheckErrno(NewGroup = getpgid(Pid));
855 if (NewGroup != GroupId)
856 {
857 LxtLogError(
858 "getpgid(getpid()) return value does not match the value "
859 "set by setpgid. Expected: %i; actual: %i",
860 GroupId,
861 NewGroup);
862
863 Result = LXT_RESULT_FAILURE;
864 goto ErrorExit;
865 }
866
867 //
868 // The sleep is to keep the group alive until the second process
869 // runs. Remove it once zombie processes are implemented.
870 //
871
872 sleep(1);
873
874 Result = LXT_RESULT_SUCCESS;
875
876 ErrorExit:
877 return Result;
878 }
879
880 int GetSetPgidExecve(PLXT_ARGS Args)
881
882 /*++
883
884 Routine Description:
885
886 This routine checks whether setpgid returns the correct failure if it is
887 called on a process that has already called execve.
888
889 Arguments:
890
891 Args - Supplies the command line arguments.
892
893 Return Value:
894
895 Returns 0 on success, -1 on failure.
896
897 --*/
898
899 {
900
901 struct sockaddr_un Address;
902 int ClientSocket;
903 char* Argv[4];
904 char* Envp[1];
905 int Result;
906 int ServerSocket;
907 int Status;
908 int Child;
909
910 ClientSocket = -1;
911 Child = -1;
912
913 //
914 // To make sure we call setpgid after the child process runs execve and
915 // before it exits, we use a unix socket to let the child signal us when
916 // it's running, and then we signal the child to exit after the test.
917 //
918
919 LxtCheckErrno(ServerSocket = socket(AF_UNIX, SOCK_STREAM, 0));
920
921 //
922 // Remove the path name in case it exists from a failed prior test run;
923 // ignore errors.
924 //
925
926 unlink(g_SocketPath);
927
928 //
929 // Bind to the address and start listening
930 //
931
932 memset(&Address, 0, sizeof(Address));
933 Address.sun_family = AF_UNIX;
934 strncpy(Address.sun_path, g_SocketPath, sizeof(Address.sun_path) - 1);
935 Address.sun_path[sizeof(Address.sun_path) - 1] = 0;
936 LxtCheckErrnoZeroSuccess(bind(ServerSocket, (struct sockaddr*)&Address, sizeof(Address)));
937 LxtCheckErrnoZeroSuccess(listen(ServerSocket, 1));
938
939 //
940 // Start the child process.
941 //
942
943 LxtCheckErrno(Child = fork());
944 if (Child == 0)
945 {
946 Argv[0] = WSL_UNIT_TEST_BINARY; // adhere to new single test binary design
947 Argv[1] = Args->Argv[0];
948 Argv[2] = "-c";
949 Argv[3] = Envp[0] = NULL;
950 execve(Argv[0], Argv, Envp);
951 LxtLogError("Execve failed, errno: %d (%s)", errno, strerror(errno));
952 _exit(LXT_RESULT_FAILURE);
953 }
954
955 //
956 // Wait for the client to tell us it's running; this guarantees we
957 // call setpgid after the execve call.
958 //
959
960 LxtCheckErrno(ClientSocket = accept(ServerSocket, NULL, NULL));
961 LxtCheckResult(LxtReceiveMessage(ClientSocket, "execve"));
962
963 //
964 // The child is now running inside the binary loaded by execve, so we
965 // can try to call setpgid, which should fail with EACCES.
966 //
967
968 LxtCheckErrnoFailure(setpgid(Child, 0), EACCES);
969
970 //
971 // Tell the client it can exit.
972 //
973
974 LxtCheckResult(LxtSendMessage(ClientSocket, "exit")) LxtCheckResult(LxtWaitPidPoll(Child, 0));
975
976 ErrorExit:
977 if (ClientSocket >= 0)
978 {
979 close(ClientSocket);
980 }
981
982 if (ServerSocket >= 0)
983 {
984 close(ServerSocket);
985 }
986
987 unlink(g_SocketPath);
988
989 return Result;
990 }
991
992 int GetSetPgidExecveChild(void)
993
994 /*++
995
996 Routine Description:
997
998 This routine runs the child process for GetSetPgidExecve.
999
1000 Arguments:
1001
1002 None.
1003
1004 Return Value:
1005
1006 Returns 0 on success, -1 on failure.
1007
1008 --*/
1009
1010 {
1011
1012 struct sockaddr_un Address;
1013 int ClientSocket;
1014 int Result;
1015
1016 LxtLogInfo("Child executable running, pid = %i", getpid());
1017 LxtCheckErrno(ClientSocket = socket(AF_UNIX, SOCK_STREAM, 0));
1018
1019 //
1020 // Connect to the parent process via AF_UNIX socket.
1021 //
1022
1023 memset(&Address, 0, sizeof(Address));
1024 Address.sun_family = AF_UNIX;
1025 strncpy(Address.sun_path, g_SocketPath, sizeof(Address.sun_path) - 1);
1026 Address.sun_path[sizeof(Address.sun_path) - 1] = 0;
1027 LxtCheckErrnoZeroSuccess(connect(ClientSocket, (struct sockaddr*)&Address, sizeof(Address)));
1028
1029 //
1030 // Tell the parent that the process is running inside the execve'd binary.
1031 //
1032
1033 LxtCheckResult(LxtSendMessage(ClientSocket, "execve"));
1034
1035 //
1036 // Wait for the parent to tell this process it can exit so it has the
1037 // chance to call setpgid.
1038 //
1039
1040 LxtCheckResult(LxtReceiveMessage(ClientSocket, "exit"));
1041
1042 //
1043 // This process should be able to change its own process group.
1044 //
1045
1046 LxtCheckErrnoZeroSuccess(setpgid(0, 0));
1047 LxtLogInfo("Child executable finished");
1048 Result = LXT_RESULT_SUCCESS;
1049
1050 ErrorExit:
1051 if (ClientSocket >= 0)
1052 {
1053 close(ClientSocket);
1054 }
1055
1056 return Result;
1057 }
1058
1059 int GetSetSid(PLXT_ARGS Args)
1060
1061 /*++
1062
1063 Routine Description:
1064
1065 This routine tests the getsid() and setsid() system calls..
1066
1067 Arguments:
1068
1069 Args - Supplies the command line arguments.
1070
1071 Return Value:
1072
1073 Returns 0 on success, -1 on failure.
1074
1075 --*/
1076
1077 {
1078
1079 pid_t ChildPid;
1080 pid_t ParentSid;
1081 int Result;
1082 pid_t Sid;
1083
1084 LxtCheckResult(LxtSignalBlock(SIGUSR1));
1085 LxtCheckErrno(ChildPid = fork());
1086 if (ChildPid == 0)
1087 {
1088
1089 //
1090 // Initial values.
1091 //
1092
1093 LxtCheckErrno(ParentSid = getsid(getppid()));
1094 LxtCheckNotEqual(ParentSid, 0, "%d") LxtCheckErrno(Sid = getsid(0));
1095 LxtCheckEqual(ParentSid, Sid, "%d");
1096 LxtCheckErrno(Sid = getsid(getpid()));
1097 LxtCheckEqual(ParentSid, Sid, "%d");
1098
1099 //
1100 // Create a new session.
1101 //
1102
1103 LxtCheckErrno(Sid = setsid());
1104 LxtCheckNotEqual(ParentSid, Sid, "%d");
1105 LxtCheckEqual(Sid, getpid(), "%d");
1106 LxtCheckEqual(Sid, getpgid(0), "%d");
1107
1108 //
1109 // Tell the parent that a new session was created.
1110 //
1111
1112 LxtCheckErrnoZeroSuccess(kill(getppid(), SIGUSR1));
1113
1114 //
1115 // Wait for the signal to exit.
1116 //
1117
1118 LxtCheckResult(LxtSignalWaitBlocked(SIGUSR1, getppid(), 2));
1119 _exit(LXT_RESULT_SUCCESS);
1120 }
1121
1122 //
1123 // Wait until the child has created the session.
1124 //
1125
1126 LxtCheckResult(LxtSignalWaitBlocked(SIGUSR1, ChildPid, 2));
1127 LxtCheckErrno(Sid = getsid(ChildPid));
1128 LxtCheckErrno(ParentSid = getsid(0));
1129 LxtCheckNotEqual(ParentSid, Sid, "%d");
1130 LxtCheckEqual(Sid, ChildPid, "%d");
1131 LxtCheckEqual(Sid, getpgid(ChildPid), "%d");
1132
1133 //
1134 // Tell the child to exit.
1135 //
1136
1137 LxtCheckErrnoZeroSuccess(kill(ChildPid, SIGUSR1));
1138 LxtWaitPidPoll(ChildPid, 0);
1139
1140 //
1141 // If the process is a process group leader, it can't create a new
1142 // session. The test is already the process group leader if it is launched
1143 // from the shell but not from all test environments.
1144 //
1145
1146 if (getpid() != getpgid(0))
1147 {
1148 LxtCheckResult(setpgid(getpid(), 0));
1149 }
1150
1151 LxtCheckErrnoFailure(setsid(), EPERM);
1152
1153 //
1154 // Getsid with invalid arguments.
1155 //
1156
1157 LxtCheckErrnoFailure(getsid(-1), ESRCH);
1158
1159 ErrorExit:
1160 return Result;
1161 }