From: Alexander Viro <viro@math.psu.edu>
To: 9fans@cse.psu.edu
Subject: [9fans] Potential race in syspipe()
Date: Fri, 11 Aug 2000 07:20:14 -0400 [thread overview]
Message-ID: <Pine.GSO.4.10.10008110640100.194-100000@weyl.math.psu.edu> (raw)
Umm... Unless I'm seriously misreading the code, there is a race
between syspipe() and sysdup(). Scenario:
CPU1 (in syspipe()):
c[0] = d->open(c[0], ORDWR);
c[1] = d->open(c[1], ORDWR);
fd[0] = newfd(c[0]);
/* got so far */
fd[1] = newfd(c[1]);
/* failed on that one for whatever reason */
CPU2 (in sysdup()):
...
lock(f);
...
oc = f->fd[fd];
f->fd[fd] = c;
unlock(f);
if(oc)
cclose(oc);
/* where fd happens to be equal to fd[0] on the CPU1 */
/* oc == CPU1's c[0], indeed */
CPU1:
if(fd[0] < 0 || fd[1] < 0)
error(Enofd);
/* there we go */
cclose(c[0]);
/* woops - extra cclose on c[0] and we are welcome to... */
if(c->flag&CFREE)
panic("cclose %lux", getcallerpc(&c));
Giving user enough rope to hang himself is a good idea, but panic() goes
somewhat beyond "himself", especially when triggered on CPU server...
AFAICS the cleanish solution would be along the lines of
int
newfd2(int fd[2], Chan *c[2])
{
Fgrp *f;
int i,j;
f = up->fgrp;
lock(f);
for(i=0; i<f->nfd; i++)
if(f->fd[i] == 0)
break;
for(j=i+1; j<f->nfd; j++)
if (f->fd[j] == 0)
break;
if(j >= f->nfd && growfd(f, j) < 0){
unlock(f);
return -1;
}
if(j > f->maxfd)
f->maxfd = j;
f->fd[fd[0]=i] = c[0];
f->fd[fd[1]=j] = c[1];
unlock(f);
return 0;
}
and using it in syspipe() (instead of two newfd() calls). That way the
error recovery in syspipe() doesn't have to touch anything that might be
anywhere near the ->fd[].
Comments? AFAICS _anything_ that goes into ->fd[] must be treated as final
as soon as you release the lock on ->fgrp (due to the dup2() issues).
Al
next reply other threads:[~2000-08-11 11:20 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2000-08-11 11:20 Alexander Viro [this message]
2000-08-14 1:47 presotto
2000-08-14 2:42 ` Alexander Viro
2000-08-15 19:42 ` Dan Cross
2000-08-16 11:58 ` Alexander Viro
2000-08-16 12:36 ` Boyd Roberts
2000-08-14 4:30 presotto
2000-08-14 4:50 ` Alexander Viro
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.GSO.4.10.10008110640100.194-100000@weyl.math.psu.edu \
--to=viro@math.psu.edu \
--cc=9fans@cse.psu.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).