Module: xenomai-forge
Branch: next
Commit: 72c842c7c129c91784a7157e58890f46708dcc33
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=72c842c7c129c91784a7157e58890f46708dcc33

Author: Philippe Gerum <r...@xenomai.org>
Date:   Wed May  7 11:53:20 2014 +0200

cobalt/signal: fix memory leakage

Make sure the signal data (struct cobalt_sigpending) is freed when
cobalt_signal_send() decides not to queue it.

---

 kernel/cobalt/posix/mqueue.c |    3 ++-
 kernel/cobalt/posix/signal.c |   32 ++++++++++++++++++++------------
 kernel/cobalt/posix/signal.h |    2 ++
 3 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/kernel/cobalt/posix/mqueue.c b/kernel/cobalt/posix/mqueue.c
index 395eaf2..a3154d1 100644
--- a/kernel/cobalt/posix/mqueue.c
+++ b/kernel/cobalt/posix/mqueue.c
@@ -657,7 +657,8 @@ cobalt_mq_finish_send(mqd_t fd, cobalt_mq_t *mq, struct 
cobalt_msg *msg)
                                sigp = cobalt_signal_alloc();
                                if (sigp) {
                                        cobalt_copy_siginfo(SI_MESGQ, 
&sigp->si, &mq->si);
-                                       cobalt_signal_send(mq->target, sigp, 0);
+                                       if (cobalt_signal_send(mq->target, 
sigp, 0) <= 0)
+                                               cobalt_signal_free(sigp);
                                }
                                mq->target = NULL;
                        }
diff --git a/kernel/cobalt/posix/signal.c b/kernel/cobalt/posix/signal.c
index 15171e1..d24cbf9 100644
--- a/kernel/cobalt/posix/signal.c
+++ b/kernel/cobalt/posix/signal.c
@@ -89,9 +89,7 @@ deliver:
         * have to release the sigpending data right away before
         * leaving.
         */
-       if ((void *)sigp >= sigpending_mem &&
-           (void *)sigp < sigpending_mem + __SIGPOOL_SIZE)
-               list_add_tail(&sigp->next, &sigpending_pool);
+       cobalt_signal_free(sigp);
 
        return 1;
 }
@@ -106,17 +104,16 @@ int cobalt_signal_send(struct cobalt_thread *thread,
        /* Can we deliver this signal immediately? */
        ret = cobalt_signal_deliver(thread, sigp, group);
        if (ret)
-               return 0;       /* Yep, done. */
+               return ret;     /* Yep, done. */
 
        /*
         * Nope, attempt to queue it. We start by calling any Cobalt
         * extension for queuing the signal first.
         */
        if (cobalt_call_extension(signal_queue, &thread->extref, ret, sigp)) {
-               if (ret < 0)
-                       return ret; /* Error. */
-               if (ret > 0)
-                       return 0; /* Queuing done. */
+               if (ret)
+                       /* Queuing done remotely or error. */
+                       return ret;
        }
 
        sig = sigp->si.si_signo;
@@ -133,7 +130,7 @@ int cobalt_signal_send(struct cobalt_thread *thread,
        sigaddset(&thread->sigpending, sig);
        list_add_tail(&sigp->next, sigq);
 
-       return 0;
+       return 1;
 }
 EXPORT_SYMBOL_GPL(cobalt_signal_send);
 
@@ -166,6 +163,14 @@ struct cobalt_sigpending *cobalt_signal_alloc(void)
 }
 EXPORT_SYMBOL_GPL(cobalt_signal_alloc);
 
+void cobalt_signal_free(struct cobalt_sigpending *sigp)
+{                              /* nklocked, IRQs off */
+       if ((void *)sigp >= sigpending_mem &&
+           (void *)sigp < sigpending_mem + __SIGPOOL_SIZE)
+               list_add_tail(&sigp->next, &sigpending_pool);
+}
+EXPORT_SYMBOL_GPL(cobalt_signal_free);
+
 void cobalt_signal_flush(struct cobalt_thread *thread)
 {
        struct cobalt_sigpending *sigp, *tmp;
@@ -461,7 +466,8 @@ int __cobalt_kill(struct cobalt_thread *thread, int sig, 
int group) /* nklocked,
                        sigp->si.si_code = SI_USER;
                        sigp->si.si_pid = current->pid;
                        sigp->si.si_uid = get_current_uuid();
-                       cobalt_signal_send(thread, sigp, group);
+                       if (cobalt_signal_send(thread, sigp, group) <= 0)
+                               cobalt_signal_free(sigp);
                }
        resched:
                xnsched_run();
@@ -525,8 +531,10 @@ int cobalt_sigqueue(pid_t pid, int sig,
                        sigp->si.si_pid = current->pid;
                        sigp->si.si_uid = get_current_uuid();
                        sigp->si.si_value = val;
-                       cobalt_signal_send(thread, sigp, 1);
-                       xnsched_run();
+                       if (cobalt_signal_send(thread, sigp, 1) <= 0)
+                               cobalt_signal_free(sigp);
+                       else
+                               xnsched_run();
                }
                break;
        default:
diff --git a/kernel/cobalt/posix/signal.h b/kernel/cobalt/posix/signal.h
index 9ad3c9e..ed2f387 100644
--- a/kernel/cobalt/posix/signal.h
+++ b/kernel/cobalt/posix/signal.h
@@ -63,6 +63,8 @@ int cobalt_signal_send_pid(pid_t pid,
 
 struct cobalt_sigpending *cobalt_signal_alloc(void);
 
+void cobalt_signal_free(struct cobalt_sigpending *sigp);
+
 void cobalt_signal_flush(struct cobalt_thread *thread);
 
 int cobalt_signal_wait(sigset_t *set, struct siginfo *si,


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to