pidfd_send_signal syscall is used to signal and pass siginfo_t type data to a process identified by a pidfd. PCuABI specification requires that the data should be transmitted along with the capability pointer tags in case of signal delivered to the same process. In case of different process no tag details should be copied and any tag present in siginfo_t should be treated as an -EINVAL type error.
Modify function copy_siginfo_from_user_any() to have a bool argument and is obtained by comparing received pidfd with the current process. However the siginfo_t tag validation checks for non current process is marked as a TODO for now.
Signed-off-by: Amit Daniel Kachhap amit.kachhap@arm.com --- kernel/signal.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/kernel/signal.c b/kernel/signal.c index 355195b665b6..3efb33031d36 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -3834,7 +3834,7 @@ static bool access_pidfd_pidns(struct pid *pid) }
static int copy_siginfo_from_user_any(kernel_siginfo_t *kinfo, - siginfo_t __user *info) + siginfo_t __user *info, bool current_pid) { #ifdef CONFIG_COMPAT /* @@ -3846,7 +3846,13 @@ static int copy_siginfo_from_user_any(kernel_siginfo_t *kinfo, return copy_siginfo_from_user32( kinfo, (struct compat_siginfo __user *)info); #endif - return copy_siginfo_from_user(kinfo, info); + /* + * TODO [PCuABI]: In case target pid differs from the current pid, this + * code silently ignores the tag copy. Revisit this later to treat this + * as an error(-EINVAL) for PCuABI. + */ + return (current_pid ? copy_siginfo_from_user_with_ptr(kinfo, info) + : copy_siginfo_from_user(kinfo, info)); }
static struct pid *pidfd_to_pid(const struct file *file) @@ -3906,7 +3912,7 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig, goto err;
if (info) { - ret = copy_siginfo_from_user_any(&kinfo, info); + ret = copy_siginfo_from_user_any(&kinfo, info, (task_pid(current) == pid)); if (unlikely(ret)) goto err;