From 1fcd40719dd89d92213c6ba5b4872b79198c309f Mon Sep 17 00:00:00 2001 From: Wei Zhang Date: Tue, 2 Apr 2019 14:50:09 -0700 Subject: device: fix device major/minor Current gvisor doesn't give devices a right major and minor number. When testing golang supporting of gvisor, I run the test case below: ``` $ docker run -ti --runtime runsc golang:1.12.1 bash -c "cd /usr/local/go/src && ./run.bash " ``` And it reports some errors, one of them is: "--- FAIL: TestDevices (0.00s) --- FAIL: TestDevices//dev/null_1:3 (0.00s) dev_linux_test.go:45: for /dev/null Major(0x0) == 0, want 1 dev_linux_test.go:48: for /dev/null Minor(0x0) == 0, want 3 dev_linux_test.go:51: for /dev/null Mkdev(1, 3) == 0x103, want 0x0 --- FAIL: TestDevices//dev/zero_1:5 (0.00s) dev_linux_test.go:45: for /dev/zero Major(0x0) == 0, want 1 dev_linux_test.go:48: for /dev/zero Minor(0x0) == 0, want 5 dev_linux_test.go:51: for /dev/zero Mkdev(1, 5) == 0x105, want 0x0 --- FAIL: TestDevices//dev/random_1:8 (0.00s) dev_linux_test.go:45: for /dev/random Major(0x0) == 0, want 1 dev_linux_test.go:48: for /dev/random Minor(0x0) == 0, want 8 dev_linux_test.go:51: for /dev/random Mkdev(1, 8) == 0x108, want 0x0 --- FAIL: TestDevices//dev/full_1:7 (0.00s) dev_linux_test.go:45: for /dev/full Major(0x0) == 0, want 1 dev_linux_test.go:48: for /dev/full Minor(0x0) == 0, want 7 dev_linux_test.go:51: for /dev/full Mkdev(1, 7) == 0x107, want 0x0 --- FAIL: TestDevices//dev/urandom_1:9 (0.00s) dev_linux_test.go:45: for /dev/urandom Major(0x0) == 0, want 1 dev_linux_test.go:48: for /dev/urandom Minor(0x0) == 0, want 9 dev_linux_test.go:51: for /dev/urandom Mkdev(1, 9) == 0x109, want 0x0 " So I think we'd better assign to them correct major/minor numbers following linux spec. Signed-off-by: Wei Zhang Change-Id: I4521ee7884b4e214fd3a261929e3b6dac537ada9 PiperOrigin-RevId: 241609021 --- pkg/sentry/fs/dev/dev.go | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'pkg/sentry/fs/dev') diff --git a/pkg/sentry/fs/dev/dev.go b/pkg/sentry/fs/dev/dev.go index e1eaa08cb..fbc750a71 100644 --- a/pkg/sentry/fs/dev/dev.go +++ b/pkg/sentry/fs/dev/dev.go @@ -27,6 +27,19 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) +// Memory device numbers are from Linux's drivers/char/mem.c +const ( + // Mem device major. + memDevMajor uint16 = 1 + + // Mem device minors. + nullDevMinor uint32 = 3 + zeroDevMinor uint32 = 5 + fullDevMinor uint32 = 7 + randomDevMinor uint32 = 8 + urandomDevMinor uint32 = 9 +) + func newCharacterDevice(iops fs.InodeOperations, msrc *fs.MountSource) *fs.Inode { return fs.NewInode(iops, msrc, fs.StableAttr{ DeviceID: devDevice.DeviceID(), @@ -36,6 +49,17 @@ func newCharacterDevice(iops fs.InodeOperations, msrc *fs.MountSource) *fs.Inode }) } +func newMemDevice(iops fs.InodeOperations, msrc *fs.MountSource, minor uint32) *fs.Inode { + return fs.NewInode(iops, msrc, fs.StableAttr{ + DeviceID: devDevice.DeviceID(), + InodeID: devDevice.NextIno(), + BlockSize: usermem.PageSize, + Type: fs.CharacterDevice, + DeviceFileMajor: memDevMajor, + DeviceFileMinor: minor, + }) +} + func newDirectory(ctx context.Context, msrc *fs.MountSource) *fs.Inode { iops := ramfs.NewDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0555)) return fs.NewInode(iops, msrc, fs.StableAttr{ @@ -64,17 +88,17 @@ func New(ctx context.Context, msrc *fs.MountSource, binderEnabled bool, ashmemEn "stdout": newSymlink(ctx, "/proc/self/fd/1", msrc), "stderr": newSymlink(ctx, "/proc/self/fd/2", msrc), - "null": newCharacterDevice(newNullDevice(ctx, fs.RootOwner, 0666), msrc), - "zero": newCharacterDevice(newZeroDevice(ctx, fs.RootOwner, 0666), msrc), - "full": newCharacterDevice(newFullDevice(ctx, fs.RootOwner, 0666), msrc), + "null": newMemDevice(newNullDevice(ctx, fs.RootOwner, 0666), msrc, nullDevMinor), + "zero": newMemDevice(newZeroDevice(ctx, fs.RootOwner, 0666), msrc, zeroDevMinor), + "full": newMemDevice(newFullDevice(ctx, fs.RootOwner, 0666), msrc, fullDevMinor), // This is not as good as /dev/random in linux because go // runtime uses sys_random and /dev/urandom internally. // According to 'man 4 random', this will be sufficient unless // application uses this to generate long-lived GPG/SSL/SSH // keys. - "random": newCharacterDevice(newRandomDevice(ctx, fs.RootOwner, 0444), msrc), - "urandom": newCharacterDevice(newRandomDevice(ctx, fs.RootOwner, 0444), msrc), + "random": newMemDevice(newRandomDevice(ctx, fs.RootOwner, 0444), msrc, randomDevMinor), + "urandom": newMemDevice(newRandomDevice(ctx, fs.RootOwner, 0444), msrc, urandomDevMinor), "shm": tmpfs.NewDir(ctx, nil, fs.RootOwner, fs.FilePermsFromMode(0777), msrc), -- cgit v1.2.3