On 02.08.21 18:56, Jan Kiszka via Xenomai wrote:
> 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();

This is not a good idea, at least for I-pipe which is not RCU-compatible
(Dovetail just gained that).

I think we need to rest this approach for now, either under I-pipe
gained support for RCU read-side access or we switched to Dovetail
completely. Pulling it from next.

Jan

> +     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,
> 

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux

Reply via email to