summaryrefslogtreecommitdiff
path: root/sys/src
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2020-03-08 04:54:37 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2020-03-08 04:54:37 +0100
commit59fdb3a12cd1e6ec9f65ca014c23fd27bea45245 (patch)
treec1df0e5f1f92ae09c1756c358893ff2a572aed5b /sys/src
parent2c53dd32b5cf88daad2bad02a058af414275322d (diff)
sshnet: fix fork race conditions
sshreadproc() needs to be started after opening the sshfd file descriptor. fsnetproc() needs to run in the same filedescriptor group as the fileserver.
Diffstat (limited to 'sys/src')
-rwxr-xr-xsys/src/cmd/sshnet.c54
1 files changed, 30 insertions, 24 deletions
diff --git a/sys/src/cmd/sshnet.c b/sys/src/cmd/sshnet.c
index ecb730abc..d185dbb59 100755
--- a/sys/src/cmd/sshnet.c
+++ b/sys/src/cmd/sshnet.c
@@ -33,7 +33,7 @@ enum
#define TYPE(path) ((int)(path) & 0xFF)
#define NUM(path) ((uint)(path)>>8)
-Channel *ssherrchan; /* chan(char*) */
+int sessionopen = 0;
Channel *sshmsgchan; /* chan(Msg*) */
Channel *fsreqchan; /* chan(Req*) */
Channel *fsreqwaitchan; /* chan(nil) */
@@ -125,7 +125,7 @@ struct Msg
int nclient;
Client **client;
-char *mtpt;
+char *mtpt, *service;
int sshfd;
int
@@ -1148,7 +1148,7 @@ handlemsg(Msg *m)
if(unpack(m, "_uuuu", &chan, &n, &win, &pkt) < 0)
break;
if(chan == SESSIONCHAN){
- sendp(ssherrchan, nil);
+ sessionopen++;
break;
}
c = getclient(chan);
@@ -1173,7 +1173,7 @@ handlemsg(Msg *m)
break;
s = smprint("%.*s", utfnlen(s, n), s);
if(chan == SESSIONCHAN){
- sendp(ssherrchan, s);
+ sysfatal("ssh failed: %s", s);
break;
}
c = getclient(chan);
@@ -1313,6 +1313,12 @@ fsdestroyfid(Fid *fid)
recvp(fsclunkwaitchan);
}
+static void
+startup(Srv*)
+{
+ proccreate(fsnetproc, nil, 8*1024);
+}
+
void
takedown(Srv*)
{
@@ -1321,7 +1327,7 @@ takedown(Srv*)
Srv fs =
{
-.attach= fssend,
+.attach= fssend,
.destroyfid= fsdestroyfid,
.walk1= fswalk1,
.open= fssend,
@@ -1329,6 +1335,7 @@ Srv fs =
.write= fssend,
.stat= fssend,
.flush= fssend,
+.start= startup,
.end= takedown,
};
@@ -1356,9 +1363,9 @@ startssh(void *)
void
ssh(int argc, char *argv[])
{
- Alt a[3];
+ Alt a[4];
Waitmsg *w;
- char *e;
+ Msg *m;
sshargc = argc + 2;
sshargv = emalloc9p(sizeof(char *) * (sshargc + 1));
@@ -1366,11 +1373,14 @@ ssh(int argc, char *argv[])
sshargv[1] = "-X";
memcpy(sshargv + 2, argv, argc * sizeof(char *));
- pipe(pfd);
+ if(pipe(pfd) < 0)
+ sysfatal("pipe: %r");
sshfd = pfd[0];
- procrfork(startssh, nil, 8*1024, RFFDG|RFNOTEG|RFNAMEG);
+ procrfork(startssh, nil, 8*1024, RFFDG|RFNOTEG);
close(pfd[1]);
+ procrfork(sshreadproc, nil, 8*1024, RFFDG|RFNOTEG);
+
sendmsg(pack(nil, "bsuuu", MSG_CHANNEL_OPEN,
"session", 7,
SESSIONCHAN,
@@ -1381,18 +1391,18 @@ ssh(int argc, char *argv[])
a[0].c = threadwaitchan();
a[0].v = &w;
a[1].op = CHANRCV;
- a[1].c = ssherrchan;
- a[1].v = &e;
+ a[1].c = sshmsgchan;
+ a[1].v = &m;
a[2].op = CHANEND;
- switch(alt(a)){
- case 0:
- sysfatal("ssh failed: %s", w->msg);
- case 1:
- if(e != nil)
- sysfatal("ssh failed: %s", e);
+ while(!sessionopen){
+ switch(alt(a)){
+ case 0:
+ sysfatal("ssh failed: %s", w->msg);
+ case 1:
+ handlemsg(m);
+ }
}
- chanclose(ssherrchan);
}
void
@@ -1405,8 +1415,6 @@ usage(void)
void
threadmain(int argc, char **argv)
{
- char *service;
-
fmtinstall('H', encodefmt);
mtpt = "/net";
@@ -1429,17 +1437,15 @@ threadmain(int argc, char **argv)
usage();
time0 = time(0);
- ssherrchan = chancreate(sizeof(char*), 0);
sshmsgchan = chancreate(sizeof(Msg*), 16);
fsreqchan = chancreate(sizeof(Req*), 0);
fsreqwaitchan = chancreate(sizeof(void*), 0);
fsclunkchan = chancreate(sizeof(Fid*), 0);
fsclunkwaitchan = chancreate(sizeof(void*), 0);
- procrfork(fsnetproc, nil, 8*1024, RFNAMEG|RFNOTEG);
- procrfork(sshreadproc, nil, 8*1024, RFNAMEG|RFNOTEG);
ssh(argc, argv);
threadpostmountsrv(&fs, service, mtpt, MREPL);
- exits(0);
+
+ threadexits(nil);
}