Syzkaller is reporting crashes relating to changes made by these commits.
Rolling back for now. Should be rolled forward with fix.

Reported-by: syzbot+9868746b8b0f679da548@syzkaller.appspotmail.com
PiperOrigin-RevId: 564000728
This commit is contained in:
Ayush Ranjan
2023-09-09 06:50:38 -07:00
committed by gVisor bot
parent 717539fbd7
commit bb4410f44e
3 changed files with 35 additions and 86 deletions
-37
View File
@@ -108,10 +108,6 @@ type Mount struct {
// Mount.EndWrite(). The MSB of writers is set if MS_RDONLY is in effect.
// writers is accessed using atomic memory operations.
writers atomicbitops.Int64
// pendingChildren is a list of new child mounts that have not yet been
// connected to this mount as the parent.
pendingChildren []*Mount
}
func newMount(vfs *VirtualFilesystem, fs *Filesystem, root *Dentry, mntns *MountNamespace, opts *MountOptions) *Mount {
@@ -308,39 +304,6 @@ func (vfs *VirtualFilesystem) cloneMount(mnt *Mount, root *Dentry, mopts *MountO
return clone
}
type cloneTreeNode struct {
prevMount *Mount
parentMount *Mount
}
// cloneMountTree creates a copy of mnt's tree with the specified root
// dentry at root. The new descendents are added to mnt's pending mount list.
//
// +checklocks:vfs.mountMu
func (vfs *VirtualFilesystem) cloneMountTree(ctx context.Context, mnt *Mount, root *Dentry) (*Mount, error) {
clone := vfs.cloneMount(mnt, root, nil)
queue := []cloneTreeNode{{mnt, clone}}
for len(queue) != 0 {
p := queue[len(queue)-1]
queue = queue[:len(queue)-1]
for c := range p.prevMount.children {
m := vfs.cloneMount(c, c.root, nil)
vfs.delayDecRef(m)
mp := VirtualDentry{
mount: p.parentMount,
dentry: c.point(),
}
mp.IncRef()
m.setKey(mp)
p.parentMount.pendingChildren = append(p.parentMount.pendingChildren, m)
if len(c.children) != 0 {
queue = append(queue, cloneTreeNode{c, m})
}
}
}
return clone, nil
}
// BindAt creates a clone of the source path's parent mount and mounts it at
// the target path. The new mount's root dentry is one pointed to by the source
// path.
+35 -12
View File
@@ -125,6 +125,11 @@ func (vfs *VirtualFilesystem) NewMountNamespaceFrom(
return mntns
}
type cloneEntry struct {
prevMount *Mount
parentMount *Mount
}
// +checklocks:vfs.mountMu
func (vfs *VirtualFilesystem) updateRootAndCWD(ctx context.Context, root *VirtualDentry, cwd *VirtualDentry, src *Mount, dst *Mount) {
if root.mount == src {
@@ -137,10 +142,6 @@ func (vfs *VirtualFilesystem) updateRootAndCWD(ctx context.Context, root *Virtua
cwd.mount = dst
cwd.mount.IncRef()
}
for srcChild := range src.children {
dstChild := vfs.mounts.Lookup(dst, srcChild.point())
vfs.updateRootAndCWD(ctx, root, cwd, srcChild, dstChild)
}
}
// NamespaceInodeGetter is an interface that provides the GetNamespaceInode method.
@@ -169,16 +170,38 @@ func (vfs *VirtualFilesystem) CloneMountNamespace(
vfs.lockMounts()
defer vfs.unlockMounts(ctx)
newRoot, err := vfs.cloneMountTree(ctx, ns.root, ns.root.root)
if err != nil {
newns.DecRef(ctx)
vfs.abortTree(ctx, newRoot)
return nil, err
ns.root.root.IncRef()
ns.root.fs.IncRef()
newns.root = newMount(vfs, ns.root.fs, ns.root.root, newns, &MountOptions{Flags: ns.root.Flags, ReadOnly: ns.root.ReadOnly()})
if ns.root.isShared {
vfs.addPeer(ns.root, newns.root)
}
newns.root = newRoot
newns.root.ns = newns
vfs.commitTree(ctx, newRoot)
vfs.updateRootAndCWD(ctx, root, cwd, ns.root, newns.root)
queue := []cloneEntry{cloneEntry{ns.root, newns.root}}
for len(queue) != 0 {
p := queue[0]
queue = queue[1:]
for c := range p.prevMount.children {
m := vfs.cloneMount(c, c.root, nil)
vd := VirtualDentry{
mount: p.parentMount,
dentry: c.point(),
}
vd.IncRef()
err := vfs.connectMountAtLocked(ctx, m, vd)
vfs.delayDecRef(m)
if err != nil {
newns.DecRef(ctx)
return nil, err
}
vfs.updateRootAndCWD(ctx, root, cwd, c, m)
if len(c.children) != 0 {
queue = append(queue, cloneEntry{c, m})
}
}
}
return newns, nil
}
-37
View File
@@ -153,43 +153,6 @@ func (vfs *VirtualFilesystem) abortPropagationTree(ctx context.Context, tree map
}
}
// +checklocks:vfs.mountMu
func (vfs *VirtualFilesystem) commitTree(ctx context.Context, mnt *Mount) {
vfs.mounts.seq.BeginWrite()
for _, c := range mnt.pendingChildren {
vfs.commitTreeSeqed(ctx, c)
}
mnt.pendingChildren = nil
vfs.mounts.seq.EndWrite()
}
// +checklocks:vfs.mountMu
func (vfs *VirtualFilesystem) commitTreeSeqed(ctx context.Context, mnt *Mount) {
mp := mnt.getKey()
mp.dentry.mu.Lock()
vfs.connectLocked(mnt, mp, mp.mount.ns)
mp.dentry.mu.Unlock()
for _, c := range mnt.pendingChildren {
vfs.commitTreeSeqed(ctx, c)
}
mnt.pendingChildren = nil
}
// abortTree releases references on a pending mount and all its pending
// descendants.
//
// +checklocks:vfs.mountMu
func (vfs *VirtualFilesystem) abortTree(ctx context.Context, mnt *Mount) {
mp := mnt.getKey()
vfs.delayDecRef(mnt)
vfs.delayDecRef(mp.dentry)
vfs.setPropagation(mnt, linux.MS_PRIVATE)
for _, c := range mnt.pendingChildren {
vfs.abortTree(ctx, c)
}
mnt.pendingChildren = nil
}
// SetMountPropagationAt changes the propagation type of the mount pointed to by
// pop.
func (vfs *VirtualFilesystem) SetMountPropagationAt(ctx context.Context, creds *auth.Credentials, pop *PathOperation, propFlags uint32) error {