From 40521f86261f0cf3cc83bd321dc310b75301bf97 Mon Sep 17 00:00:00 2001 From: Achilleas Anagnostopoulos Date: Wed, 5 Jul 2017 16:50:59 +0100 Subject: [PATCH] Ensure that the memory returned by sysAlloc is always zeroed --- src/gopheros/kernel/goruntime/bootstrap.go | 13 +++++++++++++ src/gopheros/kernel/goruntime/bootstrap_test.go | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/gopheros/kernel/goruntime/bootstrap.go b/src/gopheros/kernel/goruntime/bootstrap.go index e43e279..06d06b4 100644 --- a/src/gopheros/kernel/goruntime/bootstrap.go +++ b/src/gopheros/kernel/goruntime/bootstrap.go @@ -13,12 +13,14 @@ import ( var ( mapFn = vmm.Map earlyReserveRegionFn = vmm.EarlyReserveRegion + memsetFn = mem.Memset frameAllocFn = allocator.AllocFrame mallocInitFn = mallocInit algInitFn = algInit modulesInitFn = modulesInit typeLinksInitFn = typeLinksInit itabsInitFn = itabsInit + initGoPackagesFn = initGoPackages // A seed for the pseudo-random number generator used by getRandomData prngSeed = 0xdeadc0de @@ -42,6 +44,13 @@ func mallocInit() //go:linkname mSysStatInc runtime.mSysStatInc func mSysStatInc(*uint64, uintptr) +// initGoPackages is an alias to main.init which recursively calls the init() +// methods in all imported packages. Unless this function is called, things like +// package errors will not be properly initialized causing various problems when +// we try to use the stdlib. +//go:linkname initGoPackages main.init +func initGoPackages() + // sysReserve reserves address space without allocating any memory or // establishing any page mappings. // @@ -117,6 +126,8 @@ func sysAlloc(size uintptr, sysStat *uint64) unsafe.Pointer { if err = mapFn(page, frame, mapFlags); err != nil { return unsafe.Pointer(uintptr(0)) } + + memsetFn(page.Address(), 0, mem.PageSize) } mSysStatInc(sysStat, uintptr(regionSize)) @@ -163,6 +174,8 @@ func Init() *kernel.Error { typeLinksInitFn() // uses maps, activeModules itabsInitFn() // uses activeModules + initGoPackagesFn() + return nil } diff --git a/src/gopheros/kernel/goruntime/bootstrap_test.go b/src/gopheros/kernel/goruntime/bootstrap_test.go index 298c5d0..cec83a7 100644 --- a/src/gopheros/kernel/goruntime/bootstrap_test.go +++ b/src/gopheros/kernel/goruntime/bootstrap_test.go @@ -136,6 +136,7 @@ func TestSysAlloc(t *testing.T) { defer func() { earlyReserveRegionFn = vmm.EarlyReserveRegion mapFn = vmm.Map + memsetFn = mem.Memset frameAllocFn = allocator.AllocFrame }() @@ -161,10 +162,15 @@ func TestSysAlloc(t *testing.T) { for specIndex, spec := range specs { var ( - sysStat uint64 - mapCallCount int + sysStat uint64 + mapCallCount int + memsetCallCount int ) + memsetFn = func(_ uintptr, _ byte, _ mem.Size) { + memsetCallCount++ + } + mapFn = func(_ vmm.Page, _ pmm.Frame, flags vmm.PageTableEntryFlag) *kernel.Error { expFlags := vmm.FlagPresent | vmm.FlagNoExecute | vmm.FlagRW if flags != expFlags { @@ -182,6 +188,11 @@ func TestSysAlloc(t *testing.T) { t.Errorf("[spec %d] expected vmm.Map call count to be %d; got %d", specIndex, spec.expMapCallCount, mapCallCount) } + // sysAlloc should perform the same number of memset calls as map calls + if memsetCallCount != spec.expMapCallCount { + t.Errorf("[spec %d] expected mem.Memset call count to be %d; got %d", specIndex, spec.expMapCallCount, memsetCallCount) + } + if exp := uint64(spec.expMapCallCount << mem.PageShift); sysStat != exp { t.Errorf("[spec %d] expected stat counter to be %d; got %d", specIndex, exp, sysStat) }