Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some UB in signal handling #18

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

a3f
Copy link
Member

@a3f a3f commented Aug 25, 2019

While looking over #15, I noticed some issues with the way microcom handles signals. This fixes what was straight forward to fix. What remains is the access to ios, ios->exit and whatever is called there. With #15 merged, this could be fixed by peppering some volatile around, but it's very unlikely to happen so postponing this for now.

sigaction(2) reads the sa_mask and sa_flags struct members as well, but
we didn't initialize them so far. We probably didn't run into problems,
because we allocate it when the stack is fresh and full of zeroes.

Fix this by explicitly zeroing the struct and emptying the signal set.

Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
We use malloc elsewhere in the code with signals unmasked, but use free
in a signal handler. This could result in a dead lock when terminating
microcom by signal.

The duplication of exit(0) call is ok, as the call site in the signal
handler will be replaced in a follow-up commit.

Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
Both printf and exit aren't async signal safe, replace them with write
and _Exit respectively.

The access to ios and ios->exit and callees is still illegal, but at
least we don't run risk reentering stdio and causing a deadlock anymore.

As exit flushes stdio buffers as well, we now risk losing unflushed
stdio output. This is acceptable as we aren't buffering the serial
port output and the program is being terminated abnormally anyway.

Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
ukleinek
ukleinek previously approved these changes Aug 25, 2019
@ukleinek ukleinek self-requested a review August 25, 2019 21:19
@ukleinek
Copy link
Contributor

Sorry, github UI problems. I only intended to approve the first commit.

Copy link
Contributor

@ukleinek ukleinek left a comment

Choose a reason for hiding this comment

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

Hmm, I don't particularly like this. I'd like to allow backends calling async-unsafe functions. Freeing ios in global code seems to work, but is a layer violation because the structure was allocated in the backends. I'll think about that, if you want to improve this while I think that would be welcome of course :-)

@ukleinek ukleinek dismissed their stale review August 25, 2019 21:27

added by accident, only intended to approve first commit

@a3f
Copy link
Member Author

a3f commented Aug 25, 2019

Hmm, I don't particularly like this. I'd like to allow backends calling async-unsafe functions.

We could longjmp back into main and exit regularly there. Thinking about it, I like this approach more as well. What do you think?
(EDIT: Thinking some more about this, this is non-nonsensical. If you call an async-signal-unsafe function after a longjmp, you run into UB as well.)

Freeing ios in global code seems to work, but is a layer violation because the structure was allocated in the backends.

Is it? malloc, calloc and strdup are all free'd by the same free. Same goes for open, socket and creat, which are all destructed by close.

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.

2 participants