Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755427AbcDKXgR (ORCPT ); Mon, 11 Apr 2016 19:36:17 -0400 Received: from mail-pf0-f175.google.com ([209.85.192.175]:32876 "EHLO mail-pf0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755372AbcDKXgN (ORCPT ); Mon, 11 Apr 2016 19:36:13 -0400 From: Andrey Vagin To: linux-kernel@vger.kernel.org Cc: Andrey Vagin , Oleg Nesterov , Andrew Morton , Cyrill Gorcunov , Pavel Emelyanov , Roger Luethi , Arnd Bergmann , Arnaldo Carvalho de Melo , David Ahern , Andy Lutomirski , Pavel Odintsov Subject: [PATCH 05/15] task_diag: add a new group to get process credentials Date: Mon, 11 Apr 2016 16:35:45 -0700 Message-Id: <1460417755-18201-6-git-send-email-avagin@openvz.org> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1460417755-18201-1-git-send-email-avagin@openvz.org> References: <1460417755-18201-1-git-send-email-avagin@openvz.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3698 Lines: 142 A response is represented by the task_diag_creds structure: struct task_diag_creds { struct task_diag_caps cap_inheritable; struct task_diag_caps cap_permitted; struct task_diag_caps cap_effective; struct task_diag_caps cap_bset; __u32 uid; __u32 euid; __u32 suid; __u32 fsuid; __u32 gid; __u32 egid; __u32 sgid; __u32 fsgid; }; This group is optional and it's filled only if show_flags contains TASK_DIAG_SHOW_CRED. Signed-off-by: Andrey Vagin --- fs/proc/task_diag.c | 50 ++++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/task_diag.h | 21 ++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/fs/proc/task_diag.c b/fs/proc/task_diag.c index 3c2127e..fc31771 100644 --- a/fs/proc/task_diag.c +++ b/fs/proc/task_diag.c @@ -80,6 +80,48 @@ static int fill_task_base(struct task_struct *p, return 0; } +static inline void caps2diag(struct task_diag_caps *diag, const kernel_cap_t *cap) +{ + int i; + + for (i = 0; i < _LINUX_CAPABILITY_U32S_3; i++) + diag->cap[i] = cap->cap[i]; +} + +static int fill_creds(struct task_struct *p, struct sk_buff *skb, + struct user_namespace *user_ns) +{ + struct task_diag_creds *diag_cred; + const struct cred *cred; + struct nlattr *attr; + + attr = nla_reserve(skb, TASK_DIAG_CRED, sizeof(struct task_diag_creds)); + if (!attr) + return -EMSGSIZE; + + diag_cred = nla_data(attr); + + cred = get_task_cred(p); + + caps2diag(&diag_cred->cap_inheritable, &cred->cap_inheritable); + caps2diag(&diag_cred->cap_permitted, &cred->cap_permitted); + caps2diag(&diag_cred->cap_effective, &cred->cap_effective); + caps2diag(&diag_cred->cap_bset, &cred->cap_bset); + + diag_cred->uid = from_kuid_munged(user_ns, cred->uid); + diag_cred->euid = from_kuid_munged(user_ns, cred->euid); + diag_cred->suid = from_kuid_munged(user_ns, cred->suid); + diag_cred->fsuid = from_kuid_munged(user_ns, cred->fsuid); + diag_cred->gid = from_kgid_munged(user_ns, cred->gid); + diag_cred->egid = from_kgid_munged(user_ns, cred->egid); + diag_cred->sgid = from_kgid_munged(user_ns, cred->sgid); + diag_cred->fsgid = from_kgid_munged(user_ns, cred->fsgid); + + put_cred(cred); + + return 0; +} + static int task_diag_fill(struct task_struct *tsk, struct sk_buff *skb, struct task_diag_pid *req, struct task_diag_cb *cb, struct pid_namespace *pidns, @@ -113,6 +155,14 @@ static int task_diag_fill(struct task_struct *tsk, struct sk_buff *skb, i++; } + if (show_flags & TASK_DIAG_SHOW_CRED) { + if (i >= n) + err = fill_creds(tsk, skb, userns); + if (err) + goto err; + i++; + } + nlmsg_end(skb, nlh); if (cb) cb->attr = 0; diff --git a/include/uapi/linux/task_diag.h b/include/uapi/linux/task_diag.h index ba0f71a..ea500c6 100644 --- a/include/uapi/linux/task_diag.h +++ b/include/uapi/linux/task_diag.h @@ -15,12 +15,14 @@ struct task_diag_msg { enum { TASK_DIAG_BASE = 0, + TASK_DIAG_CRED, __TASK_DIAG_ATTR_MAX #define TASK_DIAG_ATTR_MAX (__TASK_DIAG_ATTR_MAX - 1) }; #define TASK_DIAG_SHOW_BASE (1ULL << TASK_DIAG_BASE) +#define TASK_DIAG_SHOW_CRED (1ULL << TASK_DIAG_CRED) enum { TASK_DIAG_RUNNING, @@ -45,6 +47,25 @@ struct task_diag_base { char comm[TASK_DIAG_COMM_LEN]; }; +struct task_diag_caps { + __u32 cap[_LINUX_CAPABILITY_U32S_3]; +}; + +struct task_diag_creds { + struct task_diag_caps cap_inheritable; + struct task_diag_caps cap_permitted; + struct task_diag_caps cap_effective; + struct task_diag_caps cap_bset; + + __u32 uid; + __u32 euid; + __u32 suid; + __u32 fsuid; + __u32 gid; + __u32 egid; + __u32 sgid; + __u32 fsgid; +}; #define TASK_DIAG_DUMP_ALL 0 #define TASK_DIAG_DUMP_ONE 1 -- 2.5.5