summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRahat Mahmood <rahat@google.com>2021-07-23 13:34:24 -0700
committergVisor bot <gvisor-bot@google.com>2021-07-23 13:37:33 -0700
commit3d0a9300050ad9a72d452ec862827e35e3f38dcc (patch)
tree04a8d8c216d6357f08755aad0744b80bae24f0a0
parent0eea96057a8559ae542a0cccfd61ceddc26ceb35 (diff)
Don't panic on user-controlled state in semaphore syscalls.
Reported-by: syzbot+beb099a67f670386a367@syzkaller.appspotmail.com PiperOrigin-RevId: 386521361
-rw-r--r--pkg/sentry/kernel/semaphore/semaphore.go10
-rw-r--r--test/syscalls/linux/semaphore.cc11
2 files changed, 16 insertions, 5 deletions
diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go
index b7879d284..8610d3fc1 100644
--- a/pkg/sentry/kernel/semaphore/semaphore.go
+++ b/pkg/sentry/kernel/semaphore/semaphore.go
@@ -214,15 +214,14 @@ func (r *Registry) Remove(id ipc.ID, creds *auth.Credentials) error {
r.mu.Lock()
defer r.mu.Unlock()
- r.reg.Remove(id, creds)
-
index, found := r.findIndexByID(id)
if !found {
- // Inconsistent state.
- panic(fmt.Sprintf("unable to find an index for ID: %d", id))
+ return linuxerr.EINVAL
}
delete(r.indexes, index)
+ r.reg.Remove(id, creds)
+
return nil
}
@@ -245,7 +244,8 @@ func (r *Registry) newSetLocked(ctx context.Context, key ipc.Key, creator fs.Fil
index, found := r.findFirstAvailableIndex()
if !found {
- panic("unable to find an available index")
+ // See linux, ipc/sem.c:newary().
+ return nil, linuxerr.ENOSPC
}
r.indexes[index] = set.obj.ID
diff --git a/test/syscalls/linux/semaphore.cc b/test/syscalls/linux/semaphore.cc
index f72957f89..87b66aa98 100644
--- a/test/syscalls/linux/semaphore.cc
+++ b/test/syscalls/linux/semaphore.cc
@@ -1019,6 +1019,17 @@ TEST(SemaphoreTest, SemInfo) {
EXPECT_EQ(info.semvmx, kSemVmx);
}
+TEST(SempahoreTest, RemoveNonExistentSemaphore) {
+ EXPECT_THAT(semctl(-1, 0, IPC_RMID), SyscallFailsWithErrno(EINVAL));
+}
+
+TEST(SempahoreTest, RemoveDeletedSemaphore) {
+ int id;
+ EXPECT_THAT(id = semget(IPC_PRIVATE, 1, 0), SyscallSucceeds());
+ EXPECT_THAT(semctl(id, 0, IPC_RMID), SyscallSucceeds());
+ EXPECT_THAT(semctl(id, 0, IPC_RMID), SyscallFailsWithErrno(EINVAL));
+}
+
} // namespace
} // namespace testing
} // namespace gvisor