Fix construct of linux.Stat for arm64.

PiperOrigin-RevId: 297494373
This commit is contained in:
Rahat Mahmood
2020-02-26 19:29:27 -08:00
committed by gVisor bot
parent 6ddeb35ed4
commit 8fb84f78ad
8 changed files with 186 additions and 41 deletions
+2
View File
@@ -42,6 +42,8 @@ go_library(
"sys_socket.go",
"sys_splice.go",
"sys_stat.go",
"sys_stat_amd64.go",
"sys_stat_arm64.go",
"sys_sync.go",
"sys_sysinfo.go",
"sys_syslog.go",
-18
View File
@@ -25,24 +25,6 @@ import (
// LINT.IfChange
func statFromAttrs(t *kernel.Task, sattr fs.StableAttr, uattr fs.UnstableAttr) linux.Stat {
return linux.Stat{
Dev: sattr.DeviceID,
Ino: sattr.InodeID,
Nlink: uattr.Links,
Mode: sattr.Type.LinuxType() | uint32(uattr.Perms.LinuxMode()),
UID: uint32(uattr.Owner.UID.In(t.UserNamespace()).OrOverflow()),
GID: uint32(uattr.Owner.GID.In(t.UserNamespace()).OrOverflow()),
Rdev: uint64(linux.MakeDeviceID(sattr.DeviceFileMajor, sattr.DeviceFileMinor)),
Size: uattr.Size,
Blksize: sattr.BlockSize,
Blocks: uattr.Usage / 512,
ATime: uattr.AccessTime.Timespec(),
MTime: uattr.ModificationTime.Timespec(),
CTime: uattr.StatusChangeTime.Timespec(),
}
}
// Stat implements linux syscall stat(2).
func Stat(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
addr := args[0].Pointer()
@@ -0,0 +1,45 @@
// Copyright 2020 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build amd64
package linux
import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
)
// LINT.IfChange
func statFromAttrs(t *kernel.Task, sattr fs.StableAttr, uattr fs.UnstableAttr) linux.Stat {
return linux.Stat{
Dev: sattr.DeviceID,
Ino: sattr.InodeID,
Nlink: uattr.Links,
Mode: sattr.Type.LinuxType() | uint32(uattr.Perms.LinuxMode()),
UID: uint32(uattr.Owner.UID.In(t.UserNamespace()).OrOverflow()),
GID: uint32(uattr.Owner.GID.In(t.UserNamespace()).OrOverflow()),
Rdev: uint64(linux.MakeDeviceID(sattr.DeviceFileMajor, sattr.DeviceFileMinor)),
Size: uattr.Size,
Blksize: sattr.BlockSize,
Blocks: uattr.Usage / 512,
ATime: uattr.AccessTime.Timespec(),
MTime: uattr.ModificationTime.Timespec(),
CTime: uattr.StatusChangeTime.Timespec(),
}
}
// LINT.ThenChange(vfs2/stat_amd64.go)
@@ -0,0 +1,45 @@
// Copyright 2020 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build arm64
package linux
import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/fs"
"gvisor.dev/gvisor/pkg/sentry/kernel"
)
// LINT.IfChange
func statFromAttrs(t *kernel.Task, sattr fs.StableAttr, uattr fs.UnstableAttr) linux.Stat {
return linux.Stat{
Dev: sattr.DeviceID,
Ino: sattr.InodeID,
Nlink: uint32(uattr.Links),
Mode: sattr.Type.LinuxType() | uint32(uattr.Perms.LinuxMode()),
UID: uint32(uattr.Owner.UID.In(t.UserNamespace()).OrOverflow()),
GID: uint32(uattr.Owner.GID.In(t.UserNamespace()).OrOverflow()),
Rdev: uint64(linux.MakeDeviceID(sattr.DeviceFileMajor, sattr.DeviceFileMinor)),
Size: uattr.Size,
Blksize: int32(sattr.BlockSize),
Blocks: uattr.Usage / 512,
ATime: uattr.AccessTime.Timespec(),
MTime: uattr.ModificationTime.Timespec(),
CTime: uattr.StatusChangeTime.Timespec(),
}
}
// LINT.ThenChange(vfs2/stat_arm64.go)
+2
View File
@@ -22,6 +22,8 @@ go_library(
"read_write.go",
"setstat.go",
"stat.go",
"stat_amd64.go",
"stat_arm64.go",
"sync.go",
"xattr.go",
],
-23
View File
@@ -113,29 +113,6 @@ func fstatat(t *kernel.Task, dirfd int32, pathAddr, statAddr usermem.Addr, flags
return stat.CopyOut(t, statAddr)
}
// This takes both input and output as pointer arguments to avoid copying large
// structs.
func convertStatxToUserStat(t *kernel.Task, statx *linux.Statx, stat *linux.Stat) {
// Linux just copies fields from struct kstat without regard to struct
// kstat::result_mask (fs/stat.c:cp_new_stat()), so we do too.
userns := t.UserNamespace()
*stat = linux.Stat{
Dev: uint64(linux.MakeDeviceID(uint16(statx.DevMajor), statx.DevMinor)),
Ino: statx.Ino,
Nlink: uint64(statx.Nlink),
Mode: uint32(statx.Mode),
UID: uint32(auth.KUID(statx.UID).In(userns).OrOverflow()),
GID: uint32(auth.KGID(statx.GID).In(userns).OrOverflow()),
Rdev: uint64(linux.MakeDeviceID(uint16(statx.RdevMajor), statx.RdevMinor)),
Size: int64(statx.Size),
Blksize: int64(statx.Blksize),
Blocks: int64(statx.Blocks),
ATime: timespecFromStatxTimestamp(statx.Atime),
MTime: timespecFromStatxTimestamp(statx.Mtime),
CTime: timespecFromStatxTimestamp(statx.Ctime),
}
}
func timespecFromStatxTimestamp(sxts linux.StatxTimestamp) linux.Timespec {
return linux.Timespec{
Sec: sxts.Sec,
@@ -0,0 +1,46 @@
// Copyright 2020 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build amd64
package vfs2
import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
)
// This takes both input and output as pointer arguments to avoid copying large
// structs.
func convertStatxToUserStat(t *kernel.Task, statx *linux.Statx, stat *linux.Stat) {
// Linux just copies fields from struct kstat without regard to struct
// kstat::result_mask (fs/stat.c:cp_new_stat()), so we do too.
userns := t.UserNamespace()
*stat = linux.Stat{
Dev: uint64(linux.MakeDeviceID(uint16(statx.DevMajor), statx.DevMinor)),
Ino: statx.Ino,
Nlink: uint64(statx.Nlink),
Mode: uint32(statx.Mode),
UID: uint32(auth.KUID(statx.UID).In(userns).OrOverflow()),
GID: uint32(auth.KGID(statx.GID).In(userns).OrOverflow()),
Rdev: uint64(linux.MakeDeviceID(uint16(statx.RdevMajor), statx.RdevMinor)),
Size: int64(statx.Size),
Blksize: int64(statx.Blksize),
Blocks: int64(statx.Blocks),
ATime: timespecFromStatxTimestamp(statx.Atime),
MTime: timespecFromStatxTimestamp(statx.Mtime),
CTime: timespecFromStatxTimestamp(statx.Ctime),
}
}
@@ -0,0 +1,46 @@
// Copyright 2020 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build arm64
package vfs2
import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/sentry/kernel"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
)
// This takes both input and output as pointer arguments to avoid copying large
// structs.
func convertStatxToUserStat(t *kernel.Task, statx *linux.Statx, stat *linux.Stat) {
// Linux just copies fields from struct kstat without regard to struct
// kstat::result_mask (fs/stat.c:cp_new_stat()), so we do too.
userns := t.UserNamespace()
*stat = linux.Stat{
Dev: uint64(linux.MakeDeviceID(uint16(statx.DevMajor), statx.DevMinor)),
Ino: statx.Ino,
Nlink: uint32(statx.Nlink),
Mode: uint32(statx.Mode),
UID: uint32(auth.KUID(statx.UID).In(userns).OrOverflow()),
GID: uint32(auth.KGID(statx.GID).In(userns).OrOverflow()),
Rdev: uint64(linux.MakeDeviceID(uint16(statx.RdevMajor), statx.RdevMinor)),
Size: int64(statx.Size),
Blksize: int32(statx.Blksize),
Blocks: int64(statx.Blocks),
ATime: timespecFromStatxTimestamp(statx.Atime),
MTime: timespecFromStatxTimestamp(statx.Mtime),
CTime: timespecFromStatxTimestamp(statx.Ctime),
}
}