Disable process_vm_read/writev and add a test.

ProcessVM readv/writev needs some work due to lock ordering issues
with locking MM between tasks. So disable the call until it
can be fixed.

Also add a test from one of the identified bugs from syzcaller.

PiperOrigin-RevId: 467085160
This commit is contained in:
Zach Koopmans
2022-08-11 17:11:17 -07:00
committed by gVisor bot
parent 5852220509
commit 004b4e727b
2 changed files with 24 additions and 5 deletions
+1 -2
View File
@@ -156,8 +156,7 @@ func Override() {
s.Table[299] = syscalls.Supported("recvmmsg", RecvMMsg)
s.Table[306] = syscalls.Supported("syncfs", Syncfs)
s.Table[307] = syscalls.Supported("sendmmsg", SendMMsg)
s.Table[310] = syscalls.Supported("process_vm_readv", ProcessVMReadv)
s.Table[311] = syscalls.Supported("process_vm_writev", ProcessVMWritev)
// FIXME(zkoopmans): Re-enable calls for process_vm_(read/write)v.
s.Table[316] = syscalls.Supported("renameat2", Renameat2)
s.Table[319] = syscalls.Supported("memfd_create", MemfdCreate)
s.Table[322] = syscalls.SupportedPoint("execveat", Execveat, linux.PointExecveat)
+23 -3
View File
@@ -13,6 +13,7 @@
// limitations under the License.
#include <asm-generic/errno-base.h>
#include <bits/types/siginfo_t.h>
#include <bits/types/struct_iovec.h>
#include <errno.h>
#include <string.h>
@@ -36,7 +37,6 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "test/util/linux_capability_util.h"
#include "test/util/logging.h"
#include "test/util/multiprocess_util.h"
#include "test/util/posix_error.h"
#include "test/util/test_util.h"
@@ -140,8 +140,8 @@ TEST_P(ProcessVMTest, TestReadvSameProcess) {
// TestReadvSubProcess repeats the previous test in a forked process.
TEST_P(ProcessVMTest, TestReadvSubProcess) {
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE((HaveCapability(CAP_SYS_PTRACE))));
SKIP_IF(ProcessVMCallsNotSupported());
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE((HaveCapability(CAP_SYS_PTRACE))));
auto local_data = GetParam().local_data;
auto remote_data = GetParam().remote_data;
@@ -190,8 +190,8 @@ TEST_P(ProcessVMTest, TestWritevSameProcess) {
// TestWritevSubProcess repeats the previous test in a forked process.
TEST_P(ProcessVMTest, TestWritevSubProcess) {
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE((HaveCapability(CAP_SYS_PTRACE))));
SKIP_IF(ProcessVMCallsNotSupported());
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE((HaveCapability(CAP_SYS_PTRACE))));
auto local_data = GetParam().local_data;
auto remote_data = GetParam().remote_data;
TestIovecs remote_iovecs(remote_data);
@@ -282,10 +282,12 @@ TEST(ProcessVMInvalidTest, NULLRemoteIovec) {
pid_t parent = getppid();
int ret =
process_vm_readv(parent, &child_iov, contents.length(), nullptr, 1, 0);
TEST_CHECK(ret == -1);
TEST_CHECK(errno == EFAULT || errno == EINVAL);
ret =
process_vm_writev(parent, &child_iov, contents.length(), nullptr, 1, 0);
TEST_CHECK(ret == -1);
TEST_CHECK(errno == EFAULT || errno == EINVAL);
};
ASSERT_THAT(InForkedProcess(fn), IsPosixErrorOkAndHolds(0));
@@ -377,6 +379,24 @@ TEST(ProcessVMInvalidTest, PartialReadWrite) {
SyscallSucceedsWithValue(iov_content_1.size()));
}
TEST(ProcessVMTest, WriteToZombie) {
SKIP_IF(ProcessVMCallsNotSupported());
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE((HaveCapability(CAP_SYS_PTRACE))));
char* data = {0};
pid_t child;
ASSERT_THAT(child = fork(), SyscallSucceeds());
if (child == 0) {
_exit(0);
}
siginfo_t siginfo = {};
ASSERT_THAT(RetryEINTR(waitid)(P_PID, child, &siginfo, WEXITED | WNOWAIT),
SyscallSucceeds());
struct iovec iov;
iov.iov_base = data;
iov.iov_len = sizeof(data);
ASSERT_THAT(process_vm_writev(child, &iov, 1, &iov, 1, 0),
SyscallFailsWithErrno(ESRCH));
}
} // namespace
} // namespace testing