[PATCH v3 5/5] libselinux: update man pages for new thread safety guarantees

Stephen Smalley <[email protected]>
Newsgroups org.kernel.vger.selinux
Message-ID <[email protected]>
Document the new thread safety guarantees and callback constraints for
the AVC, class/perm string mapping, status page, and access checking
APIs.

Signed-off-by: Stephen Smalley <[email protected]>
---
 libselinux/man/man3/avc_add_callback.3        | 12 +++++++-
 libselinux/man/man3/avc_init.3                | 15 ++++++++--
 libselinux/man/man3/avc_netlink_loop.3        | 14 +++++++++
 libselinux/man/man3/avc_open.3                | 20 +++++++++++++
 .../man/man3/security_class_to_string.3       | 10 +++++++
 libselinux/man/man3/security_compute_av.3     | 20 +++++++++++--
 libselinux/man/man3/selinux_set_callback.3    | 29 +++++++++++++++++++
 libselinux/man/man3/selinux_status_open.3     | 22 ++++++++++++--
 8 files changed, 133 insertions(+), 9 deletions(-)

diff --git a/libselinux/man/man3/avc_add_callback.3 b/libselinux/man/man3/avc_add_callback.3
index bdbbadf1..ede2c907 100644
--- a/libselinux/man/man3/avc_add_callback.3
+++ b/libselinux/man/man3/avc_add_callback.3
@@ -177,7 +177,17 @@ may be executed in the context of the netlink handler thread.  This will likely
 
 Support for dynamic revocation and retained permissions is mostly unimplemented in the SELinux kernel module.  The only security event that currently gets exercised is
 .BR AVC_CALLBACK_RESET .
-.
+
+.B AVC_CALLBACK_RESET
+callbacks driven by
+.BR selinux_status_updated (3),
+(the default when no netlink handler thread is installed) run with the
+status lock held and must not call
+.BR selinux_status_updated (3),
+.BR selinux_status_getenforce (3)
+or
+.BR selinux_status_policyload (3).
+
 .SH "AUTHOR"
 Eamon Walsh <[email protected]>
 .
diff --git a/libselinux/man/man3/avc_init.3 b/libselinux/man/man3/avc_init.3
index a5dc7c93..9740b0ad 100644
--- a/libselinux/man/man3/avc_init.3
+++ b/libselinux/man/man3/avc_init.3
@@ -153,7 +153,18 @@ The
 .B func_free_lock
 callback should destroy
 .IR lock ,
-freeing any resources associated with it.  The default behavior is not to perform any locking.  Note that undefined behavior may result if threading is used without appropriate locking.
+freeing any resources associated with it.
+If
+.I lock_callbacks
+is NULL (as it always is for
+.BR avc_open (3)),
+the AVC uses an internal
+.BR pthread_mutex_t
+per lock.
+If an
+.B avc_lock_callback
+structure is supplied, all four callbacks must be non-NULL;
+supplying a subset is not supported.
 .
 .SH "KERNEL STATUS PAGE"
 Linux kernel version 2.6.37 supports the SELinux kernel status page, enabling userspace applications to
@@ -195,7 +206,7 @@ events will have the same results as for the status page implementation, but all
 
 By default,
 .BR avc_open (3)
-does not set threading or locking callbacks. In the fallback case, the userspace AVC checks for new netlink messages at the start of each permission query. If threading and locking callbacks are passed to
+does not set threading callbacks. In the fallback case, the userspace AVC checks for new netlink messages at the start of each permission query. If threading callbacks are passed to
 .BR avc_init (),
 a dedicated thread will be started to listen on the netlink socket.  This may increase performance in the absence of the status page and will ensure that log messages are generated immediately rather than at the time of the next permission query.
 .
diff --git a/libselinux/man/man3/avc_netlink_loop.3 b/libselinux/man/man3/avc_netlink_loop.3
index f03d7813..41928be6 100644
--- a/libselinux/man/man3/avc_netlink_loop.3
+++ b/libselinux/man/man3/avc_netlink_loop.3
@@ -83,6 +83,20 @@ with a return value return zero on success.  On error, \-1 is returned and
 .I errno
 is set appropriately.
 .
+.SH "NOTES"
+After
+.BR avc_netlink_acquire_fd (),
+the application owns the netlink socket.
+.BR avc_netlink_check_nb ()
+and
+.BR avc_netlink_loop()
+do not take the status lock that serializes
+.BR selinux_status_updated (3);
+the application is responsible for draining the socket from a single
+thread (or under its own lock), and should not mix direct netlink
+draining with concurrent calls to
+.BR selinux_status_updated (3).
+.
 .SH "AUTHOR"
 Originally KaiGai Kohei. Updated by Mike Palmiotto <[email protected]>
 .
diff --git a/libselinux/man/man3/avc_open.3 b/libselinux/man/man3/avc_open.3
index 74f85593..a02d7e0b 100644
--- a/libselinux/man/man3/avc_open.3
+++ b/libselinux/man/man3/avc_open.3
@@ -81,6 +81,26 @@ and
 .B policyload
 events will have the same results as for the status page implementation, but all status update checks will now require a system call.
 .
+.SH "THREAD SAFETY"
+The userspace AVC initialized by
+.BR avc_open (3)
+protects its shared state with internal pthread mutexes by default, so
+.BR avc_has_perm (3),
+.BR avc_context_to_sid (3),
+.BR avc_compute_create (3)
+and
+.BR selinux_check_access (3)
+may be called concurrently from multiple threads after a single
+.BR avc_open (3).
+The
+.B SELINUX_CB_LOG
+and
+.B SELINUX_CB_AUDIT
+callbacks (see
+.BR selinux_set_callback (3))
+are invoked while the audit-buffer lock is held and must not call back
+into the AVC.
+.
 .SH "RETURN VALUE"
 Functions with a return value return zero on success.  On error, \-1 is returned and
 .I errno
diff --git a/libselinux/man/man3/security_class_to_string.3 b/libselinux/man/man3/security_class_to_string.3
index 1b1b88d4..02afa093 100644
--- a/libselinux/man/man3/security_class_to_string.3
+++ b/libselinux/man/man3/security_class_to_string.3
@@ -86,6 +86,16 @@ A class or access vector argument is not recognized by the currently loaded poli
 .B ENOMEM
 An attempt to allocate memory failed.
 .
+.SH "THREAD SAFETY"
+These functions share a process-wide class/permission cache that is
+serialized internally. The string pointers returned by
+.BR security_class_to_string ()
+and
+.BR security_av_perm_to_string ()
+remain valid across concurrent calls to
+.BR selinux_flush_class_cache (3)
+for the lifetime of the process.
+.
 .SH "AUTHOR"
 Eamon Walsh <[email protected]>
 .
diff --git a/libselinux/man/man3/security_compute_av.3 b/libselinux/man/man3/security_compute_av.3
index af8797b5..98e53095 100644
--- a/libselinux/man/man3/security_compute_av.3
+++ b/libselinux/man/man3/security_compute_av.3
@@ -181,10 +181,24 @@ function.
 .SH "RETURN VALUE"
 Returns zero on success or \-1 on error.
 .
-.SH "CAVEATS"
+.SH "THREAD SAFETY"
 .sp
-These functions are not thread-safe, you have to protect them from
-concurrent calls using exclusive locks when multiple threads are executing.
+.BR selinux_check_access ()
+may be called concurrently from multiple threads; the underlying
+AVC and SELinux status page interfaces serialize their shared
+state internally. See the re-entrancy constraints for
+.B SELINUX_CB_LOG
+/
+.B SELINUX_CB_AUDIT
+/
+.B SELINUX_CB_SETENFORCE
+/
+.B SELINUX_CB_POLICYLOAD
+in
+.BR selinux_set_callback (3).
+.
+The remaining security_compute_* ()
+functions are direct kernel queries with no shared userspace state.
 .
 .SH "SEE ALSO"
 .BR string_to_security_class (3),
diff --git a/libselinux/man/man3/selinux_set_callback.3 b/libselinux/man/man3/selinux_set_callback.3
index 75f49b06..9bdc5573 100644
--- a/libselinux/man/man3/selinux_set_callback.3
+++ b/libselinux/man/man3/selinux_set_callback.3
@@ -116,6 +116,35 @@ The
 .I seqno
 argument is the current sequential number of the policy generation in the system.
 .
+.SH "NOTES"
+Callbacks run while a library-internal lock is held and must not call back
+into the interfaces that lock protects:
+.B SELINUX_CB_LOG
+and
+.B SELINUX_CB_AUDIT
+are invoked from
+.BR avc_audit (3)
+with the audit-buffer lock held and must not call any function that reaches
+the userspace AVC (e.g.
+.BR avc_has_perm (3),
+.BR selinux_check_access (3));
+.B SELINUX_CB_SETENFORCE
+and
+.B SELINUX_CB_POLICYLOAD
+are invoked from
+.BR selinux_status_updated (3)
+with the status lock held and must not call
+.BR selinux_status_updated (3),
+.BR selinux_status_getenforce (3)
+or
+.BR selinux_status_policyload (3);
+.B SELINUX_CB_VALIDATE
+is invoked from
+.BR selabel_lookup (3)
+with a per-specification lock held and must not call
+.BR selabel_lookup (3)
+on the same handle.
+.
 .SH "RETURN VALUE"
 None.
 .
diff --git a/libselinux/man/man3/selinux_status_open.3 b/libselinux/man/man3/selinux_status_open.3
index 5592487f..696677ed 100644
--- a/libselinux/man/man3/selinux_status_open.3
+++ b/libselinux/man/man3/selinux_status_open.3
@@ -92,10 +92,26 @@ On error, \-1 shall be returned.
 Any other functions with a return value shall return its characteristic
 value as described above, or \-1 on errors.
 .
-.SH "CAVEATS"
+.SH "THREAD SAFETY"
 .sp
-These functions are not thread-safe, you have to protect them from
-concurrent calls using exclusive locks when multiple threads are executing.
+.BR selinux_status_updated (),
+.BR selinux_status_getenforce ()
+and
+.BR selinux_status_policyload ()
+are serialized internally and may be called concurrently from
+multiple threads. For a given setenforce or policyload event the
+.B SELINUX_CB_SETENFORCE
+/
+.B SELINUX_CB_POLICYLOAD
+callbacks (see
+.BR selinux_set_callback(3))
+and any registered
+.B AVC_CALLBACK_RESET
+callbacks are invoked exactly once.
+.BR selinux_status_open ()
+and
+.BR selinux_status_close ()
+are not serialized against concurrent callers of the other functions.
 .
 .SH "SEE ALSO"
 .ad l
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.