Module: xenomai-3
Branch: next
Commit: 68cdffd721f751f2cf08123791d75d27cd7bc880
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=68cdffd721f751f2cf08123791d75d27cd7bc880

Author: Philippe Gerum <r...@xenomai.org>
Date:   Mon Oct 27 10:09:35 2014 +0100

cobalt/posix/nsem: allow path lengths up to PATH_MAX

As a consequence of this change, open/close/unlink ops move to low
stage handling.

---

 kernel/cobalt/posix/nsem.c      |   40 ++++++++++++++++++++++-----------------
 kernel/cobalt/posix/sem.c       |   14 ++++++--------
 kernel/cobalt/posix/sem.h       |    1 -
 kernel/cobalt/posix/syscall.c   |    6 +++---
 kernel/cobalt/posix/syscall32.c |    2 +-
 5 files changed, 33 insertions(+), 30 deletions(-)

diff --git a/kernel/cobalt/posix/nsem.c b/kernel/cobalt/posix/nsem.c
index af0cd49..e0472f7 100644
--- a/kernel/cobalt/posix/nsem.c
+++ b/kernel/cobalt/posix/nsem.c
@@ -33,6 +33,7 @@ struct named_sem {
        struct cobalt_sem_shadow __user *usem;
        unsigned int refs;
        struct xnid id;
+       struct filename *filename;
 };
 
 static struct named_sem *sem_search(struct cobalt_process *cc, xnhandle_t 
handle)
@@ -48,11 +49,12 @@ static struct named_sem *sem_search(struct cobalt_process 
*cc, xnhandle_t handle
 
 static struct cobalt_sem_shadow __user *
 sem_open(struct cobalt_process *cc, struct cobalt_sem_shadow __user *ushadow,
-        const char *name, int oflags, mode_t mode, unsigned int value)
+        struct filename *filename, int oflags, mode_t mode, unsigned int value)
 {
+       const char *name = filename->name;
        struct cobalt_sem_shadow shadow;
-       struct cobalt_sem *sem;
        struct named_sem *u, *v;
+       struct cobalt_sem *sem;
        xnhandle_t handle;
        spl_t s;
        int rc;
@@ -126,6 +128,7 @@ sem_open(struct cobalt_process *cc, struct 
cobalt_sem_shadow __user *ushadow,
        u->sem = sem;
        u->usem = ushadow;
        u->refs = 1;
+       u->filename = filename;
 
        xnlock_get_irqsave(&named_sem_lock, s);
        v = sem_search(cc, handle);
@@ -136,6 +139,7 @@ sem_open(struct cobalt_process *cc, struct 
cobalt_sem_shadow __user *ushadow,
                --sem->refs;
                xnlock_put_irqrestore(&nklock, s);
 
+               putname(filename);
                xnfree(u);
                u = v;
        } else {
@@ -171,6 +175,7 @@ static int sem_close(struct cobalt_process *cc, xnhandle_t 
handle)
 
        __cobalt_sem_destroy(handle);
 
+       putname(u->filename);
        xnfree(u);
        return 1;
 
@@ -201,16 +206,17 @@ __cobalt_sem_open(struct cobalt_sem_shadow __user *usm,
        if (IS_ERR(filename))
                return ERR_CAST(filename);
 
-       usm = sem_open(cc, usm, filename->name, oflags, mode, value);
-       if (IS_ERR(usm))
+       usm = sem_open(cc, usm, filename, oflags, mode, value);
+       if (IS_ERR(usm)) {
                trace_cobalt_psem_open_failed(filename->name, oflags, mode,
                                              value, PTR_ERR(usm));
-       putname(filename);
+               putname(filename);
+       }
 
        return usm;
 }
 
-COBALT_SYSCALL(sem_open, current,
+COBALT_SYSCALL(sem_open, lostage,
               int, (struct cobalt_sem_shadow __user *__user *u_addrp,
                     const char __user *u_name,
                     int oflags, mode_t mode, unsigned int value))
@@ -227,7 +233,7 @@ COBALT_SYSCALL(sem_open, current,
        return __xn_put_user(usm, u_addrp) ? -EFAULT : 0;
 }
 
-COBALT_SYSCALL(sem_close, current,
+COBALT_SYSCALL(sem_close, lostage,
               int, (struct cobalt_sem_shadow __user *usm))
 {
        struct cobalt_process *cc;
@@ -260,21 +266,21 @@ static inline int sem_unlink(const char *name)
        return 0;
 }
 
-COBALT_SYSCALL(sem_unlink, current,
+COBALT_SYSCALL(sem_unlink, lostage,
               int, (const char __user *u_name))
 {
-       char name[COBALT_MAXNAME + 1];
-       long len;
+       struct filename *filename;
+       int ret;
 
-       len = __xn_safe_strncpy_from_user(name, u_name, sizeof(name));
-       if (len < 0)
-               return len;
-       if (len >= sizeof(name))
-               return -ENAMETOOLONG;
+       filename = getname(u_name);
+       if (IS_ERR(filename))
+               return PTR_ERR(filename);
 
-       trace_cobalt_psem_unlink(name);
+       trace_cobalt_psem_unlink(filename->name);
+       ret = sem_unlink(filename->name);
+       putname(filename);
 
-       return sem_unlink(name);
+       return ret;
 }
 
 static void cleanup_named_sems(void *cookie, struct xnid *i)
diff --git a/kernel/cobalt/posix/sem.c b/kernel/cobalt/posix/sem.c
index 3555ab8..fb9f391 100644
--- a/kernel/cobalt/posix/sem.c
+++ b/kernel/cobalt/posix/sem.c
@@ -89,8 +89,6 @@ __cobalt_sem_init(const char *name, struct cobalt_sem_shadow 
*sm,
                goto out;
        }
 
-       ksformat(sem->name, sizeof(sem->name), "%s", name);
-
        sys_ppd = cobalt_ppd_get(!!(flags & SEM_PSHARED));
        state = cobalt_umm_alloc(&sys_ppd->umm, sizeof(*state));
        if (state == NULL) {
@@ -133,7 +131,7 @@ __cobalt_sem_init(const char *name, struct 
cobalt_sem_shadow *sm,
                goto err_lock_put;
        }
 
-       ret = xnregistry_enter(sem->name, sem, &sem->handle, NULL);
+       ret = xnregistry_enter(name ?: "", sem, &sem->handle, NULL);
        if (ret < 0)
                goto err_lock_put;
 
@@ -147,16 +145,16 @@ __cobalt_sem_init(const char *name, struct 
cobalt_sem_shadow *sm,
        state->flags = flags;
        sem->flags = flags;
        sem->owningq = kq;
-       sem->refs = name[0] ? 2 : 1;
+       sem->refs = name ? 2 : 1;
 
-       sm->magic = name[0] ? COBALT_NAMED_SEM_MAGIC : COBALT_SEM_MAGIC;
+       sm->magic = name ? COBALT_NAMED_SEM_MAGIC : COBALT_SEM_MAGIC;
        sm->handle = sem->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);
 
-       trace_cobalt_psem_init(sem->name, sem->handle, flags, value);
+       trace_cobalt_psem_init(name ?: "anon", sem->handle, flags, value);
 
        return sem;
 
@@ -166,7 +164,7 @@ err_lock_put:
 err_free_sem:
        xnfree(sem);
 out:
-       trace_cobalt_psem_init_failed(name, flags, value, ret);
+       trace_cobalt_psem_init_failed(name ?: "anon", flags, value, ret);
 
        return ERR_PTR(ret);
 }
@@ -424,7 +422,7 @@ COBALT_SYSCALL(sem_init, current,
                      SEM_WARNDEL|SEM_RAWCLOCK|SEM_NOBUSYDEL))
                return -EINVAL;
 
-       sem = __cobalt_sem_init("", &sm, flags, value);
+       sem = __cobalt_sem_init(NULL, &sm, flags, value);
        if (IS_ERR(sem))
                return PTR_ERR(sem);
 
diff --git a/kernel/cobalt/posix/sem.h b/kernel/cobalt/posix/sem.h
index 1211a4d..d050a5e 100644
--- a/kernel/cobalt/posix/sem.h
+++ b/kernel/cobalt/posix/sem.h
@@ -36,7 +36,6 @@ struct cobalt_sem {
        struct cobalt_kqueues *owningq;
        xnhandle_t handle;
        unsigned int refs;
-       char name[COBALT_MAXNAME];
 };
 
 /* Copied from Linuxthreads semaphore.h. */
diff --git a/kernel/cobalt/posix/syscall.c b/kernel/cobalt/posix/syscall.c
index 71ed345..537defe 100644
--- a/kernel/cobalt/posix/syscall.c
+++ b/kernel/cobalt/posix/syscall.c
@@ -637,9 +637,9 @@ static const int cobalt_sysmodes[] = {
        __COBALT_MODE(sem_timedwait, primary),
        __COBALT_MODE(sem_trywait, primary),
        __COBALT_MODE(sem_getvalue, current),
-       __COBALT_MODE(sem_open, current),
-       __COBALT_MODE(sem_close, current),
-       __COBALT_MODE(sem_unlink, current),
+       __COBALT_MODE(sem_open, lostage),
+       __COBALT_MODE(sem_close, lostage),
+       __COBALT_MODE(sem_unlink, lostage),
        __COBALT_MODE(sem_broadcast_np, current),
        __COBALT_MODE(sem_inquire, current),
        __COBALT_MODE(clock_getres, current),
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index 603c379..633cc22 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -422,7 +422,7 @@ static inline int sys32_fetch_timeout(struct timespec *ts,
                sys32_get_timespec(ts, u_ts);
 }
 
-COBALT_SYSCALL32emu(sem_open, current,
+COBALT_SYSCALL32emu(sem_open, lostage,
                    int, (compat_uptr_t __user *u_addrp,
                          const char __user *u_name,
                          int oflags, mode_t mode, unsigned int value))


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

Reply via email to