44
44
struct monitor_closure {
45
45
const struct command_details * details ;
46
46
struct sudo_event_base * evbase ;
47
- struct sudo_event * errpipe_event ;
47
+ struct sudo_event * errsock_event ;
48
48
struct sudo_event * backchannel_event ;
49
49
struct sudo_event * sigint_event ;
50
50
struct sudo_event * sigquit_event ;
@@ -263,18 +263,18 @@ mon_signal_cb(int signo, int what, void *v)
263
263
debug_return ;
264
264
}
265
265
266
- /* Note: this is basically the same as errpipe_cb() in exec_nopty.c */
266
+ /* This is essentially the same as errpipe_cb() in exec_nopty.c */
267
267
static void
268
- mon_errpipe_cb (int fd , int what , void * v )
268
+ mon_errsock_cb (int fd , int what , void * v )
269
269
{
270
270
struct monitor_closure * mc = v ;
271
271
ssize_t nread ;
272
272
int errval ;
273
- debug_decl (mon_errpipe_cb , SUDO_DEBUG_EXEC );
273
+ debug_decl (mon_errsock_cb , SUDO_DEBUG_EXEC );
274
274
275
275
/*
276
276
* Read errno from child or EOF when command is executed.
277
- * Note that the error pipe is *blocking*.
277
+ * Note that the error socket is *blocking*.
278
278
*/
279
279
nread = read (fd , & errval , sizeof (errval ));
280
280
switch (nread ) {
@@ -286,22 +286,22 @@ mon_errpipe_cb(int fd, int what, void *v)
286
286
mc -> cstat -> val = errno ;
287
287
}
288
288
sudo_debug_printf (SUDO_DEBUG_ERROR |SUDO_DEBUG_ERRNO ,
289
- "%s: failed to read error pipe " , __func__ );
289
+ "%s: failed to read error socket " , __func__ );
290
290
sudo_ev_loopbreak (mc -> evbase );
291
291
}
292
292
break ;
293
293
default :
294
294
if (nread == 0 ) {
295
- /* The error pipe closes when the command is executed. */
296
- sudo_debug_printf (SUDO_DEBUG_INFO , "EOF on error pipe " );
295
+ /* The error socket closes when the command is executed. */
296
+ sudo_debug_printf (SUDO_DEBUG_INFO , "EOF on error socket " );
297
297
} else {
298
298
/* Errno value when child is unable to execute command. */
299
299
sudo_debug_printf (SUDO_DEBUG_INFO , "errno from child: %s" ,
300
300
strerror (errval ));
301
301
mc -> cstat -> type = CMD_ERRNO ;
302
302
mc -> cstat -> val = errval ;
303
303
}
304
- sudo_ev_del (mc -> evbase , mc -> errpipe_event );
304
+ sudo_ev_del (mc -> evbase , mc -> errsock_event );
305
305
close (fd );
306
306
break ;
307
307
}
@@ -374,13 +374,25 @@ exec_cmnd_pty(struct command_details *details, sigset_t *mask,
374
374
375
375
/* Wait for parent to grant us the tty if we are foreground. */
376
376
if (foreground ) {
377
- struct timespec ts = { 0 , 1000 }; /* 1us */
378
- sudo_debug_printf (SUDO_DEBUG_DEBUG , "%s: waiting for controlling tty" ,
379
- __func__ );
380
- while (tcgetpgrp (io_fds [SFD_FOLLOWER ]) != self )
381
- nanosleep (& ts , NULL );
382
- sudo_debug_printf (SUDO_DEBUG_DEBUG , "%s: got controlling tty" ,
377
+ char ch ;
378
+
379
+ sudo_debug_printf (SUDO_DEBUG_INFO , "%s: waiting for controlling tty" ,
383
380
__func__ );
381
+ while (recv (errfd , & ch , sizeof (ch ), 0 ) == -1 ) {
382
+ if (errno != EINTR ) {
383
+ sudo_debug_printf (SUDO_DEBUG_ERROR |SUDO_DEBUG_ERRNO ,
384
+ "%s: unable to receive message from parent" , __func__ );
385
+ debug_return ;
386
+ }
387
+ }
388
+ if (tcgetpgrp (io_fds [SFD_FOLLOWER ]) == self ) {
389
+ sudo_debug_printf (SUDO_DEBUG_INFO , "%s: got controlling tty" ,
390
+ __func__ );
391
+ } else {
392
+ sudo_debug_printf (SUDO_DEBUG_ERROR ,
393
+ "%s: unable to get controlling tty" , __func__ );
394
+ foreground = false;
395
+ }
384
396
}
385
397
386
398
/* Done with the pty follower, don't leak it. */
@@ -418,11 +430,11 @@ fill_exec_closure_monitor(struct monitor_closure *mc,
418
430
sudo_fatalx (U_ ("%s: %s" ), __func__ , U_ ("unable to allocate memory" ));
419
431
420
432
/* Event for command status via errfd. */
421
- mc -> errpipe_event = sudo_ev_alloc (errfd ,
422
- SUDO_EV_READ |SUDO_EV_PERSIST , mon_errpipe_cb , mc );
423
- if (mc -> errpipe_event == NULL )
433
+ mc -> errsock_event = sudo_ev_alloc (errfd ,
434
+ SUDO_EV_READ |SUDO_EV_PERSIST , mon_errsock_cb , mc );
435
+ if (mc -> errsock_event == NULL )
424
436
sudo_fatalx (U_ ("%s: %s" ), __func__ , U_ ("unable to allocate memory" ));
425
- if (sudo_ev_add (mc -> evbase , mc -> errpipe_event , NULL , false) == -1 )
437
+ if (sudo_ev_add (mc -> evbase , mc -> errsock_event , NULL , false) == -1 )
426
438
sudo_fatal ("%s" , U_ ("unable to add event to queue" ));
427
439
428
440
/* Event for forwarded signals via backchannel. */
@@ -534,7 +546,7 @@ exec_monitor(struct command_details *details, sigset_t *oset,
534
546
struct monitor_closure mc = { 0 };
535
547
struct command_status cstat ;
536
548
struct sigaction sa ;
537
- int errpipe [2 ];
549
+ int errsock [2 ];
538
550
debug_decl (exec_monitor , SUDO_DEBUG_EXEC );
539
551
540
552
/* Close fds the monitor doesn't use. */
@@ -568,10 +580,14 @@ exec_monitor(struct command_details *details, sigset_t *oset,
568
580
}
569
581
570
582
/*
571
- * We use a pipe to get errno if execve(2) fails in the child.
583
+ * The child waits on the other end of a socketpair for the
584
+ * parent to set the controlling terminal. It also writes
585
+ * error to the socket on execve(2) failure.
572
586
*/
573
- if (pipe2 (errpipe , O_CLOEXEC ) != 0 ) {
574
- sudo_warn ("%s" , U_ ("unable to create pipe" ));
587
+ if (socketpair (PF_UNIX , SOCK_STREAM , 0 , errsock ) == -1 ||
588
+ fcntl (errsock [0 ], F_SETFD , FD_CLOEXEC ) == -1 ||
589
+ fcntl (errsock [1 ], F_SETFD , FD_CLOEXEC ) == -1 ) {
590
+ sudo_warn ("%s" , U_ ("unable to create sockets" ));
575
591
goto bad ;
576
592
}
577
593
@@ -608,15 +624,15 @@ exec_monitor(struct command_details *details, sigset_t *oset,
608
624
case 0 :
609
625
/* child */
610
626
close (backchannel );
611
- close (errpipe [0 ]);
627
+ close (errsock [0 ]);
612
628
/* setup tty and exec command */
613
- exec_cmnd_pty (details , oset , foreground , intercept_fd , errpipe [1 ]);
614
- if (write ( errpipe [1 ], & errno , sizeof (int )) == -1 )
629
+ exec_cmnd_pty (details , oset , foreground , intercept_fd , errsock [1 ]);
630
+ if (send ( errsock [1 ], & errno , sizeof (int ), 0 ) == -1 )
615
631
sudo_warn (U_ ("unable to execute %s" ), details -> command );
616
632
_exit (EXIT_FAILURE );
617
633
/* NOTREACHED */
618
634
}
619
- close (errpipe [1 ]);
635
+ close (errsock [1 ]);
620
636
if (intercept_fd != -1 )
621
637
close (intercept_fd );
622
638
@@ -635,7 +651,7 @@ exec_monitor(struct command_details *details, sigset_t *oset,
635
651
* Create new event base and register read events for the
636
652
* signal pipe, error pipe, and backchannel.
637
653
*/
638
- fill_exec_closure_monitor (& mc , details , & cstat , errpipe [0 ], backchannel );
654
+ fill_exec_closure_monitor (& mc , details , & cstat , errsock [0 ], backchannel );
639
655
640
656
/* Restore signal mask now that signal handlers are setup. */
641
657
sigprocmask (SIG_SETMASK , oset , NULL );
@@ -659,6 +675,9 @@ exec_monitor(struct command_details *details, sigset_t *oset,
659
675
"%s: unable to set foreground pgrp to %d (command)" ,
660
676
__func__ , (int )mc .cmnd_pgrp );
661
677
}
678
+ /* Tell the child to go ahead now that it is the foreground pgrp. */
679
+ while (send (errsock [0 ], "" , 1 , 0 ) == -1 && errno == EINTR )
680
+ continue ;
662
681
}
663
682
664
683
/*
0 commit comments