Rework security_manager_sync_threads_internal() 66/301866/12
authorTomasz Swierczek <t.swierczek@samsung.com>
Fri, 24 Nov 2023 12:47:07 +0000 (13:47 +0100)
committerTomasz Swierczek <t.swierczek@samsung.com>
Mon, 27 Nov 2023 11:57:07 +0000 (12:57 +0100)
commit5760192eafe3a0f6121428d45ac14a33d55323ff
treef8d7e2bb890f3b0ee035ae24f26171a5c5d75c6f
parent89e420387094981855d7034ebc4d95cfb70ac173
Rework security_manager_sync_threads_internal()

Add "stop-the-world" implemenation in signal handler.

Why this change may be needed?
------------------------------

On slower platforms, some dotnet-based app candidate processes
tend to have 10-15-... threads. Sending signals that change
Smack labels & drop caps to each of them can be delayed - for apps
that don't have a priority to get launched, this can take up
to 10-15 seconds, in pathological cases (observed in real life,
on low-end boards). In such situation, there's non-zero time window
when some threads have changed security attributes and some
haven't  - access control issues occur in app candidate's logic,
leading to serious errors & abort()s in the launched app.

With this modification, threads change the Smack labels & capabilities
when none of them are performing any of their original app candidate
logic and the only thread NOT in signal handler is the one
with security-manager client library.

This is expected to limit Smack/permission issues mentioned earlier.

Details, disclaimers:
---------------------

This implementation CANNOT fix an issue where app candidate process
created a resource (ie. a file) BEFORE call to security_manager_prepare_app()
and then, wants to access it (for read) AFTER call to the function.
This is because, before the transition, the process has either User
or System::Privileged Smack label, to which apps do not have R Smack rule
(such issues can still occur and can't be dealt with at security-manger level).

This implementation can be up to 3x slower on low-end boards,
as we have 3 waiting points here, instead of one:
    1) waiting for signals to arrive in all threads (place from old implementation)
    2) waiting for signals to be able to start changing caps/Smack labels
    3) waiting for signals to sync after attributes are changed to start work

Tests performed on Tizen emulator show about 30-40% slowdown
of prepare app vs. previous implementation.

This implementation assumes that the size of set of all TIDs
that can appear in a process (already dead + currently alive) will not exceed 1000.
A global array of std::atomic's is used to keep track of each thread's
state in the execution of signal handler.

This implementation uses sleep() and std::atomic to implement
waiting for the barrier inside a signal handler (home-made spinlock,
basically). While this can be done more elegantly, ie. with std::atomic's wait()
functionality, this C++ feature doesn't seem to be supported in current Tizen
toolchain (c++2a supported, not full c++20).

An alternative way for synchronization would be to use high-profile system
resources like fd's or semaphores, however, because the VD H/W platform
where the issue of thread dis-synchronization happens is very slow, interfacing
with kernel was limited to minimum, as adding any context switch to kernel
may slow down even more.

Change-Id: Ic7037acaeb4e3eaab03284ae63216e7ab4d6d862
src/client/check-proper-drop.cpp
src/client/client-security-manager.cpp
src/common/include/check-proper-drop.h