diff options
author | Jamie Liu <jamieliu@google.com> | 2019-05-06 16:38:37 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-05-06 16:39:43 -0700 |
commit | 14f0e7618e28dac78ca7b00ec61fcec062159009 (patch) | |
tree | c013e3de320aff59850bee29f44be0fde8ea58a6 | |
parent | ff8ed5e6a5a391c5465230121af09afa5d1906e9 (diff) |
Ensure all uses of MM.brk occur under MM.mappingMu in MM.Brk().
PiperOrigin-RevId: 246921386
Change-Id: I71d8908858f45a9a33a0483470d0240eaf0fd012
-rw-r--r-- | pkg/sentry/mm/syscalls.go | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/pkg/sentry/mm/syscalls.go b/pkg/sentry/mm/syscalls.go index a25318abb..70c9aa7f6 100644 --- a/pkg/sentry/mm/syscalls.go +++ b/pkg/sentry/mm/syscalls.go @@ -694,8 +694,9 @@ func (mm *MemoryManager) Brk(ctx context.Context, addr usermem.Addr) (usermem.Ad // Can't defer mm.mappingMu.Unlock(); see below. if addr < mm.brk.Start { + addr = mm.brk.End mm.mappingMu.Unlock() - return mm.brk.End, syserror.EINVAL + return addr, syserror.EINVAL } // TODO(gvisor.dev/issue/156): This enforces RLIMIT_DATA, but is @@ -704,22 +705,20 @@ func (mm *MemoryManager) Brk(ctx context.Context, addr usermem.Addr) (usermem.Ad // size of heap + data + bss. The segment sizes need to be plumbed from // the loader package to fully enforce RLIMIT_DATA. if uint64(addr-mm.brk.Start) > limits.FromContext(ctx).Get(limits.Data).Cur { + addr = mm.brk.End mm.mappingMu.Unlock() - return mm.brk.End, syserror.ENOMEM + return addr, syserror.ENOMEM } oldbrkpg, _ := mm.brk.End.RoundUp() newbrkpg, ok := addr.RoundUp() if !ok { + addr = mm.brk.End mm.mappingMu.Unlock() - return mm.brk.End, syserror.EFAULT + return addr, syserror.EFAULT } switch { - case newbrkpg < oldbrkpg: - mm.unmapLocked(ctx, usermem.AddrRange{newbrkpg, oldbrkpg}) - mm.mappingMu.Unlock() - case oldbrkpg < newbrkpg: vseg, ar, err := mm.createVMALocked(ctx, memmap.MMapOpts{ Length: uint64(newbrkpg - oldbrkpg), @@ -736,21 +735,26 @@ func (mm *MemoryManager) Brk(ctx context.Context, addr usermem.Addr) (usermem.Ad Hint: "[heap]", }) if err != nil { + addr = mm.brk.End mm.mappingMu.Unlock() - return mm.brk.End, err + return addr, err } + mm.brk.End = addr if mm.defMLockMode == memmap.MLockEager { mm.populateVMAAndUnlock(ctx, vseg, ar, true) } else { mm.mappingMu.Unlock() } + case newbrkpg < oldbrkpg: + mm.unmapLocked(ctx, usermem.AddrRange{newbrkpg, oldbrkpg}) + fallthrough + default: - // Nothing to do. + mm.brk.End = addr mm.mappingMu.Unlock() } - mm.brk.End = addr return addr, nil } |