On Tue, 19 Oct 2021 at 17:01, Ondrej Mosnacek <omosnace@xxxxxxxxxx> wrote: > > This series adds basic support for parallel relabeling to the libselinux > API and the setfiles/restorecon CLI tools. It turns out that doing the > relabeling in parallel can significantly reduce the time even with a > relatively simple approach. > > The first patch is a small cleanup that was found along the way and can > be applied independently. Patches 2-4 are small incremental changes that > make the internal selinux_restorecon functions more thread-safe (I kept > them separate for ease of of review, but maybe they should be rather > folded into the netx patch...). Patch 5 then completes the parallel > relabeling implementation at libselinux level and adds a new function > to the API that allows to make use of it. Finally, patch 6 adds parallel > relabeling support to he setfiles/restorecon tools. > > The relevant man pages are also updated to reflect the new > functionality. > > The patch descriptions contain more details, namely the last patch has > also some benchmark numbers. > There seems to be another data race, which however does not occur every time: ================== WARNING: ThreadSanitizer: data race (pid=4189) Read of size 8 at 0x7f72252e5908 by thread T3: #0 is_context_customizable /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:70:7 (libselinux.so.1+0x12d86) #1 restorecon_sb /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:696:10 (libselinux.so.1+0x24b41) #2 selinux_restorecon_thread /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:943:12 (libselinux.so.1+0x25695) Previous write of size 8 at 0x7f72252e5908 by thread T1: #0 get_customizable_type_list /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:58:11 (libselinux.so.1+0x13027) #1 is_context_customizable /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:71:7 (libselinux.so.1+0x13027) #2 restorecon_sb /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:696:10 (libselinux.so.1+0x24b41) #3 selinux_restorecon_thread /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:943:12 (libselinux.so.1+0x25695) Location is global 'customizable_list' of size 8 at 0x7f72252e5908 (libselinux.so.1+0x000000036908) Thread T3 (tid=4197, running) created by main thread at: #0 pthread_create <null> (setfiles+0x44c6ed) #1 selinux_restorecon_common /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1193:8 (libselinux.so.1+0x22ba6) #2 selinux_restorecon_parallel /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1310:9 (libselinux.so.1+0x22da2) #3 process_glob /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/restore.c:94:8 (setfiles+0x4c13b7) #4 main /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/setfiles.c:463:14 (setfiles+0x4c0938) Thread T1 (tid=4195, running) created by main thread at: #0 pthread_create <null> (setfiles+0x44c6ed) #1 selinux_restorecon_common /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1193:8 (libselinux.so.1+0x22ba6) #2 selinux_restorecon_parallel /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1310:9 (libselinux.so.1+0x22da2) #3 process_glob /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/restore.c:94:8 (setfiles+0x4c13b7) #4 main /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/setfiles.c:463:14 (setfiles+0x4c0938) SUMMARY: ThreadSanitizer: data race /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:70:7 in is_context_customizable ================== ================== WARNING: ThreadSanitizer: data race (pid=4189) Read of size 8 at 0x7b080000c000 by thread T3: #0 is_context_customizable /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:85:14 (libselinux.so.1+0x12ddc) #1 restorecon_sb /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:696:10 (libselinux.so.1+0x24b41) #2 selinux_restorecon_thread /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:943:12 (libselinux.so.1+0x25695) Previous write of size 8 at 0x7b080000c000 by thread T1: [failed to restore the stack] Location is heap block of size 32 at 0x7b080000c000 allocated by thread T1: #0 calloc <null> (setfiles+0x44b249) #1 get_customizable_type_list /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:34:17 (libselinux.so.1+0x12ed7) #2 is_context_customizable /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:71:7 (libselinux.so.1+0x12ed7) #3 restorecon_sb /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:696:10 (libselinux.so.1+0x24b41) #4 selinux_restorecon_thread /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:943:12 (libselinux.so.1+0x25695) Thread T3 (tid=4197, running) created by main thread at: #0 pthread_create <null> (setfiles+0x44c6ed) #1 selinux_restorecon_common /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1193:8 (libselinux.so.1+0x22ba6) #2 selinux_restorecon_parallel /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1310:9 (libselinux.so.1+0x22da2) #3 process_glob /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/restore.c:94:8 (setfiles+0x4c13b7) #4 main /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/setfiles.c:463:14 (setfiles+0x4c0938) Thread T1 (tid=4195, running) created by main thread at: #0 pthread_create <null> (setfiles+0x44c6ed) #1 selinux_restorecon_common /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1193:8 (libselinux.so.1+0x22ba6) #2 selinux_restorecon_parallel /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1310:9 (libselinux.so.1+0x22da2) #3 process_glob /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/restore.c:94:8 (setfiles+0x4c13b7) #4 main /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/setfiles.c:463:14 (setfiles+0x4c0938) SUMMARY: ThreadSanitizer: data race /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:85:14 in is_context_customizable ================== ================== WARNING: ThreadSanitizer: data race (pid=4189) Read of size 1 at 0x7b080000c040 by thread T3: #0 strcmp <null> (setfiles+0x4545d4) #1 is_context_customizable /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:86:7 (libselinux.so.1+0x12df7) #2 restorecon_sb /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:696:10 (libselinux.so.1+0x24b41) #3 selinux_restorecon_thread /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:943:12 (libselinux.so.1+0x25695) Previous write of size 8 at 0x7b080000c040 by thread T1: [failed to restore the stack] Location is heap block of size 17 at 0x7b080000c040 allocated by thread T1: #0 malloc <null> (setfiles+0x44b05d) #1 strdup <null> (libc.so.6+0x8e4aa) #2 get_customizable_type_list /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:41:15 (libselinux.so.1+0x12f45) #3 is_context_customizable /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:71:7 (libselinux.so.1+0x12f45) #4 restorecon_sb /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:696:10 (libselinux.so.1+0x24b41) #5 selinux_restorecon_thread /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:943:12 (libselinux.so.1+0x25695) Thread T3 (tid=4197, running) created by main thread at: #0 pthread_create <null> (setfiles+0x44c6ed) #1 selinux_restorecon_common /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1193:8 (libselinux.so.1+0x22ba6) #2 selinux_restorecon_parallel /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1310:9 (libselinux.so.1+0x22da2) #3 process_glob /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/restore.c:94:8 (setfiles+0x4c13b7) #4 main /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/setfiles.c:463:14 (setfiles+0x4c0938) Thread T1 (tid=4195, running) created by main thread at: #0 pthread_create <null> (setfiles+0x44c6ed) #1 selinux_restorecon_common /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1193:8 (libselinux.so.1+0x22ba6) #2 selinux_restorecon_parallel /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1310:9 (libselinux.so.1+0x22da2) #3 process_glob /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/restore.c:94:8 (setfiles+0x4c13b7) #4 main /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/setfiles.c:463:14 (setfiles+0x4c0938) SUMMARY: ThreadSanitizer: data race (/home/debianuser/destdir/sbin/setfiles+0x4545d4) in strcmp ================== ================== WARNING: ThreadSanitizer: data race (pid=4189) Read of size 8 at 0x7b080000c008 by thread T3: #0 is_context_customizable /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:85:14 (libselinux.so.1+0x12e07) #1 restorecon_sb /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:696:10 (libselinux.so.1+0x24b41) #2 selinux_restorecon_thread /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:943:12 (libselinux.so.1+0x25695) Previous write of size 8 at 0x7b080000c008 by thread T1: [failed to restore the stack] Location is heap block of size 32 at 0x7b080000c000 allocated by thread T1: #0 calloc <null> (setfiles+0x44b249) #1 get_customizable_type_list /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:34:17 (libselinux.so.1+0x12ed7) #2 is_context_customizable /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:71:7 (libselinux.so.1+0x12ed7) #3 restorecon_sb /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:696:10 (libselinux.so.1+0x24b41) #4 selinux_restorecon_thread /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:943:12 (libselinux.so.1+0x25695) Thread T3 (tid=4197, running) created by main thread at: #0 pthread_create <null> (setfiles+0x44c6ed) #1 selinux_restorecon_common /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1193:8 (libselinux.so.1+0x22ba6) #2 selinux_restorecon_parallel /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1310:9 (libselinux.so.1+0x22da2) #3 process_glob /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/restore.c:94:8 (setfiles+0x4c13b7) #4 main /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/setfiles.c:463:14 (setfiles+0x4c0938) Thread T1 (tid=4195, running) created by main thread at: #0 pthread_create <null> (setfiles+0x44c6ed) #1 selinux_restorecon_common /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1193:8 (libselinux.so.1+0x22ba6) #2 selinux_restorecon_parallel /home/debianuser/workspace/selinux/selinux/libselinux/src/selinux_restorecon.c:1310:9 (libselinux.so.1+0x22da2) #3 process_glob /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/restore.c:94:8 (setfiles+0x4c13b7) #4 main /home/debianuser/workspace/selinux/selinux/policycoreutils/setfiles/setfiles.c:463:14 (setfiles+0x4c0938) SUMMARY: ThreadSanitizer: data race /home/debianuser/workspace/selinux/selinux/libselinux/src/is_customizable_type.c:85:14 in is_context_customizable ================== > Changes v2->v3: > - add a patch to fix pre-exiting data race in label_file > - wait for threads to complete using pthread_join(3) to prevent thread leaks > > Changes v1->v2: > - make selinux_log() synchronized instead of introducing selinux_log_sync() > - fix -Wcomma warning > - update the swig files as well > - bump new symbol version to LIBSELINUX_3.3 (this may need further update > depending on when this gets merged) > > Ondrej Mosnacek (7): > label_file: fix a data race > selinux_restorecon: simplify fl_head allocation by using calloc() > selinux_restorecon: protect file_spec list with a mutex > libselinux: make selinux_log() thread-safe > selinux_restorecon: add a global mutex to synchronize progress output > selinux_restorecon: introduce selinux_restorecon_parallel(3) > setfiles/restorecon: support parallel relabeling > > libselinux/include/selinux/restorecon.h | 14 + > libselinux/man/man3/selinux_restorecon.3 | 29 ++ > .../man/man3/selinux_restorecon_parallel.3 | 1 + > libselinux/src/callbacks.c | 8 +- > libselinux/src/callbacks.h | 13 +- > libselinux/src/label_file.c | 15 +- > libselinux/src/label_file.h | 2 +- > libselinux/src/libselinux.map | 5 + > libselinux/src/selinux_internal.h | 16 + > libselinux/src/selinux_restorecon.c | 458 ++++++++++++------ > libselinux/src/selinuxswig_python.i | 6 +- > libselinux/src/selinuxswig_python_exception.i | 8 + > policycoreutils/setfiles/Makefile | 2 +- > policycoreutils/setfiles/restore.c | 7 +- > policycoreutils/setfiles/restore.h | 2 +- > policycoreutils/setfiles/restorecon.8 | 9 + > policycoreutils/setfiles/setfiles.8 | 9 + > policycoreutils/setfiles/setfiles.c | 28 +- > 18 files changed, 458 insertions(+), 174 deletions(-) > create mode 100644 libselinux/man/man3/selinux_restorecon_parallel.3 > > -- > 2.31.1 >