Skip to content

Prevent some infinite recursion and loops - #352

Open
martin-hughes wants to merge 1 commit into
rust-osdev:mainfrom
martin-hughes:prevent-infinite-recursion
Open

martin-hughes wants to merge 1 commit into
rust-osdev:mainfrom
martin-hughes:prevent-infinite-recursion

Conversation

@martin-hughes

Copy link
Copy Markdown
Contributor

The motivation is to help stop AML causing a thread (or the system as a whole) to become deadlocked.

The first protection adds a maximum method call stack depth. This has been chosen arbitrarily, for now. It does not protect against all possible ways of recursing infinitely. For example, it does not stop recursive table loads. (Although LoadTable is not currently supported)

The second protection is a straightforward timeout for while loops, with associated tests.

These are both based on the uACPI protections, although they differ in a key way: in uACPI, the method stack is unwound. If a table definition is reached, execution continues with the next statement, but the execution is still flagged as failed. In this crate, execution is stopped with an error.

Notes:

  • I haven't made these configurable, for now. That could be valuable follow-on work if we see these limits being a problem.
  • I did wonder about enforcing a method execution timeout. But I wasn't sure what would happen if the system went to sleep and woke up a long time later. uACPI doesn't have such a timeout which made me feel better about leaving it out
  • I considered adding reference unwrapping limits as well, but they'd need to change the signatures of the unwrap_ methods, so I felt that was worth leaving for a separate PR.

The motivation is to help stop AML causing a thread (or the system as a
whole) to become deadlocked.

The first protection adds a maximum method call stack depth. This has
been chosen arbitrarily, for now. It does not protect against all
possible ways of recursing infinitely. For example, it does not stop
recursive table loads. (Although LoadTable is not currently supported)

The second protection is a straightforward timeout for while loops,
with associated tests.

These are both based on the uACPI protections, although they differ in
a key way: in uACPI, the method stack is unwound. If a table definition
is reached, execution continues with the next statement, but the
execution is still flagged as failed. In this crate, execution is
stopped with an error.
Comment thread tests/while.asl

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual tests are the same, but now the "shoulds" have become "musts".

Panicked,
}

impl<T> std::fmt::Debug for RunTestResult<T>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed to allow RunTestResult to be checked in assert_matches

Comment thread src/aml/mod.rs
kind: BlockKind::Method { method_scope: scope.clone() },
};
let block =
Block { stream: code.clone(), pc: 0, kind: BlockKind::Method { method_scope: scope.clone() } };

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pure formatting change - I'm not sure why the previous version was unacceptable to rustfmt. Maybe it's a new-nightly thing?

@martin-hughes

Copy link
Copy Markdown
Contributor Author

Whoever merges this PR: it will interact with #345. The second of the two to be merged will need updating to handle the first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant