From: Jan Kiszka <jan.kis...@siemens.com>

Make sure that we consider all pids taken from or sent to userspace via
syscalls as virtual. That means converting them to global pids before
processing them or converting them back to virtual pids in the caller's
namespace before reporting them. We also need to switch thread hashing
from vpids to real pids.

Not converted is the procfs interface as this one continues to provide
only a global view on cobalt objects and associated pids.

A few syscall tracepoints that report the vpid as passed down from
userspace get adjusted in their output so that it is clear that no
global pid is shown.

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>
---

Changes in v3:
 - handle process-local thread lookups correctly (hopefully)

This is in next for a while and ran several test cycles. Even if we 
should have remaining issues under pid namespaces, we should not have 
regressions in the normal cases.

 include/cobalt/kernel/thread.h     |  2 ++
 kernel/cobalt/posix/event.c        |  2 +-
 kernel/cobalt/posix/mqueue.c       |  2 +-
 kernel/cobalt/posix/process.c      | 14 ++++++++++++++
 kernel/cobalt/posix/process.h      |  2 ++
 kernel/cobalt/posix/sched.c        | 10 ++++++----
 kernel/cobalt/posix/sem.c          |  2 +-
 kernel/cobalt/posix/signal.c       | 10 ++++++----
 kernel/cobalt/posix/thread.c       | 18 ++++++++++--------
 kernel/cobalt/posix/thread.h       |  2 +-
 kernel/cobalt/thread.c             | 10 ++++++++++
 kernel/cobalt/trace/cobalt-posix.h |  4 ++--
 12 files changed, 56 insertions(+), 22 deletions(-)

diff --git a/include/cobalt/kernel/thread.h b/include/cobalt/kernel/thread.h
index b79cb84296..4c8a0b9f2a 100644
--- a/include/cobalt/kernel/thread.h
+++ b/include/cobalt/kernel/thread.h
@@ -450,6 +450,8 @@ char *xnthread_format_status(unsigned long status,
 
 pid_t xnthread_host_pid(struct xnthread *thread);
 
+pid_t xnthread_host_vpid(struct xnthread *thread);
+
 int xnthread_set_clock(struct xnthread *thread,
                       struct xnclock *newclock);
 
diff --git a/kernel/cobalt/posix/event.c b/kernel/cobalt/posix/event.c
index 3712154f53..5871106301 100644
--- a/kernel/cobalt/posix/event.c
+++ b/kernel/cobalt/posix/event.c
@@ -352,7 +352,7 @@ COBALT_SYSCALL(event_inquire, current,
                xnsynch_for_each_sleeper(thread, &event->synch) {
                        if (nrwait >= nrpids)
                                break;
-                       t[nrwait++] = xnthread_host_pid(thread);
+                       t[nrwait++] = xnthread_host_vpid(thread);
                }
        }
 
diff --git a/kernel/cobalt/posix/mqueue.c b/kernel/cobalt/posix/mqueue.c
index dd8acd55b0..fcde87a077 100644
--- a/kernel/cobalt/posix/mqueue.c
+++ b/kernel/cobalt/posix/mqueue.c
@@ -720,7 +720,7 @@ mq_notify(struct cobalt_mqd *mqd, unsigned index, const 
struct sigevent *evp)
                 * receiver's namespaces. We pass the receiver's creds
                 * into the init namespace instead.
                 */
-               mq->si.si_pid = task_pid_nr(current);
+               mq->si.si_pid = task_pid_vnr(current);
                mq->si.si_uid = get_current_uuid();
        }
 
diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
index 1f059ad830..98b7df33fb 100644
--- a/kernel/cobalt/posix/process.c
+++ b/kernel/cobalt/posix/process.c
@@ -975,6 +975,20 @@ int cobalt_handle_cleanup_event(struct mm_struct *mm)
        return KEVENT_PROPAGATE;
 }
 
+pid_t cobalt_vpid2pid_nr(pid_t vpid)
+{
+       struct pid *pid;
+       pid_t nr = -1;
+
+       rcu_read_lock();
+       pid = find_vpid(vpid);
+       if (pid)
+               nr = pid_nr(pid);
+       rcu_read_unlock();
+
+       return nr;
+}
+
 static int attach_process(struct cobalt_process *process)
 {
        struct cobalt_ppd *p = &process->sys_ppd;
diff --git a/kernel/cobalt/posix/process.h b/kernel/cobalt/posix/process.h
index 279707a680..46dff43b7a 100644
--- a/kernel/cobalt/posix/process.h
+++ b/kernel/cobalt/posix/process.h
@@ -175,4 +175,6 @@ int cobalt_handle_cleanup_event(struct mm_struct *mm);
 
 int cobalt_handle_user_return(struct task_struct *task);
 
+pid_t cobalt_vpid2pid_nr(pid_t vpid);
+
 #endif /* !_COBALT_POSIX_PROCESS_H */
diff --git a/kernel/cobalt/posix/sched.c b/kernel/cobalt/posix/sched.c
index 4fd9c2b46e..26259fbd3f 100644
--- a/kernel/cobalt/posix/sched.c
+++ b/kernel/cobalt/posix/sched.c
@@ -736,7 +736,7 @@ COBALT_SYSCALL(sched_weightprio, current,
        return __cobalt_sched_weightprio(policy, &param_ex);
 }
 
-int cobalt_sched_setscheduler_ex(pid_t pid,
+int cobalt_sched_setscheduler_ex(pid_t vpid,
                                 int policy,
                                 const struct sched_param_ex *param_ex,
                                 __u32 __user *u_winoff,
@@ -747,9 +747,11 @@ int cobalt_sched_setscheduler_ex(pid_t pid,
        int ret, promoted = 0;
        spl_t s;
 
-       trace_cobalt_sched_setscheduler(pid, policy, param_ex);
+       trace_cobalt_sched_setscheduler(vpid, policy, param_ex);
+
+       if (vpid) {
+               pid_t pid = cobalt_vpid2pid_nr(vpid);
 
-       if (pid) {
                xnlock_get_irqsave(&nklock, s);
                thread = cobalt_thread_find(pid);
                xnlock_put_irqrestore(&nklock, s);
@@ -757,7 +759,7 @@ int cobalt_sched_setscheduler_ex(pid_t pid,
                thread = cobalt_current_thread();
 
        if (thread == NULL) {
-               if (u_winoff == NULL || pid != task_pid_vnr(current))
+               if (u_winoff == NULL || vpid != task_pid_vnr(current))
                        return -ESRCH;
                        
                thread = cobalt_thread_shadow(&hkey, u_winoff);
diff --git a/kernel/cobalt/posix/sem.c b/kernel/cobalt/posix/sem.c
index 72b20c78d2..030ce8ffed 100644
--- a/kernel/cobalt/posix/sem.c
+++ b/kernel/cobalt/posix/sem.c
@@ -602,7 +602,7 @@ COBALT_SYSCALL(sem_inquire, current,
                xnsynch_for_each_sleeper(thread, &sem->synchbase) {
                        if (nrwait >= nrpids)
                                break;
-                       t[nrwait++] = xnthread_host_pid(thread);
+                       t[nrwait++] = xnthread_host_vpid(thread);
                }
        }
 
diff --git a/kernel/cobalt/posix/signal.c b/kernel/cobalt/posix/signal.c
index 0b43b5fcfa..c2c9c092c4 100644
--- a/kernel/cobalt/posix/signal.c
+++ b/kernel/cobalt/posix/signal.c
@@ -510,7 +510,7 @@ int __cobalt_kill(struct cobalt_thread *thread, int sig, 
int group) /* nklocked,
                        sigp->si.si_signo = sig;
                        sigp->si.si_errno = 0;
                        sigp->si.si_code = SI_USER;
-                       sigp->si.si_pid = task_pid_nr(current);
+                       sigp->si.si_pid = task_pid_vnr(current);
                        sigp->si.si_uid = get_current_uuid();
                        if (cobalt_signal_send(thread, sigp, group) <= 0)
                                cobalt_signal_free(sigp);
@@ -525,8 +525,9 @@ int __cobalt_kill(struct cobalt_thread *thread, int sig, 
int group) /* nklocked,
        return ret;
 }
 
-COBALT_SYSCALL(kill, conforming, (pid_t pid, int sig))
+COBALT_SYSCALL(kill, conforming, (pid_t vpid, int sig))
 {
+       pid_t pid = cobalt_vpid2pid_nr(vpid);
        struct cobalt_thread *thread;
        int ret;
        spl_t s;
@@ -544,8 +545,9 @@ COBALT_SYSCALL(kill, conforming, (pid_t pid, int sig))
        return ret;
 }
 
-int __cobalt_sigqueue(pid_t pid, int sig, const union sigval *value)
+int __cobalt_sigqueue(pid_t vpid, int sig, const union sigval *value)
 {
+       pid_t pid = cobalt_vpid2pid_nr(vpid);
        struct cobalt_sigpending *sigp;
        struct cobalt_thread *thread;
        int ret = 0;
@@ -569,7 +571,7 @@ int __cobalt_sigqueue(pid_t pid, int sig, const union 
sigval *value)
                        sigp->si.si_signo = sig;
                        sigp->si.si_errno = 0;
                        sigp->si.si_code = SI_QUEUE;
-                       sigp->si.si_pid = task_pid_nr(current);
+                       sigp->si.si_pid = task_pid_vnr(current);
                        sigp->si.si_uid = get_current_uuid();
                        sigp->si.si_value = *value;
                        if (cobalt_signal_send(thread, sigp, 1) <= 0)
diff --git a/kernel/cobalt/posix/thread.c b/kernel/cobalt/posix/thread.c
index cdeb66d4f3..6a79fecb5c 100644
--- a/kernel/cobalt/posix/thread.c
+++ b/kernel/cobalt/posix/thread.c
@@ -176,11 +176,11 @@ struct cobalt_thread *cobalt_thread_find(pid_t pid) /* 
nklocked, IRQs off */
 }
 EXPORT_SYMBOL_GPL(cobalt_thread_find);
 
-struct cobalt_thread *cobalt_thread_find_local(pid_t pid) /* nklocked, IRQs 
off */
+struct cobalt_thread *cobalt_thread_find_local(pid_t vpid) /* nklocked, IRQs 
off */
 {
        struct cobalt_thread *thread;
 
-       thread = cobalt_thread_find(pid);
+       thread = cobalt_thread_find(cobalt_vpid2pid_nr(vpid));
        if (thread == NULL || thread->hkey.mm != current->mm)
                return NULL;
 
@@ -624,7 +624,7 @@ int __cobalt_thread_create(unsigned long pth, int policy,
                return ret;
        }
 
-       if (!thread_hash(&hkey, thread, task_pid_vnr(p))) {
+       if (!thread_hash(&hkey, thread, task_pid_nr(p))) {
                ret = -EAGAIN;
                goto fail;
        }
@@ -682,7 +682,7 @@ cobalt_thread_shadow(struct cobalt_local_hkey *hkey,
                return ERR_PTR(ret);
        }
 
-       if (!thread_hash(hkey, thread, task_pid_vnr(current))) {
+       if (!thread_hash(hkey, thread, task_pid_nr(current))) {
                ret = -EAGAIN;
                goto fail;
        }
@@ -819,7 +819,7 @@ COBALT_SYSCALL(thread_getpid, current, (unsigned long pth))
        if (thread == NULL)
                pid = -ESRCH;
        else
-               pid = xnthread_host_pid(&thread->threadbase);
+               pid = xnthread_host_vpid(&thread->threadbase);
 
        xnlock_put_irqrestore(&nklock, s);
 
@@ -827,7 +827,7 @@ COBALT_SYSCALL(thread_getpid, current, (unsigned long pth))
 }
 
 COBALT_SYSCALL(thread_getstat, current,
-              (pid_t pid, struct cobalt_threadstat __user *u_stat))
+              (pid_t vpid, struct cobalt_threadstat __user *u_stat))
 {
        struct cobalt_threadstat stat;
        struct cobalt_thread *p;
@@ -835,14 +835,16 @@ COBALT_SYSCALL(thread_getstat, current,
        xnticks_t xtime;
        spl_t s;
 
-       trace_cobalt_pthread_stat(pid);
+       trace_cobalt_pthread_stat(vpid);
 
-       if (pid == 0) {
+       if (vpid == 0) {
                thread = xnthread_current();
                if (thread == NULL)
                        return -EPERM;
                xnlock_get_irqsave(&nklock, s);
        } else {
+               pid_t pid = cobalt_vpid2pid_nr(vpid);
+
                xnlock_get_irqsave(&nklock, s);
                p = cobalt_thread_find(pid);
                if (p == NULL) {
diff --git a/kernel/cobalt/posix/thread.h b/kernel/cobalt/posix/thread.h
index 51be372a7a..66e3a88223 100644
--- a/kernel/cobalt/posix/thread.h
+++ b/kernel/cobalt/posix/thread.h
@@ -146,7 +146,7 @@ int cobalt_thread_setschedprio(unsigned long pth,
 
 struct cobalt_thread *cobalt_thread_find(pid_t pid);
 
-struct cobalt_thread *cobalt_thread_find_local(pid_t pid);
+struct cobalt_thread *cobalt_thread_find_local(pid_t vpid);
 
 struct cobalt_thread *cobalt_thread_lookup(unsigned long pth);
 
diff --git a/kernel/cobalt/thread.c b/kernel/cobalt/thread.c
index 2c1ec6d3a4..9a97213fbe 100644
--- a/kernel/cobalt/thread.c
+++ b/kernel/cobalt/thread.c
@@ -388,6 +388,16 @@ pid_t xnthread_host_pid(struct xnthread *thread)
        return task_pid_nr(xnthread_host_task(thread));
 }
 
+pid_t xnthread_host_vpid(struct xnthread *thread)
+{
+       if (xnthread_test_state(thread, XNROOT))
+               return 0;
+       if (!xnthread_host_task(thread))
+               return -1;
+
+       return task_pid_vnr(xnthread_host_task(thread));
+}
+
 int xnthread_set_clock(struct xnthread *thread, struct xnclock *newclock)
 {
        spl_t s;
diff --git a/kernel/cobalt/trace/cobalt-posix.h 
b/kernel/cobalt/trace/cobalt-posix.h
index 3df9295541..d994007bba 100644
--- a/kernel/cobalt/trace/cobalt-posix.h
+++ b/kernel/cobalt/trace/cobalt-posix.h
@@ -252,7 +252,7 @@ DECLARE_EVENT_CLASS(cobalt_posix_scheduler,
                memcpy(__get_dynamic_array(param_ex), param_ex, 
sizeof(*param_ex));
        ),
 
-       TP_printk("pid=%d policy=%s param={ %s }",
+       TP_printk("vpid=%d policy=%s param={ %s }",
                  __entry->pid,
                  cobalt_print_sched_policy(__entry->policy),
                  __parse_sched_params(__entry->policy,
@@ -369,7 +369,7 @@ DECLARE_EVENT_CLASS(cobalt_posix_pid,
        TP_fast_assign(
                __entry->pid = pid;
        ),
-       TP_printk("pid=%d", __entry->pid)
+       TP_printk("vpid=%d", __entry->pid)
 );
 
 DEFINE_EVENT(cobalt_posix_pid, cobalt_pthread_stat,
-- 
2.31.1

Reply via email to