2017-09-05 23:53:40 +02:00
|
|
|
/*
|
|
|
|
* This file is part of Jehanne.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2017 Giacomo Tesio <giacomo@tesio.it>
|
|
|
|
*
|
|
|
|
* This is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as
|
|
|
|
* published by the Free Software Foundation, version 3 of the License.
|
|
|
|
*
|
|
|
|
* Jehanne is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
#include <u.h>
|
|
|
|
#include <lib9.h>
|
|
|
|
#include <9P2000.h>
|
|
|
|
#include <posix.h>
|
|
|
|
#include "internal.h"
|
|
|
|
|
2017-09-11 01:01:11 +02:00
|
|
|
typedef union {
|
|
|
|
int group;
|
|
|
|
char raw[sizeof(int)];
|
|
|
|
} IntBuf;
|
|
|
|
|
|
|
|
extern int *__libposix_devsignal;
|
2017-09-07 00:10:34 +02:00
|
|
|
int __libposix_session_leader = -1;
|
|
|
|
|
|
|
|
static int
|
2017-09-11 01:01:11 +02:00
|
|
|
get_ppid(int pid)
|
2017-09-07 00:10:34 +02:00
|
|
|
{
|
2017-09-11 01:01:11 +02:00
|
|
|
long n;
|
|
|
|
char buf[32];
|
|
|
|
sprint(buf, "/proc/%d/ppid", pid);
|
|
|
|
n = remove(buf);
|
|
|
|
if(n == -1)
|
2017-09-07 00:10:34 +02:00
|
|
|
return -1;
|
2017-09-11 01:01:11 +02:00
|
|
|
return (int)n;
|
|
|
|
}
|
|
|
|
|
|
|
|
long
|
|
|
|
__libposix_sighelper_set_pgid(int target, int group)
|
|
|
|
{
|
|
|
|
union {
|
|
|
|
PosixHelperRequest request;
|
|
|
|
long raw;
|
|
|
|
} offset;
|
|
|
|
IntBuf buf;
|
2017-12-25 13:13:09 +01:00
|
|
|
long ret;
|
2017-09-11 01:01:11 +02:00
|
|
|
|
|
|
|
offset.request.command = PHSetProcessGroup;
|
|
|
|
offset.request.target = target;
|
2017-09-07 00:10:34 +02:00
|
|
|
|
2017-09-11 01:01:11 +02:00
|
|
|
buf.group = group;
|
2017-12-25 13:13:09 +01:00
|
|
|
ret = pwrite(*__libposix_devsignal, buf.raw, sizeof(buf.raw), offset.raw);
|
|
|
|
return ret;
|
2017-09-07 00:10:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-09-11 01:01:11 +02:00
|
|
|
set_group_id(int *errnop, int pid, int group)
|
2017-09-07 00:10:34 +02:00
|
|
|
{
|
2017-09-11 01:01:11 +02:00
|
|
|
int mypid, ppid;
|
2017-09-07 00:10:34 +02:00
|
|
|
|
2017-09-11 01:01:11 +02:00
|
|
|
if(pid < 0 || group < 0){
|
|
|
|
*errnop = __libposix_get_errno(PosixEINVAL);
|
2017-09-07 00:10:34 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2017-09-11 01:01:11 +02:00
|
|
|
if(pid == __libposix_session_leader){
|
2017-09-07 00:10:34 +02:00
|
|
|
*errnop = __libposix_get_errno(PosixEPERM);
|
|
|
|
return -1;
|
|
|
|
}
|
2017-09-11 01:01:11 +02:00
|
|
|
mypid = *__libposix_pid;
|
|
|
|
if(pid == 0 && group == 0){
|
|
|
|
/* the caller wants a new process group */
|
|
|
|
CreateNewProcessGroup:
|
|
|
|
rfork(RFNOTEG);
|
|
|
|
return __libposix_sighelper_cmd(PHSetProcessGroup, mypid);
|
|
|
|
}
|
2017-12-25 13:13:09 +01:00
|
|
|
if(pid == 0)
|
|
|
|
pid = mypid;
|
2017-09-11 01:01:11 +02:00
|
|
|
ppid = get_ppid(pid);
|
|
|
|
if(ppid == -1 || pid != mypid && mypid != ppid){
|
|
|
|
*errnop = __libposix_get_errno(PosixESRCH);
|
|
|
|
return -1;
|
|
|
|
}
|
2017-12-25 13:13:09 +01:00
|
|
|
if(group == 0)
|
|
|
|
group = pid;
|
2017-09-11 01:01:11 +02:00
|
|
|
if(pid == group && pid == mypid)
|
|
|
|
goto CreateNewProcessGroup;
|
|
|
|
|
|
|
|
return __libposix_sighelper_set_pgid(pid, group);
|
2017-09-07 00:10:34 +02:00
|
|
|
}
|
|
|
|
|
2017-09-05 23:53:40 +02:00
|
|
|
int
|
|
|
|
POSIX_getuid(int *errnop)
|
|
|
|
{
|
2017-09-11 01:01:11 +02:00
|
|
|
return 1000;
|
2017-09-05 23:53:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
POSIX_geteuid(int *errnop)
|
|
|
|
{
|
2017-09-11 01:01:11 +02:00
|
|
|
return 1000;
|
2017-09-05 23:53:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
POSIX_setuid(int *errnop, int uid)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
POSIX_seteuid(int *errnop, int euid)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
POSIX_setreuid(int *errnop, int ruid, int euid)
|
|
|
|
{
|
2017-09-11 01:01:11 +02:00
|
|
|
return 1000;
|
2017-09-05 23:53:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
POSIX_getgid(int *errnop)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
POSIX_getegid(int *errnop)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
POSIX_setgid(int *errnop, int gid)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
POSIX_setegid(int *errnop, int egid)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
POSIX_setregid(int *errnop, int rgid, int egid)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-09-07 00:10:34 +02:00
|
|
|
int
|
|
|
|
POSIX_getpgrp(int *errnop)
|
|
|
|
{
|
2017-09-11 01:01:11 +02:00
|
|
|
long ret;
|
|
|
|
int pid = *__libposix_pid;
|
|
|
|
ret = __libposix_sighelper_cmd(PHGetProcessGroupId, pid);
|
|
|
|
if(ret < 0)
|
|
|
|
return pid;
|
|
|
|
return ret;
|
2017-09-07 00:10:34 +02:00
|
|
|
}
|
|
|
|
|
2017-09-07 23:27:33 +02:00
|
|
|
int
|
|
|
|
POSIX_getpgid(int *errnop, int pid)
|
|
|
|
{
|
2017-09-11 01:01:11 +02:00
|
|
|
long ret;
|
|
|
|
ret = __libposix_sighelper_cmd(PHGetProcessGroupId, pid);
|
|
|
|
if(ret < 0)
|
|
|
|
*errnop = __libposix_get_errno(PosixESRCH);
|
|
|
|
return ret;
|
2017-09-07 23:27:33 +02:00
|
|
|
}
|
|
|
|
|
2017-09-05 23:53:40 +02:00
|
|
|
int
|
|
|
|
POSIX_setpgid(int *errnop, int pid, int pgid)
|
|
|
|
{
|
2017-09-11 01:01:11 +02:00
|
|
|
return set_group_id(errnop, pid, pgid);
|
2017-09-05 23:53:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
POSIX_getsid(int *errnop, int pid)
|
|
|
|
{
|
2017-09-11 01:01:11 +02:00
|
|
|
int mypid;
|
|
|
|
long sid;
|
|
|
|
char buf[32];
|
2017-09-07 00:10:34 +02:00
|
|
|
|
|
|
|
if(pid < 0){
|
2017-09-11 01:01:11 +02:00
|
|
|
FailWithESRCH:
|
2017-09-07 00:10:34 +02:00
|
|
|
*errnop = __libposix_get_errno(PosixESRCH);
|
|
|
|
return -1;
|
|
|
|
}
|
2017-09-11 01:01:11 +02:00
|
|
|
snprint(buf, sizeof(buf), "/proc/%d/ns", pid);
|
|
|
|
if(access(buf, AEXIST) != 0)
|
|
|
|
goto FailWithESRCH;
|
|
|
|
|
|
|
|
mypid = *__libposix_pid;
|
2017-09-07 00:10:34 +02:00
|
|
|
if(pid == 0)
|
2017-09-11 01:01:11 +02:00
|
|
|
pid = mypid;
|
|
|
|
sid = __libposix_sighelper_cmd(PHGetSessionId, pid);
|
|
|
|
if(sid < 0){
|
|
|
|
*errnop = __libposix_get_errno(PosixEPERM);
|
|
|
|
return -1;
|
2017-09-07 00:10:34 +02:00
|
|
|
}
|
2017-09-11 01:01:11 +02:00
|
|
|
if(pid == mypid)
|
|
|
|
__libposix_session_leader = (int)sid;
|
|
|
|
|
|
|
|
return sid;
|
2017-09-05 23:53:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
POSIX_setsid(int *errnop)
|
|
|
|
{
|
2017-09-11 01:01:11 +02:00
|
|
|
extern PosixSignalMask *__libposix_signal_mask;
|
|
|
|
extern SignalConf *__libposix_signals;
|
|
|
|
extern int *__libposix_devsignal;
|
|
|
|
|
|
|
|
char *posixly_args[4], *fname;
|
|
|
|
int mypid = *__libposix_pid;
|
|
|
|
int oldsid;
|
|
|
|
long controlpid;
|
|
|
|
SignalConf *c;
|
|
|
|
|
|
|
|
/* detach the previous session */
|
|
|
|
oldsid = (int)__libposix_sighelper_cmd(PHGetSessionId, 0);
|
|
|
|
fname = smprint("#s/posixly.%s.%d", getuser(), oldsid);
|
|
|
|
if(fname == nil || __libposix_sighelper_cmd(PHDetachSession, 0) < 0)
|
|
|
|
goto FailWithEPERM;
|
|
|
|
if(*__libposix_devsignal >= 0)
|
|
|
|
close(*__libposix_devsignal);
|
|
|
|
*__libposix_devsignal = -1;
|
|
|
|
rfork(RFNAMEG|RFNOTEG|RFENVG|RFFDG);
|
|
|
|
unmount(fname, "/dev");
|
|
|
|
free(fname);
|
|
|
|
fname = nil;
|
|
|
|
assert(access("/dev/posix", AEXIST) != 0);
|
|
|
|
|
|
|
|
/* start the new session */
|
|
|
|
switch(controlpid = sys_rfork(RFPROC|RFNOTEG|RFENVG|RFFDG)){
|
|
|
|
case -1:
|
|
|
|
goto FailWithEPERM;
|
|
|
|
case 0:
|
|
|
|
posixly_args[0] = "posixly";
|
|
|
|
posixly_args[1] = "-p";
|
|
|
|
posixly_args[2] = smprint("%d", mypid);
|
|
|
|
posixly_args[3] = nil;
|
|
|
|
jehanne_pexec("sys/posixly", posixly_args);
|
|
|
|
rfork(RFNOWAIT);
|
|
|
|
sysfatal("pexec sys/posixly");
|
|
|
|
default:
|
|
|
|
break;
|
2017-09-07 00:10:34 +02:00
|
|
|
}
|
2017-09-11 01:01:11 +02:00
|
|
|
|
|
|
|
/* wait for /dev/posix/ */
|
|
|
|
fname = smprint("/proc/%d/note", controlpid);
|
|
|
|
if(fname == nil)
|
|
|
|
goto FailWithEPERM;
|
|
|
|
while(access("/dev/posix", AEXIST) != 0 && access(fname, AWRITE) == 0)
|
|
|
|
sleep(250);
|
|
|
|
if(access(fname, AWRITE) != 0)
|
|
|
|
goto FailWithEPERM;
|
|
|
|
free(fname);
|
|
|
|
fname = nil;
|
|
|
|
|
|
|
|
/* connect to the new session */
|
|
|
|
__libposix_sighelper_open();
|
|
|
|
__libposix_sighelper_set(PHBlockSignals, *__libposix_signal_mask);
|
|
|
|
c = __libposix_signals;
|
|
|
|
while(c < __libposix_signals + PosixNumberOfSignals){
|
|
|
|
if(c->handler == (void*)1)
|
|
|
|
__libposix_sighelper_set(PHIgnoreSignal, SIGNAL_MASK(1+(c-__libposix_signals)));
|
|
|
|
++c;
|
|
|
|
}
|
|
|
|
__libposix_session_leader = mypid;
|
|
|
|
return mypid;
|
|
|
|
|
|
|
|
FailWithEPERM:
|
|
|
|
if(fname)
|
|
|
|
free(fname);
|
|
|
|
*errnop = __libposix_get_errno(PosixEPERM);
|
|
|
|
return -1;
|
2017-09-05 23:53:40 +02:00
|
|
|
}
|