mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 07:08:18 +00:00
hw: sanitize kernel's signal datastructures
* Move all Kernel::Signal_* structures to kernel/signal.* * Remove return value of kill_signal_context, which wasn't evaluated * Remove Kernel::Signal_context::can_kill * Remove Kernel::Signal_context::can_submit * Remove Kernel::Signal_receiver::can_add_handler * Turn nullptr into cxx nullptr instead of just zero * Turn boolean values into true/false instead of one/zero * Always add to signal FIFO also if submit counter cannot get increased enough Fix genodelabs/genode#5416
This commit is contained in:
committed by
Christian Helmuth
parent
2728853005
commit
0d648eae62
@ -382,13 +382,10 @@ namespace Kernel {
|
|||||||
* Halt processing of a signal context synchronously
|
* Halt processing of a signal context synchronously
|
||||||
*
|
*
|
||||||
* \param context capability ID of the targeted signal context
|
* \param context capability ID of the targeted signal context
|
||||||
*
|
|
||||||
* \retval 0 suceeded
|
|
||||||
* \retval -1 failed
|
|
||||||
*/
|
*/
|
||||||
inline int kill_signal_context(capid_t const context)
|
inline void kill_signal_context(capid_t const context)
|
||||||
{
|
{
|
||||||
return (int)call(call_id_kill_signal_context(), context);
|
call(call_id_kill_signal_context(), context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,7 +54,7 @@ SRC_CC += kernel/ipc_node.cc
|
|||||||
SRC_CC += kernel/irq.cc
|
SRC_CC += kernel/irq.cc
|
||||||
SRC_CC += kernel/main.cc
|
SRC_CC += kernel/main.cc
|
||||||
SRC_CC += kernel/object.cc
|
SRC_CC += kernel/object.cc
|
||||||
SRC_CC += kernel/signal_receiver.cc
|
SRC_CC += kernel/signal.cc
|
||||||
SRC_CC += kernel/thread.cc
|
SRC_CC += kernel/thread.cc
|
||||||
SRC_CC += kernel/timer.cc
|
SRC_CC += kernel/timer.cc
|
||||||
SRC_CC += capability.cc
|
SRC_CC += capability.cc
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include <util/avl_tree.h>
|
#include <util/avl_tree.h>
|
||||||
|
|
||||||
/* core includes */
|
/* core includes */
|
||||||
#include <kernel/signal_receiver.h>
|
#include <kernel/signal.h>
|
||||||
|
|
||||||
namespace Board {
|
namespace Board {
|
||||||
|
|
||||||
@ -161,9 +161,7 @@ class Kernel::User_irq : public Kernel::Irq
|
|||||||
*/
|
*/
|
||||||
void occurred() override
|
void occurred() override
|
||||||
{
|
{
|
||||||
if (_context.can_submit(1)) {
|
|
||||||
_context.submit(1);
|
_context.submit(1);
|
||||||
}
|
|
||||||
disable();
|
disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
/*
|
/*
|
||||||
* \brief Kernel backend for asynchronous inter-process communication
|
* \brief Kernel backend for asynchronous inter-process communication
|
||||||
* \author Martin Stein
|
* \author Martin Stein
|
||||||
|
* \author Stefan Kalkowski
|
||||||
* \date 2012-11-30
|
* \date 2012-11-30
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2012-2019 Genode Labs GmbH
|
* Copyright (C) 2012-2025 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* core includes */
|
/* core includes */
|
||||||
#include <kernel/signal_receiver.h>
|
#include <kernel/signal.h>
|
||||||
#include <kernel/thread.h>
|
#include <kernel/thread.h>
|
||||||
|
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
@ -26,7 +27,7 @@ void Signal_handler::cancel_waiting()
|
|||||||
{
|
{
|
||||||
if (_receiver) {
|
if (_receiver) {
|
||||||
_receiver->_handler_cancelled(*this);
|
_receiver->_handler_cancelled(*this);
|
||||||
_receiver = 0;
|
_receiver = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,27 +72,19 @@ void Signal_context::_deliverable()
|
|||||||
void Signal_context::_delivered()
|
void Signal_context::_delivered()
|
||||||
{
|
{
|
||||||
_submits = 0;
|
_submits = 0;
|
||||||
_ack = 0;
|
_ack = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Signal_context::_killer_cancelled() { _killer = 0; }
|
void Signal_context::_killer_cancelled() { _killer = nullptr; }
|
||||||
|
|
||||||
|
|
||||||
bool Signal_context::can_submit(unsigned const n) const
|
|
||||||
{
|
|
||||||
if (_killed || _submits >= (unsigned)~0 - n)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Signal_context::submit(unsigned const n)
|
void Signal_context::submit(unsigned const n)
|
||||||
{
|
{
|
||||||
if (_killed || _submits >= (unsigned)~0 - n)
|
if (_killed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (_submits < ((unsigned)~0 - n))
|
||||||
_submits += n;
|
_submits += n;
|
||||||
|
|
||||||
if (_ack)
|
if (_ack)
|
||||||
@ -105,32 +98,19 @@ void Signal_context::ack()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!_killed) {
|
if (!_killed) {
|
||||||
_ack = 1;
|
_ack = true;
|
||||||
_deliverable();
|
_deliverable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_killer) {
|
if (_killer) {
|
||||||
_killer->_context = 0;
|
_killer->_context = nullptr;
|
||||||
_killer->_thread.signal_context_kill_done();
|
_killer->_thread.signal_context_kill_done();
|
||||||
_killer = 0;
|
_killer = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Signal_context::can_kill() const
|
|
||||||
{
|
|
||||||
/* check if in a kill operation or already killed */
|
|
||||||
if (_killed) {
|
|
||||||
if (_ack)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Signal_context::kill(Signal_context_killer &k)
|
void Signal_context::kill(Signal_context_killer &k)
|
||||||
{
|
{
|
||||||
/* check if in a kill operation or already killed */
|
/* check if in a kill operation or already killed */
|
||||||
@ -139,13 +119,13 @@ void Signal_context::kill(Signal_context_killer &k)
|
|||||||
|
|
||||||
/* kill directly if there is no unacknowledged delivery */
|
/* kill directly if there is no unacknowledged delivery */
|
||||||
if (_ack) {
|
if (_ack) {
|
||||||
_killed = 1;
|
_killed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait for delivery acknowledgement */
|
/* wait for delivery acknowledgement */
|
||||||
_killer = &k;
|
_killer = &k;
|
||||||
_killed = 1;
|
_killed = true;
|
||||||
_killer->_context = this;
|
_killer->_context = this;
|
||||||
_killer->_thread.signal_context_kill_pending();
|
_killer->_thread.signal_context_kill_pending();
|
||||||
}
|
}
|
||||||
@ -231,24 +211,17 @@ void Signal_receiver::_add_context(Signal_context &c) {
|
|||||||
_contexts.enqueue(c._contexts_fe); }
|
_contexts.enqueue(c._contexts_fe); }
|
||||||
|
|
||||||
|
|
||||||
bool Signal_receiver::can_add_handler(Signal_handler const &h) const
|
|
||||||
|
bool Signal_receiver::add_handler(Signal_handler &h)
|
||||||
{
|
{
|
||||||
if (h._receiver)
|
if (h._receiver)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Signal_receiver::add_handler(Signal_handler &h)
|
|
||||||
{
|
|
||||||
if (h._receiver)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_handlers.enqueue(h._handlers_fe);
|
_handlers.enqueue(h._handlers_fe);
|
||||||
h._receiver = this;
|
h._receiver = this;
|
||||||
h._thread.signal_wait_for_signal();
|
h._thread.signal_wait_for_signal();
|
||||||
_listen();
|
_listen();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,18 +1,19 @@
|
|||||||
/*
|
/*
|
||||||
* \brief Kernel backend for asynchronous inter-process communication
|
* \brief Kernel backend for asynchronous inter-process communication
|
||||||
* \author Martin Stein
|
* \author Martin Stein
|
||||||
|
* \author Stefan Kalkowski
|
||||||
* \date 2012-11-30
|
* \date 2012-11-30
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
* Copyright (C) 2012-2025 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CORE__KERNEL__SIGNAL_RECEIVER_H_
|
#ifndef _CORE__KERNEL__SIGNAL_H_
|
||||||
#define _CORE__KERNEL__SIGNAL_RECEIVER_H_
|
#define _CORE__KERNEL__SIGNAL_H_
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/signal.h>
|
#include <base/signal.h>
|
||||||
@ -165,11 +166,7 @@ class Kernel::Signal_context
|
|||||||
* Submit the signal
|
* Submit the signal
|
||||||
*
|
*
|
||||||
* \param n number of submits
|
* \param n number of submits
|
||||||
*
|
|
||||||
* \retval 0 succeeded
|
|
||||||
* \retval -1 failed
|
|
||||||
*/
|
*/
|
||||||
bool can_submit(unsigned const n) const;
|
|
||||||
void submit(unsigned const n);
|
void submit(unsigned const n);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,12 +177,8 @@ class Kernel::Signal_context
|
|||||||
/**
|
/**
|
||||||
* Destruct context or prepare to do it as soon as delivery is done
|
* Destruct context or prepare to do it as soon as delivery is done
|
||||||
*
|
*
|
||||||
* \param killer object that shall receive progress reports
|
* \param k object that shall receive progress reports
|
||||||
*
|
|
||||||
* \retval 0 succeeded
|
|
||||||
* \retval -1 failed
|
|
||||||
*/
|
*/
|
||||||
bool can_kill() const;
|
|
||||||
void kill(Signal_context_killer &k);
|
void kill(Signal_context_killer &k);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -270,8 +263,7 @@ class Kernel::Signal_receiver
|
|||||||
* \retval 0 succeeded
|
* \retval 0 succeeded
|
||||||
* \retval -1 failed
|
* \retval -1 failed
|
||||||
*/
|
*/
|
||||||
bool can_add_handler(Signal_handler const &h) const;
|
bool add_handler(Signal_handler &h);
|
||||||
void add_handler(Signal_handler &h);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Syscall to create a signal receiver
|
* Syscall to create a signal receiver
|
@ -522,11 +522,8 @@ void Thread::timeout_triggered()
|
|||||||
{
|
{
|
||||||
Signal_context * const c =
|
Signal_context * const c =
|
||||||
pd().cap_tree().find<Signal_context>(_timeout_sigid);
|
pd().cap_tree().find<Signal_context>(_timeout_sigid);
|
||||||
if (!c || !c->can_submit(1)) {
|
if (c) c->submit(1);
|
||||||
Genode::raw(*this, ": failed to submit timeout signal");
|
else Genode::warning(*this, ": failed to submit timeout signal");
|
||||||
return;
|
|
||||||
}
|
|
||||||
c->submit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -602,12 +599,11 @@ void Thread::_call_await_signal()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* register handler at the receiver */
|
/* register handler at the receiver */
|
||||||
if (!r->can_add_handler(_signal_handler)) {
|
if (!r->add_handler(_signal_handler)) {
|
||||||
Genode::raw("failed to register handler at signal receiver");
|
Genode::raw("failed to register handler at signal receiver");
|
||||||
user_arg_0(-1);
|
user_arg_0(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
r->add_handler(_signal_handler);
|
|
||||||
user_arg_0(0);
|
user_arg_0(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,11 +620,10 @@ void Thread::_call_pending_signal()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* register handler at the receiver */
|
/* register handler at the receiver */
|
||||||
if (!r->can_add_handler(_signal_handler)) {
|
if (!r->add_handler(_signal_handler)) {
|
||||||
user_arg_0(-1);
|
user_arg_0(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
r->add_handler(_signal_handler);
|
|
||||||
|
|
||||||
if (_state == AWAITS_SIGNAL) {
|
if (_state == AWAITS_SIGNAL) {
|
||||||
_cancel_blocking();
|
_cancel_blocking();
|
||||||
@ -663,20 +658,7 @@ void Thread::_call_submit_signal()
|
|||||||
{
|
{
|
||||||
/* lookup signal context */
|
/* lookup signal context */
|
||||||
Signal_context * const c = pd().cap_tree().find<Signal_context>((Kernel::capid_t)user_arg_1());
|
Signal_context * const c = pd().cap_tree().find<Signal_context>((Kernel::capid_t)user_arg_1());
|
||||||
if(!c) {
|
if(c) c->submit((unsigned)user_arg_2());
|
||||||
/* cannot submit unknown signal context */
|
|
||||||
user_arg_0(-1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* trigger signal context */
|
|
||||||
if (!c->can_submit((unsigned)user_arg_2())) {
|
|
||||||
Genode::raw("failed to submit signal context");
|
|
||||||
user_arg_0(-1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
c->submit((unsigned)user_arg_2());
|
|
||||||
user_arg_0(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -684,13 +666,8 @@ void Thread::_call_ack_signal()
|
|||||||
{
|
{
|
||||||
/* lookup signal context */
|
/* lookup signal context */
|
||||||
Signal_context * const c = pd().cap_tree().find<Signal_context>((Kernel::capid_t)user_arg_1());
|
Signal_context * const c = pd().cap_tree().find<Signal_context>((Kernel::capid_t)user_arg_1());
|
||||||
if (!c) {
|
if (c) c->ack();
|
||||||
Genode::raw(*this, ": cannot ack unknown signal context");
|
else Genode::warning(*this, ": cannot ack unknown signal context");
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* acknowledge */
|
|
||||||
c->ack();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -698,19 +675,8 @@ void Thread::_call_kill_signal_context()
|
|||||||
{
|
{
|
||||||
/* lookup signal context */
|
/* lookup signal context */
|
||||||
Signal_context * const c = pd().cap_tree().find<Signal_context>((Kernel::capid_t)user_arg_1());
|
Signal_context * const c = pd().cap_tree().find<Signal_context>((Kernel::capid_t)user_arg_1());
|
||||||
if (!c) {
|
if (c) c->kill(_signal_context_killer);
|
||||||
Genode::raw(*this, ": cannot kill unknown signal context");
|
else Genode::warning(*this, ": cannot kill unknown signal context");
|
||||||
user_arg_0(-1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* kill signal context */
|
|
||||||
if (!c->can_kill()) {
|
|
||||||
Genode::raw("failed to kill signal context");
|
|
||||||
user_arg_0(-1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
c->kill(_signal_context_killer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
/* base-hw core includes */
|
/* base-hw core includes */
|
||||||
#include <kernel/cpu_context.h>
|
#include <kernel/cpu_context.h>
|
||||||
#include <kernel/inter_processor_work.h>
|
#include <kernel/inter_processor_work.h>
|
||||||
#include <kernel/signal_receiver.h>
|
#include <kernel/signal.h>
|
||||||
#include <kernel/ipc_node.h>
|
#include <kernel/ipc_node.h>
|
||||||
#include <object.h>
|
#include <object.h>
|
||||||
#include <kernel/interface.h>
|
#include <kernel/interface.h>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
/* core includes */
|
/* core includes */
|
||||||
#include <kernel/cpu_context.h>
|
#include <kernel/cpu_context.h>
|
||||||
#include <kernel/pd.h>
|
#include <kernel/pd.h>
|
||||||
#include <kernel/signal_receiver.h>
|
#include <kernel/signal.h>
|
||||||
|
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include <pager/capability.h>
|
#include <pager/capability.h>
|
||||||
|
|
||||||
/* core includes */
|
/* core includes */
|
||||||
#include <kernel/signal_receiver.h>
|
#include <kernel/signal.h>
|
||||||
#include <hw/mapping.h>
|
#include <hw/mapping.h>
|
||||||
#include <mapping.h>
|
#include <mapping.h>
|
||||||
#include <object.h>
|
#include <object.h>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
/* core includes */
|
/* core includes */
|
||||||
#include <object.h>
|
#include <object.h>
|
||||||
#include <kernel/signal_receiver.h>
|
#include <kernel/signal.h>
|
||||||
#include <assertion.h>
|
#include <assertion.h>
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
Reference in New Issue
Block a user