Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933101AbbBQIji (ORCPT ); Tue, 17 Feb 2015 03:39:38 -0500 Received: from mailhub.sw.ru ([195.214.232.25]:45995 "EHLO relay.sw.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933056AbbBQIje (ORCPT ); Tue, 17 Feb 2015 03:39:34 -0500 X-Greylist: delayed 1122 seconds by postgrey-1.27 at vger.kernel.org; Tue, 17 Feb 2015 03:39:28 EST From: Andrey Vagin To: linux-kernel@vger.kernel.org Cc: linux-api@vger.kernel.org, Oleg Nesterov , Andrew Morton , Cyrill Gorcunov , Pavel Emelyanov , Roger Luethi , Andrey Vagin Subject: [PATCH 4/7] task-diag: add a new group to get process credentials Date: Tue, 17 Feb 2015 11:20:23 +0300 Message-Id: <1424161226-15176-5-git-send-email-avagin@openvz.org> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1424161226-15176-1-git-send-email-avagin@openvz.org> References: <1424161226-15176-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: 4295 Lines: 161 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 filled only if show_flags contains TASK_DIAG_SHOW_CRED. Signed-off-by: Andrey Vagin --- include/uapi/linux/taskdiag.h | 23 ++++++++++++++++++ kernel/taskdiag.c | 55 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/taskdiag.h b/include/uapi/linux/taskdiag.h index e1feb35..db12f6d 100644 --- a/include/uapi/linux/taskdiag.h +++ b/include/uapi/linux/taskdiag.h @@ -9,11 +9,14 @@ enum { /* optional attributes which can be specified in show_flags */ + TASK_DIAG_CRED, /* other attributes */ TASK_DIAG_MSG = 64, }; +#define TASK_DIAG_SHOW_CRED (1ULL << TASK_DIAG_CRED) + enum { TASK_DIAG_RUNNING, TASK_DIAG_INTERRUPTIBLE, @@ -37,6 +40,26 @@ struct task_diag_msg { 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; +}; + enum { TASKDIAG_CMD_UNSPEC = 0, /* Reserved */ TASKDIAG_CMD_GET, diff --git a/kernel/taskdiag.c b/kernel/taskdiag.c index da4a51b..6ccbcaf 100644 --- a/kernel/taskdiag.c +++ b/kernel/taskdiag.c @@ -15,7 +15,14 @@ static struct genl_family family = { static size_t taskdiag_packet_size(u64 show_flags) { - return nla_total_size(sizeof(struct task_diag_msg)); + size_t size; + + size = nla_total_size(sizeof(struct task_diag_msg)); + + if (show_flags & TASK_DIAG_SHOW_CRED) + size += nla_total_size(sizeof(struct task_diag_creds)); + + return size; } /* @@ -82,6 +89,46 @@ static int fill_task_msg(struct task_struct *p, struct sk_buff *skb) 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 = current_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); + + return 0; +} + static int task_diag_fill(struct task_struct *tsk, struct sk_buff *skb, u64 show_flags, u32 portid, u32 seq) { @@ -96,6 +143,12 @@ static int task_diag_fill(struct task_struct *tsk, struct sk_buff *skb, if (err) goto err; + if (show_flags & TASK_DIAG_SHOW_CRED) { + err = fill_creds(tsk, skb); + if (err) + goto err; + } + return genlmsg_end(skb, reply); err: genlmsg_cancel(skb, reply); -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/