This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 7a137f0353 syslog: Don't allow blocking when in signal handler
7a137f0353 is described below

commit 7a137f03539181ef47cad0610e871470b1cfd0ab
Author: Ville Juven <[email protected]>
AuthorDate: Tue Oct 22 16:09:31 2024 +0300

    syslog: Don't allow blocking when in signal handler
    
    Blocking while running a signal handler is not advisable, instead write
    the log string character by character.
    
    There is also a potential for a deadlock, as discussed in #6618
    
    Note: querying for rtcb->sigdeliver is not 100% ideal, as it only tells
    _if_ a signal handler has been queued, not if it is running. However, it
    makes syslog safe / usable which is a debug feature anyhow.
---
 drivers/syslog/syslog_write.c | 39 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/syslog/syslog_write.c b/drivers/syslog/syslog_write.c
index 2573384050..f8d8ae739f 100644
--- a/drivers/syslog/syslog_write.c
+++ b/drivers/syslog/syslog_write.c
@@ -37,6 +37,43 @@
  * Private Functions
  ****************************************************************************/
 
+/****************************************************************************
+ * Name: syslog_safe_to_block
+ *
+ * Description:
+ *   Check if it is safe to block for write. If not, the write  defaults to a
+ *   non-blocking method.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   true if it is safe to block; false otherwise.
+ *
+ ****************************************************************************/
+
+static bool syslog_safe_to_block(void)
+{
+  FAR const struct tcb_s *rtcb;
+
+  /* It's not safe to block in interrupts or when executing the idle loop */
+
+  if (up_interrupt_context() || sched_idletask())
+    {
+      return false;
+    }
+
+  /* It's not safe to block if a signal is being delivered */
+
+  rtcb = nxsched_self();
+  if (rtcb->sigdeliver != NULL)
+    {
+      return false;
+    }
+
+  return true;
+}
+
 /****************************************************************************
  * Name: syslog_default_write
  *
@@ -59,7 +96,7 @@ static ssize_t syslog_default_write(FAR const char *buffer, 
size_t buflen)
 {
   size_t nwritten;
 
-  if (up_interrupt_context() || sched_idletask())
+  if (!syslog_safe_to_block())
     {
 #ifdef CONFIG_SYSLOG_INTBUFFER
       if (up_interrupt_context())

Reply via email to