Module: xenomai-jki
Branch: for-forge
Commit: 1d7bccbc6aaa4454c98ecf11694e2cc2d7d150e2
URL:    
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=1d7bccbc6aaa4454c98ecf11694e2cc2d7d150e2

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Thu May 24 19:34:26 2018 +0200

cobalt/posix/sem: Fix sem_open for preexisting semaphores

We missed to create and copy the shadow into userspace in case a
preexisting semaphore was opened in process that didn't created it. Was
biting us in pshared setups, but also when the previous owner died
before destroying a named semaphore.

Reported-by: Paal Tamas <paal...@freemail.hu>
Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>

---

 kernel/cobalt/posix/nsem.c |   11 +++++++----
 kernel/cobalt/posix/sem.c  |   23 ++++++++++++++++++-----
 kernel/cobalt/posix/sem.h  |    3 +++
 3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/kernel/cobalt/posix/nsem.c b/kernel/cobalt/posix/nsem.c
index bf2157d..89cf62b 100644
--- a/kernel/cobalt/posix/nsem.c
+++ b/kernel/cobalt/posix/nsem.c
@@ -95,6 +95,8 @@ sem_open(struct cobalt_process *process,
                        xnlock_put_irqrestore(&nklock, s);
                        goto retry_bind;
                }
+
+               __cobalt_sem_shadow_init(sem, COBALT_NAMED_SEM_MAGIC, &shadow);
                break;
 
        case -EWOULDBLOCK:
@@ -112,10 +114,6 @@ sem_open(struct cobalt_process *process,
                        return ERR_PTR(rc);
                }
 
-               if (cobalt_copy_to_user(ushadow, &shadow, sizeof(shadow))) {
-                       __cobalt_sem_destroy(shadow.handle);
-                       return ERR_PTR(-EFAULT);
-               }
                sem->pathname = filename;
                handle = shadow.handle;
                break;
@@ -124,6 +122,11 @@ sem_open(struct cobalt_process *process,
                return ERR_PTR(rc);
        }
 
+       if (cobalt_copy_to_user(ushadow, &shadow, sizeof(shadow))) {
+               __cobalt_sem_destroy(handle);
+               return ERR_PTR(-EFAULT);
+       }
+
        u = xnmalloc(sizeof(*u));
        if (u == NULL) {
                __cobalt_sem_destroy(handle);
diff --git a/kernel/cobalt/posix/sem.c b/kernel/cobalt/posix/sem.c
index dc7ff0d..ab075bb 100644
--- a/kernel/cobalt/posix/sem.c
+++ b/kernel/cobalt/posix/sem.c
@@ -153,13 +153,11 @@ __cobalt_sem_init(const char *name, struct 
cobalt_sem_shadow *sm,
        sem->refs = name ? 2 : 1;
        sem->pathname = NULL;
 
-       sm->magic = name ? COBALT_NAMED_SEM_MAGIC : COBALT_SEM_MAGIC;
-       sm->handle = sem->resnode.handle;
-       sm->state_offset = cobalt_umm_offset(&sys_ppd->umm, state);
-       if (flags & SEM_PSHARED)
-               sm->state_offset = -sm->state_offset;
        xnlock_put_irqrestore(&nklock, s);
 
+       __cobalt_sem_shadow_init(sem,
+                       name ? COBALT_NAMED_SEM_MAGIC : COBALT_SEM_MAGIC, sm);
+
        trace_cobalt_psem_init(name ?: "anon",
                               sem->resnode.handle, flags, value);
 
@@ -176,6 +174,21 @@ out:
        return ERR_PTR(ret);
 }
 
+void __cobalt_sem_shadow_init(struct cobalt_sem *sem, __u32 magic,
+                             struct cobalt_sem_shadow *sm)
+{
+       __u32 flags = sem->state->flags;
+       struct cobalt_ppd *sys_ppd;
+
+       sys_ppd = cobalt_ppd_get(!!(flags & SEM_PSHARED));
+
+       sm->magic = magic;
+       sm->handle = sem->resnode.handle;
+       sm->state_offset = cobalt_umm_offset(&sys_ppd->umm, sem->state);
+       if (sem->state->flags & SEM_PSHARED)
+               sm->state_offset = -sm->state_offset;
+}
+
 static int sem_destroy(struct cobalt_sem_shadow *sm)
 {
        struct cobalt_sem *sem;
diff --git a/kernel/cobalt/posix/sem.h b/kernel/cobalt/posix/sem.h
index a95b6c4..1723807 100644
--- a/kernel/cobalt/posix/sem.h
+++ b/kernel/cobalt/posix/sem.h
@@ -76,6 +76,9 @@ struct cobalt_sem *
 __cobalt_sem_init(const char *name, struct cobalt_sem_shadow *sem,
                  int flags, unsigned value);
 
+void __cobalt_sem_shadow_init(struct cobalt_sem *sem, __u32 magic,
+                             struct cobalt_sem_shadow *sm);
+
 COBALT_SYSCALL_DECL(sem_init,
                    (struct cobalt_sem_shadow __user *u_sem,
                     int flags, unsigned value));


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

Reply via email to