kernel: fix Abind cyclic reference and mounthead leaks (thanks Alex Musolino)
The Abind case in namec() needs to cunique() the chan before attaching the umh mount head pointer onto it. This is because we cannot give a reference to the mount head to any of the mh->mount...->to channels, as they will never go away until the mount head goes away. This is a cyclic reference. This could be reproduced with: @{rfork n; mount -a '#s/boot' /mnt/root; bind /mnt/root /} Also, fix memory leaks around cunique(), which can error, leaking the mount head we got from domount(). Move the umh != nil check inside cunique().
This commit is contained in:
parent
951a71012f
commit
603d9812a7
1 changed files with 17 additions and 12 deletions
|
@ -556,6 +556,12 @@ cunique(Chan *c)
|
|||
c = nc;
|
||||
}
|
||||
|
||||
if(c->umh != nil){ //BUG
|
||||
print("cunique umh != nil from %#p\n", getcallerpc(&c));
|
||||
putmhead(c->umh);
|
||||
c->umh = nil;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -1094,11 +1100,6 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
|
|||
}
|
||||
putmhead(mh);
|
||||
c = cunique(c);
|
||||
if(c->umh != nil){ //BUG
|
||||
print("walk umh\n");
|
||||
putmhead(c->umh);
|
||||
c->umh = nil;
|
||||
}
|
||||
|
||||
pathclose(c->path);
|
||||
c->path = path;
|
||||
|
@ -1410,8 +1411,13 @@ namec(char *aname, int amode, int omode, ulong perm)
|
|||
m = nil;
|
||||
if(!nomount)
|
||||
domount(&c, &m, nil);
|
||||
putmhead(c->umh);
|
||||
if(waserror()){
|
||||
putmhead(m);
|
||||
nexterror();
|
||||
}
|
||||
c = cunique(c);
|
||||
c->umh = m;
|
||||
poperror();
|
||||
break;
|
||||
|
||||
case Aaccess:
|
||||
|
@ -1428,9 +1434,13 @@ namec(char *aname, int amode, int omode, ulong perm)
|
|||
m = nil;
|
||||
if(!nomount)
|
||||
domount(&c, &m, &path);
|
||||
|
||||
if(waserror()){
|
||||
putmhead(m);
|
||||
nexterror();
|
||||
}
|
||||
/* our own copy to open or remove */
|
||||
c = cunique(c);
|
||||
poperror();
|
||||
|
||||
/* now it's our copy anyway, we can put the name back */
|
||||
pathclose(c->path);
|
||||
|
@ -1448,11 +1458,6 @@ namec(char *aname, int amode, int omode, ulong perm)
|
|||
|
||||
case Aopen:
|
||||
case Acreate:
|
||||
if(c->umh != nil){
|
||||
print("cunique umh Open\n");
|
||||
putmhead(c->umh);
|
||||
c->umh = nil;
|
||||
}
|
||||
/* only save the mount head if it's a multiple element union */
|
||||
if(m != nil && m->mount != nil && m->mount->next != nil)
|
||||
c->umh = m;
|
||||
|
|
Loading…
Reference in a new issue