Skip to content

Commit

Permalink
[pty] Split chfunc into functions in steps
Browse files Browse the repository at this point in the history
- start a new session
- obtain the new controlling terminal
- drop privileges
- finally, `exec`
  • Loading branch information
nobu committed Apr 9, 2024
1 parent 88355da commit 0bc7182
Showing 1 changed file with 42 additions and 11 deletions.
53 changes: 42 additions & 11 deletions ext/pty/pty.c
Expand Up @@ -92,28 +92,48 @@ struct pty_info {

static void getDevice(int*, int*, char [DEVICELEN], int);

static int start_new_session(char *errbuf, size_t errbuf_len);
static int obtain_ctty(int master, int slave, const char *slavename, char *errbuf, size_t errbuf_len);
static int drop_privilige(char *errbuf, size_t errbuf_len);

struct child_info {
int master, slave;
char *slavename;
const char *slavename;
VALUE execarg_obj;
struct rb_execarg *eargp;
};

static int
chfunc(void *data, char *errbuf, size_t errbuf_len)
{
struct child_info *carg = data;
const struct child_info *carg = data;
int master = carg->master;
int slave = carg->slave;
const char *slavename = carg->slavename;

if (start_new_session(errbuf, errbuf_len))
return -1;

if (obtain_ctty(master, slave, slavename, errbuf, errbuf_len))
return -1;

if (drop_privilige(errbuf, errbuf_len))
return -1;

return rb_exec_async_signal_safe(carg->eargp, errbuf, errbuf_len);
}

#define ERROR_EXIT(str) do { \
strlcpy(errbuf, (str), errbuf_len); \
return -1; \
} while (0)

/*
* Set free from process group and controlling terminal
*/
/*
* Set free from process group and controlling terminal
*/
static int
start_new_session(char *errbuf, size_t errbuf_len)
{
#ifdef HAVE_SETSID
(void) setsid();
#else /* HAS_SETSID */
Expand All @@ -135,17 +155,22 @@ chfunc(void *data, char *errbuf, size_t errbuf_len)
# endif /* SETPGRP_VOID */
# endif /* HAVE_SETPGRP */
#endif /* HAS_SETSID */
return 0;
}

/*
* obtain new controlling terminal
*/
/*
* obtain new controlling terminal
*/
static int
obtain_ctty(int master, int slave, const char *slavename, char *errbuf, size_t errbuf_len)
{
#if defined(TIOCSCTTY)
close(master);
(void) ioctl(slave, TIOCSCTTY, (char *)0);
/* errors ignored for sun */
#else
close(slave);
slave = rb_cloexec_open(carg->slavename, O_RDWR, 0);
slave = rb_cloexec_open(slavename, O_RDWR, 0);
if (slave < 0) {
ERROR_EXIT("open: pty slave");
}
Expand All @@ -156,13 +181,19 @@ chfunc(void *data, char *errbuf, size_t errbuf_len)
dup2(slave,1);
dup2(slave,2);
if (slave < 0 || slave > 2) (void)!close(slave);
return 0;
}

static int
drop_privilige(char *errbuf, size_t errbuf_len)
{
#if defined(HAVE_SETEUID) || defined(HAVE_SETREUID) || defined(HAVE_SETRESUID)
if (seteuid(getuid())) ERROR_EXIT("seteuid()");
#endif
return 0;
}

return rb_exec_async_signal_safe(carg->eargp, errbuf, sizeof(errbuf_len));
#undef ERROR_EXIT
}

static void
establishShell(int argc, VALUE *argv, struct pty_info *info,
Expand Down

0 comments on commit 0bc7182

Please sign in to comment.