[Xenomai-git] Gilles Chanteperdrix : cobalt/process: avoid crash at fork

2015-11-01 Thread git repository hosting
Module: xenomai-3
Branch: master
Commit: e30f30df631fff143233732cf21756fe2f29c7dc
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=e30f30df631fff143233732cf21756fe2f29c7dc

Author: Gilles Chanteperdrix 
Date:   Sun Oct 11 23:29:47 2015 +0200

cobalt/process: avoid crash at fork

When handle_cleanup_event() is called because a thread is calling exec
after a fork from a Xenomai process, handle_taskexit_event() is called
before remove_process(). However, handle_taskexit_event() calls
clear_threadinfo(), so that later calls to cobalt_current_process()
return NULL, causing crashes in cleanup functions relying on
cobalt_current_process() or cobalt_ppd_get(), such as
cobalt_mutex_reclaim().

---

 kernel/cobalt/posix/process.c |   23 ++-
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
index e7f8a93..c5a3297 100644
--- a/kernel/cobalt/posix/process.c
+++ b/kernel/cobalt/posix/process.c
@@ -200,7 +200,8 @@ static void remove_process(struct cobalt_process *process)
 * upon return from detach_process() for the Cobalt
 * personality, so don't dereference it afterwards.
 */
-   process->priv[xid] = NULL;
+   if (xid)
+   process->priv[xid] = NULL;
__clear_bit(personality->xid, >permap);
personality->ops.detach_process(priv);
atomic_dec(>refcnt);
@@ -1006,7 +1007,7 @@ static void unregister_debugged_thread(struct xnthread 
*thread)
xnlock_put_irqrestore(, s);
 }
 
-static int handle_taskexit_event(struct task_struct *p) /* p == current */
+static void __handle_taskexit_event(struct task_struct *p)
 {
struct cobalt_ppd *sys_ppd;
struct xnthread *thread;
@@ -1036,13 +1037,18 @@ static int handle_taskexit_event(struct task_struct *p) 
/* p == current */
if (atomic_dec_and_test(_ppd->refcnt))
remove_process(cobalt_current_process());
}
+}
+
+static int handle_taskexit_event(struct task_struct *p) /* p == current */
+{
+   __handle_taskexit_event(p);
 
/*
 * __xnthread_cleanup() -> ... -> finalize_thread
 * handler. From that point, the TCB is dropped. Be careful of
 * not treading on stale memory within @thread.
 */
-   __xnthread_cleanup(thread);
+   __xnthread_cleanup(xnthread_current());
 
clear_threadinfo();
 
@@ -1198,6 +1204,8 @@ static int handle_cleanup_event(struct mm_struct *mm)
old = cobalt_set_process(process);
sys_ppd = cobalt_ppd_get(0);
if (sys_ppd != _kernel_ppd) {
+   bool running_exec;
+
/*
 * Detect a userland shadow running exec(), i.e. still
 * attached to the current linux task (no prior
@@ -1208,12 +1216,17 @@ static int handle_cleanup_event(struct mm_struct *mm)
 * notifier manually for it.
 */
thread = xnthread_current();
-   if (thread && (current->flags & PF_EXITING) == 0) {
-   handle_taskexit_event(current);
+   running_exec = thread && (current->flags & PF_EXITING) == 0;
+   if (running_exec) {
+   __handle_taskexit_event(current);
ipipe_disable_notifier(current);
}
if (atomic_dec_and_test(_ppd->refcnt))
remove_process(process);
+   if (running_exec) {
+   __xnthread_cleanup(thread);
+   clear_threadinfo();
+   }
}
 
/*


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


[Xenomai-git] Gilles Chanteperdrix : cobalt/process: avoid crash at fork

2015-10-17 Thread git repository hosting
Module: xenomai-3
Branch: arm64
Commit: e30f30df631fff143233732cf21756fe2f29c7dc
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=e30f30df631fff143233732cf21756fe2f29c7dc

Author: Gilles Chanteperdrix 
Date:   Sun Oct 11 23:29:47 2015 +0200

cobalt/process: avoid crash at fork

When handle_cleanup_event() is called because a thread is calling exec
after a fork from a Xenomai process, handle_taskexit_event() is called
before remove_process(). However, handle_taskexit_event() calls
clear_threadinfo(), so that later calls to cobalt_current_process()
return NULL, causing crashes in cleanup functions relying on
cobalt_current_process() or cobalt_ppd_get(), such as
cobalt_mutex_reclaim().

---

 kernel/cobalt/posix/process.c |   23 ++-
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
index e7f8a93..c5a3297 100644
--- a/kernel/cobalt/posix/process.c
+++ b/kernel/cobalt/posix/process.c
@@ -200,7 +200,8 @@ static void remove_process(struct cobalt_process *process)
 * upon return from detach_process() for the Cobalt
 * personality, so don't dereference it afterwards.
 */
-   process->priv[xid] = NULL;
+   if (xid)
+   process->priv[xid] = NULL;
__clear_bit(personality->xid, >permap);
personality->ops.detach_process(priv);
atomic_dec(>refcnt);
@@ -1006,7 +1007,7 @@ static void unregister_debugged_thread(struct xnthread 
*thread)
xnlock_put_irqrestore(, s);
 }
 
-static int handle_taskexit_event(struct task_struct *p) /* p == current */
+static void __handle_taskexit_event(struct task_struct *p)
 {
struct cobalt_ppd *sys_ppd;
struct xnthread *thread;
@@ -1036,13 +1037,18 @@ static int handle_taskexit_event(struct task_struct *p) 
/* p == current */
if (atomic_dec_and_test(_ppd->refcnt))
remove_process(cobalt_current_process());
}
+}
+
+static int handle_taskexit_event(struct task_struct *p) /* p == current */
+{
+   __handle_taskexit_event(p);
 
/*
 * __xnthread_cleanup() -> ... -> finalize_thread
 * handler. From that point, the TCB is dropped. Be careful of
 * not treading on stale memory within @thread.
 */
-   __xnthread_cleanup(thread);
+   __xnthread_cleanup(xnthread_current());
 
clear_threadinfo();
 
@@ -1198,6 +1204,8 @@ static int handle_cleanup_event(struct mm_struct *mm)
old = cobalt_set_process(process);
sys_ppd = cobalt_ppd_get(0);
if (sys_ppd != _kernel_ppd) {
+   bool running_exec;
+
/*
 * Detect a userland shadow running exec(), i.e. still
 * attached to the current linux task (no prior
@@ -1208,12 +1216,17 @@ static int handle_cleanup_event(struct mm_struct *mm)
 * notifier manually for it.
 */
thread = xnthread_current();
-   if (thread && (current->flags & PF_EXITING) == 0) {
-   handle_taskexit_event(current);
+   running_exec = thread && (current->flags & PF_EXITING) == 0;
+   if (running_exec) {
+   __handle_taskexit_event(current);
ipipe_disable_notifier(current);
}
if (atomic_dec_and_test(_ppd->refcnt))
remove_process(process);
+   if (running_exec) {
+   __xnthread_cleanup(thread);
+   clear_threadinfo();
+   }
}
 
/*


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


[Xenomai-git] Gilles Chanteperdrix : cobalt/process: avoid crash at fork

2015-10-15 Thread git repository hosting
Module: xenomai-gch
Branch: for-forge
Commit: c1438a3814958924f43d5ac278a02a57a61cb701
URL:
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=c1438a3814958924f43d5ac278a02a57a61cb701

Author: Gilles Chanteperdrix 
Date:   Sun Oct 11 23:29:47 2015 +0200

cobalt/process: avoid crash at fork

When handle_cleanup_event() is called because a thread is calling exec
after a fork from a Xenomai process, handle_taskexit_event() is called
before remove_process(). However, handle_taskexit_event() calls
clear_threadinfo(), so that later calls to cobalt_current_process()
return NULL, causing crashes in cleanup functions relying on
cobalt_current_process() or cobalt_ppd_get(), such as
cobalt_mutex_reclaim().

---

 kernel/cobalt/posix/process.c |   29 ++---
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
index e7f8a93..6c6f868 100644
--- a/kernel/cobalt/posix/process.c
+++ b/kernel/cobalt/posix/process.c
@@ -200,7 +200,8 @@ static void remove_process(struct cobalt_process *process)
 * upon return from detach_process() for the Cobalt
 * personality, so don't dereference it afterwards.
 */
-   process->priv[xid] = NULL;
+   if (xid)
+   process->priv[xid] = NULL;
__clear_bit(personality->xid, >permap);
personality->ops.detach_process(priv);
atomic_dec(>refcnt);
@@ -1006,7 +1007,7 @@ static void unregister_debugged_thread(struct xnthread 
*thread)
xnlock_put_irqrestore(, s);
 }
 
-static int handle_taskexit_event(struct task_struct *p) /* p == current */
+static void __handle_taskexit_event(struct task_struct *p)
 {
struct cobalt_ppd *sys_ppd;
struct xnthread *thread;
@@ -1033,16 +1034,22 @@ static int handle_taskexit_event(struct task_struct *p) 
/* p == current */
cobalt_umm_free(_kernel_ppd.umm, thread->u_window);
thread->u_window = NULL;
sys_ppd = cobalt_ppd_get(0);
-   if (atomic_dec_and_test(_ppd->refcnt))
+   if (atomic_dec_and_test(_ppd->refcnt)) {
remove_process(cobalt_current_process());
+   }
}
+}
+
+static int handle_taskexit_event(struct task_struct *p) /* p == current */
+{
+   __handle_taskexit_event(p);
 
/*
 * __xnthread_cleanup() -> ... -> finalize_thread
 * handler. From that point, the TCB is dropped. Be careful of
 * not treading on stale memory within @thread.
 */
-   __xnthread_cleanup(thread);
+   __xnthread_cleanup(xnthread_current());
 
clear_threadinfo();
 
@@ -1198,6 +1205,8 @@ static int handle_cleanup_event(struct mm_struct *mm)
old = cobalt_set_process(process);
sys_ppd = cobalt_ppd_get(0);
if (sys_ppd != _kernel_ppd) {
+   bool running_exec;
+
/*
 * Detect a userland shadow running exec(), i.e. still
 * attached to the current linux task (no prior
@@ -1208,12 +1217,18 @@ static int handle_cleanup_event(struct mm_struct *mm)
 * notifier manually for it.
 */
thread = xnthread_current();
-   if (thread && (current->flags & PF_EXITING) == 0) {
-   handle_taskexit_event(current);
+   running_exec = thread && (current->flags & PF_EXITING) == 0;
+   if (running_exec) {
+   __handle_taskexit_event(current);
ipipe_disable_notifier(current);
}
-   if (atomic_dec_and_test(_ppd->refcnt))
+   if (atomic_dec_and_test(_ppd->refcnt)) {
remove_process(process);
+   if (running_exec) {
+   __xnthread_cleanup(thread);
+   clear_threadinfo();
+   }
+   }
}
 
/*


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


[Xenomai-git] Gilles Chanteperdrix : cobalt/process: avoid crash at fork

2015-10-15 Thread git repository hosting
Module: xenomai-gch
Branch: for-forge
Commit: 91315a0947ac7d002af6ad0447d0e870d44a6bfa
URL:
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=91315a0947ac7d002af6ad0447d0e870d44a6bfa

Author: Gilles Chanteperdrix 
Date:   Sun Oct 11 23:29:47 2015 +0200

cobalt/process: avoid crash at fork

When handle_cleanup_event() is called because a thread is calling exec
after a fork from a Xenomai process, handle_taskexit_event() is called
before remove_process(). However, handle_taskexit_event() calls
clear_threadinfo(), so that later calls to cobalt_current_process()
return NULL, causing crashes in cleanup functions relying on
cobalt_current_process() or cobalt_ppd_get(), such as
cobalt_mutex_reclaim().

---

 kernel/cobalt/posix/process.c |   23 ++-
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
index e7f8a93..c5a3297 100644
--- a/kernel/cobalt/posix/process.c
+++ b/kernel/cobalt/posix/process.c
@@ -200,7 +200,8 @@ static void remove_process(struct cobalt_process *process)
 * upon return from detach_process() for the Cobalt
 * personality, so don't dereference it afterwards.
 */
-   process->priv[xid] = NULL;
+   if (xid)
+   process->priv[xid] = NULL;
__clear_bit(personality->xid, >permap);
personality->ops.detach_process(priv);
atomic_dec(>refcnt);
@@ -1006,7 +1007,7 @@ static void unregister_debugged_thread(struct xnthread 
*thread)
xnlock_put_irqrestore(, s);
 }
 
-static int handle_taskexit_event(struct task_struct *p) /* p == current */
+static void __handle_taskexit_event(struct task_struct *p)
 {
struct cobalt_ppd *sys_ppd;
struct xnthread *thread;
@@ -1036,13 +1037,18 @@ static int handle_taskexit_event(struct task_struct *p) 
/* p == current */
if (atomic_dec_and_test(_ppd->refcnt))
remove_process(cobalt_current_process());
}
+}
+
+static int handle_taskexit_event(struct task_struct *p) /* p == current */
+{
+   __handle_taskexit_event(p);
 
/*
 * __xnthread_cleanup() -> ... -> finalize_thread
 * handler. From that point, the TCB is dropped. Be careful of
 * not treading on stale memory within @thread.
 */
-   __xnthread_cleanup(thread);
+   __xnthread_cleanup(xnthread_current());
 
clear_threadinfo();
 
@@ -1198,6 +1204,8 @@ static int handle_cleanup_event(struct mm_struct *mm)
old = cobalt_set_process(process);
sys_ppd = cobalt_ppd_get(0);
if (sys_ppd != _kernel_ppd) {
+   bool running_exec;
+
/*
 * Detect a userland shadow running exec(), i.e. still
 * attached to the current linux task (no prior
@@ -1208,12 +1216,17 @@ static int handle_cleanup_event(struct mm_struct *mm)
 * notifier manually for it.
 */
thread = xnthread_current();
-   if (thread && (current->flags & PF_EXITING) == 0) {
-   handle_taskexit_event(current);
+   running_exec = thread && (current->flags & PF_EXITING) == 0;
+   if (running_exec) {
+   __handle_taskexit_event(current);
ipipe_disable_notifier(current);
}
if (atomic_dec_and_test(_ppd->refcnt))
remove_process(process);
+   if (running_exec) {
+   __xnthread_cleanup(thread);
+   clear_threadinfo();
+   }
}
 
/*


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


[Xenomai-git] Gilles Chanteperdrix : cobalt/process: avoid crash at fork

2015-10-15 Thread git repository hosting
Module: xenomai-gch
Branch: for-forge
Commit: 2840c876f0cf9c5da7b47cafd70646ea9ed64a13
URL:
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=2840c876f0cf9c5da7b47cafd70646ea9ed64a13

Author: Gilles Chanteperdrix 
Date:   Sun Oct 11 23:29:47 2015 +0200

cobalt/process: avoid crash at fork

When handle_cleanup_event() is called because a thread is calling exec
after a fork from a Xenomai process, handle_taskexit_event() is called
before remove_process(). However, handle_taskexit_event() calls
clear_threadinfo(), so that later calls to cobalt_current_process()
return NULL, causing crashes in cleanup functions relying on
cobalt_current_process() or cobalt_ppd_get(), such as
cobalt_mutex_reclaim().

---

 kernel/cobalt/posix/process.c |   23 ++-
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
index e7f8a93..08d1477 100644
--- a/kernel/cobalt/posix/process.c
+++ b/kernel/cobalt/posix/process.c
@@ -200,7 +200,8 @@ static void remove_process(struct cobalt_process *process)
 * upon return from detach_process() for the Cobalt
 * personality, so don't dereference it afterwards.
 */
-   process->priv[xid] = NULL;
+   if (xid)
+   process->priv[xid] = NULL;
__clear_bit(personality->xid, >permap);
personality->ops.detach_process(priv);
atomic_dec(>refcnt);
@@ -1006,7 +1007,7 @@ static void unregister_debugged_thread(struct xnthread 
*thread)
xnlock_put_irqrestore(, s);
 }
 
-static int handle_taskexit_event(struct task_struct *p) /* p == current */
+static void __handle_taskexit_event(struct task_struct *p)
 {
struct cobalt_ppd *sys_ppd;
struct xnthread *thread;
@@ -1036,13 +1037,18 @@ static int handle_taskexit_event(struct task_struct *p) 
/* p == current */
if (atomic_dec_and_test(_ppd->refcnt))
remove_process(cobalt_current_process());
}
+}
+
+static int handle_taskexit_event(struct task_struct *p) /* p == current */
+{
+   __handle_taskexit_event(p);
 
/*
 * __xnthread_cleanup() -> ... -> finalize_thread
 * handler. From that point, the TCB is dropped. Be careful of
 * not treading on stale memory within @thread.
 */
-   __xnthread_cleanup(thread);
+   __xnthread_cleanup(p);
 
clear_threadinfo();
 
@@ -1198,6 +1204,8 @@ static int handle_cleanup_event(struct mm_struct *mm)
old = cobalt_set_process(process);
sys_ppd = cobalt_ppd_get(0);
if (sys_ppd != _kernel_ppd) {
+   bool running_exec;
+
/*
 * Detect a userland shadow running exec(), i.e. still
 * attached to the current linux task (no prior
@@ -1208,12 +1216,17 @@ static int handle_cleanup_event(struct mm_struct *mm)
 * notifier manually for it.
 */
thread = xnthread_current();
-   if (thread && (current->flags & PF_EXITING) == 0) {
-   handle_taskexit_event(current);
+   running_exec = thread && (current->flags & PF_EXITING) == 0;
+   if (running_exec) {
+   __handle_taskexit_event(current);
ipipe_disable_notifier(current);
}
if (atomic_dec_and_test(_ppd->refcnt))
remove_process(process);
+   if (running_exec) {
+   __xnthread_cleanup(thread);
+   clear_threadinfo();
+   }
}
 
/*


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


[Xenomai-git] Gilles Chanteperdrix : cobalt/process: avoid crash at fork

2015-10-15 Thread git repository hosting
Module: xenomai-3
Branch: next
Commit: e30f30df631fff143233732cf21756fe2f29c7dc
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=e30f30df631fff143233732cf21756fe2f29c7dc

Author: Gilles Chanteperdrix 
Date:   Sun Oct 11 23:29:47 2015 +0200

cobalt/process: avoid crash at fork

When handle_cleanup_event() is called because a thread is calling exec
after a fork from a Xenomai process, handle_taskexit_event() is called
before remove_process(). However, handle_taskexit_event() calls
clear_threadinfo(), so that later calls to cobalt_current_process()
return NULL, causing crashes in cleanup functions relying on
cobalt_current_process() or cobalt_ppd_get(), such as
cobalt_mutex_reclaim().

---

 kernel/cobalt/posix/process.c |   23 ++-
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
index e7f8a93..c5a3297 100644
--- a/kernel/cobalt/posix/process.c
+++ b/kernel/cobalt/posix/process.c
@@ -200,7 +200,8 @@ static void remove_process(struct cobalt_process *process)
 * upon return from detach_process() for the Cobalt
 * personality, so don't dereference it afterwards.
 */
-   process->priv[xid] = NULL;
+   if (xid)
+   process->priv[xid] = NULL;
__clear_bit(personality->xid, >permap);
personality->ops.detach_process(priv);
atomic_dec(>refcnt);
@@ -1006,7 +1007,7 @@ static void unregister_debugged_thread(struct xnthread 
*thread)
xnlock_put_irqrestore(, s);
 }
 
-static int handle_taskexit_event(struct task_struct *p) /* p == current */
+static void __handle_taskexit_event(struct task_struct *p)
 {
struct cobalt_ppd *sys_ppd;
struct xnthread *thread;
@@ -1036,13 +1037,18 @@ static int handle_taskexit_event(struct task_struct *p) 
/* p == current */
if (atomic_dec_and_test(_ppd->refcnt))
remove_process(cobalt_current_process());
}
+}
+
+static int handle_taskexit_event(struct task_struct *p) /* p == current */
+{
+   __handle_taskexit_event(p);
 
/*
 * __xnthread_cleanup() -> ... -> finalize_thread
 * handler. From that point, the TCB is dropped. Be careful of
 * not treading on stale memory within @thread.
 */
-   __xnthread_cleanup(thread);
+   __xnthread_cleanup(xnthread_current());
 
clear_threadinfo();
 
@@ -1198,6 +1204,8 @@ static int handle_cleanup_event(struct mm_struct *mm)
old = cobalt_set_process(process);
sys_ppd = cobalt_ppd_get(0);
if (sys_ppd != _kernel_ppd) {
+   bool running_exec;
+
/*
 * Detect a userland shadow running exec(), i.e. still
 * attached to the current linux task (no prior
@@ -1208,12 +1216,17 @@ static int handle_cleanup_event(struct mm_struct *mm)
 * notifier manually for it.
 */
thread = xnthread_current();
-   if (thread && (current->flags & PF_EXITING) == 0) {
-   handle_taskexit_event(current);
+   running_exec = thread && (current->flags & PF_EXITING) == 0;
+   if (running_exec) {
+   __handle_taskexit_event(current);
ipipe_disable_notifier(current);
}
if (atomic_dec_and_test(_ppd->refcnt))
remove_process(process);
+   if (running_exec) {
+   __xnthread_cleanup(thread);
+   clear_threadinfo();
+   }
}
 
/*


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


[Xenomai-git] Gilles Chanteperdrix : cobalt/process: avoid crash at fork

2015-10-15 Thread git repository hosting
Module: xenomai-gch
Branch: for-forge
Commit: e30f30df631fff143233732cf21756fe2f29c7dc
URL:
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=e30f30df631fff143233732cf21756fe2f29c7dc

Author: Gilles Chanteperdrix 
Date:   Sun Oct 11 23:29:47 2015 +0200

cobalt/process: avoid crash at fork

When handle_cleanup_event() is called because a thread is calling exec
after a fork from a Xenomai process, handle_taskexit_event() is called
before remove_process(). However, handle_taskexit_event() calls
clear_threadinfo(), so that later calls to cobalt_current_process()
return NULL, causing crashes in cleanup functions relying on
cobalt_current_process() or cobalt_ppd_get(), such as
cobalt_mutex_reclaim().

---

 kernel/cobalt/posix/process.c |   23 ++-
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
index e7f8a93..c5a3297 100644
--- a/kernel/cobalt/posix/process.c
+++ b/kernel/cobalt/posix/process.c
@@ -200,7 +200,8 @@ static void remove_process(struct cobalt_process *process)
 * upon return from detach_process() for the Cobalt
 * personality, so don't dereference it afterwards.
 */
-   process->priv[xid] = NULL;
+   if (xid)
+   process->priv[xid] = NULL;
__clear_bit(personality->xid, >permap);
personality->ops.detach_process(priv);
atomic_dec(>refcnt);
@@ -1006,7 +1007,7 @@ static void unregister_debugged_thread(struct xnthread 
*thread)
xnlock_put_irqrestore(, s);
 }
 
-static int handle_taskexit_event(struct task_struct *p) /* p == current */
+static void __handle_taskexit_event(struct task_struct *p)
 {
struct cobalt_ppd *sys_ppd;
struct xnthread *thread;
@@ -1036,13 +1037,18 @@ static int handle_taskexit_event(struct task_struct *p) 
/* p == current */
if (atomic_dec_and_test(_ppd->refcnt))
remove_process(cobalt_current_process());
}
+}
+
+static int handle_taskexit_event(struct task_struct *p) /* p == current */
+{
+   __handle_taskexit_event(p);
 
/*
 * __xnthread_cleanup() -> ... -> finalize_thread
 * handler. From that point, the TCB is dropped. Be careful of
 * not treading on stale memory within @thread.
 */
-   __xnthread_cleanup(thread);
+   __xnthread_cleanup(xnthread_current());
 
clear_threadinfo();
 
@@ -1198,6 +1204,8 @@ static int handle_cleanup_event(struct mm_struct *mm)
old = cobalt_set_process(process);
sys_ppd = cobalt_ppd_get(0);
if (sys_ppd != _kernel_ppd) {
+   bool running_exec;
+
/*
 * Detect a userland shadow running exec(), i.e. still
 * attached to the current linux task (no prior
@@ -1208,12 +1216,17 @@ static int handle_cleanup_event(struct mm_struct *mm)
 * notifier manually for it.
 */
thread = xnthread_current();
-   if (thread && (current->flags & PF_EXITING) == 0) {
-   handle_taskexit_event(current);
+   running_exec = thread && (current->flags & PF_EXITING) == 0;
+   if (running_exec) {
+   __handle_taskexit_event(current);
ipipe_disable_notifier(current);
}
if (atomic_dec_and_test(_ppd->refcnt))
remove_process(process);
+   if (running_exec) {
+   __xnthread_cleanup(thread);
+   clear_threadinfo();
+   }
}
 
/*


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


[Xenomai-git] Gilles Chanteperdrix : cobalt/process: avoid crash at fork

2015-10-11 Thread git repository hosting
Module: xenomai-gch
Branch: for-forge
Commit: 6b90c9835634106ad2bf4213b4b2477b00ec6991
URL:
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=6b90c9835634106ad2bf4213b4b2477b00ec6991

Author: Gilles Chanteperdrix 
Date:   Sun Oct 11 23:29:47 2015 +0200

cobalt/process: avoid crash at fork

When handle_cleanup_event() is called because a thread is calling exec
after a fork from a Xenomai process, handle_taskexit_event() is called
before remove_process(). However, handle_taskexit_event() calls
clear_threadinfo(), so that later calls to cobalt_current_process()
return NULL, causing crashes in cleanup functions relying on
cobalt_current_process() or cobalt_ppd_get(), such as
cobalt_mutex_reclaim().

---

 kernel/cobalt/posix/process.c |   29 ++---
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
index e7f8a93..6c6f868 100644
--- a/kernel/cobalt/posix/process.c
+++ b/kernel/cobalt/posix/process.c
@@ -200,7 +200,8 @@ static void remove_process(struct cobalt_process *process)
 * upon return from detach_process() for the Cobalt
 * personality, so don't dereference it afterwards.
 */
-   process->priv[xid] = NULL;
+   if (xid)
+   process->priv[xid] = NULL;
__clear_bit(personality->xid, >permap);
personality->ops.detach_process(priv);
atomic_dec(>refcnt);
@@ -1006,7 +1007,7 @@ static void unregister_debugged_thread(struct xnthread 
*thread)
xnlock_put_irqrestore(, s);
 }
 
-static int handle_taskexit_event(struct task_struct *p) /* p == current */
+static void __handle_taskexit_event(struct task_struct *p)
 {
struct cobalt_ppd *sys_ppd;
struct xnthread *thread;
@@ -1033,16 +1034,22 @@ static int handle_taskexit_event(struct task_struct *p) 
/* p == current */
cobalt_umm_free(_kernel_ppd.umm, thread->u_window);
thread->u_window = NULL;
sys_ppd = cobalt_ppd_get(0);
-   if (atomic_dec_and_test(_ppd->refcnt))
+   if (atomic_dec_and_test(_ppd->refcnt)) {
remove_process(cobalt_current_process());
+   }
}
+}
+
+static int handle_taskexit_event(struct task_struct *p) /* p == current */
+{
+   __handle_taskexit_event(p);
 
/*
 * __xnthread_cleanup() -> ... -> finalize_thread
 * handler. From that point, the TCB is dropped. Be careful of
 * not treading on stale memory within @thread.
 */
-   __xnthread_cleanup(thread);
+   __xnthread_cleanup(xnthread_current());
 
clear_threadinfo();
 
@@ -1198,6 +1205,8 @@ static int handle_cleanup_event(struct mm_struct *mm)
old = cobalt_set_process(process);
sys_ppd = cobalt_ppd_get(0);
if (sys_ppd != _kernel_ppd) {
+   bool running_exec;
+
/*
 * Detect a userland shadow running exec(), i.e. still
 * attached to the current linux task (no prior
@@ -1208,12 +1217,18 @@ static int handle_cleanup_event(struct mm_struct *mm)
 * notifier manually for it.
 */
thread = xnthread_current();
-   if (thread && (current->flags & PF_EXITING) == 0) {
-   handle_taskexit_event(current);
+   running_exec = thread && (current->flags & PF_EXITING) == 0;
+   if (running_exec) {
+   __handle_taskexit_event(current);
ipipe_disable_notifier(current);
}
-   if (atomic_dec_and_test(_ppd->refcnt))
+   if (atomic_dec_and_test(_ppd->refcnt)) {
remove_process(process);
+   if (running_exec) {
+   __xnthread_cleanup(thread);
+   clear_threadinfo();
+   }
+   }
}
 
/*


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