Fix seek on /proc/pid/cmdline when task is zombie.

PiperOrigin-RevId: 348056159
This commit is contained in:
Nicolas Lacasse
2020-12-17 11:16:06 -08:00
committed by gVisor bot
parent 028271b530
commit 1ea241e4cc
2 changed files with 38 additions and 6 deletions
+11 -6
View File
@@ -57,9 +57,6 @@ func getMM(task *kernel.Task) *mm.MemoryManager {
// MemoryManager's users count is incremented, and must be decremented by the
// caller when it is no longer in use.
func getMMIncRef(task *kernel.Task) (*mm.MemoryManager, error) {
if task.ExitState() == kernel.TaskExitDead {
return nil, syserror.ESRCH
}
var m *mm.MemoryManager
task.WithMuLocked(func(t *kernel.Task) {
m = t.MemoryManager()
@@ -111,9 +108,13 @@ var _ dynamicInode = (*auxvData)(nil)
// Generate implements vfs.DynamicBytesSource.Generate.
func (d *auxvData) Generate(ctx context.Context, buf *bytes.Buffer) error {
if d.task.ExitState() == kernel.TaskExitDead {
return syserror.ESRCH
}
m, err := getMMIncRef(d.task)
if err != nil {
return err
// Return empty file.
return nil
}
defer m.DecUsers(ctx)
@@ -157,9 +158,13 @@ var _ dynamicInode = (*cmdlineData)(nil)
// Generate implements vfs.DynamicBytesSource.Generate.
func (d *cmdlineData) Generate(ctx context.Context, buf *bytes.Buffer) error {
if d.task.ExitState() == kernel.TaskExitDead {
return syserror.ESRCH
}
m, err := getMMIncRef(d.task)
if err != nil {
return err
// Return empty file.
return nil
}
defer m.DecUsers(ctx)
@@ -472,7 +477,7 @@ func (fd *memFD) PRead(ctx context.Context, dst usermem.IOSequence, offset int64
}
m, err := getMMIncRef(fd.inode.task)
if err != nil {
return 0, nil
return 0, err
}
defer m.DecUsers(ctx)
// Buffer the read data because of MM locks
+27
View File
@@ -1802,6 +1802,33 @@ TEST(ProcPidCmdline, SubprocessForkSameCmdline) {
}
}
TEST(ProcPidCmdline, SubprocessSeekCmdline) {
FileDescriptor fd;
ASSERT_NO_ERRNO(WithSubprocess(
[&](int pid) -> PosixError {
// Running. Open /proc/pid/cmdline.
ASSIGN_OR_RETURN_ERRNO(
fd, Open(absl::StrCat("/proc/", pid, "/cmdline"), O_RDONLY));
return NoError();
},
[&](int pid) -> PosixError {
// Zombie, but seek should still succeed.
int ret = lseek(fd.get(), 0x801, 0);
if (ret < 0) {
return PosixError(errno);
}
return NoError();
},
[&](int pid) -> PosixError {
// Exited.
int ret = lseek(fd.get(), 0x801, 0);
if (ret < 0) {
return PosixError(errno);
}
return NoError();
}));
}
// Test whether /proc/PID/ symlinks can be read for a running process.
TEST(ProcPidSymlink, SubprocessRunning) {
char buf[1];