blob: 6095211d297d30498e56b5c342c64c594e67910b [file] [log] [blame]
From javier.martinez@collabora.co.uk Thu Jun 6 03:26:33 2013
From: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Date: Thu, 6 Jun 2013 12:25:52 +0200
Subject: [PATCH 4/6] netfilter: nfdbus: use the uid instead of the pid to check permissions
To: Greg KH <gregkh@linuxfoundation.org>
Cc: ltsi-dev@lists.linuxfoundation.org, Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Message-ID: <1370514354-19114-5-git-send-email-javier.martinez@collabora.co.uk>
User-space processes can update the match rules set using a Netlink
interface. To avoid non-allowed processes to update this set, a
check was made that only the process who owns the bus master
listen socket would be able to send these netlink commands.
But this breaks D-Bus/AF_BUS when the D-Bus daemon was started
with the --fork argument since the launcher process calls socket(2)
and listen(2) before forking a child process that is the D-Bus
daemon. So, the bus master pid and the pid of the child that tries
to update the match rules is different.
Since the process exits after the fork, the new parent of the D-Bus
daemon is the init process. Also, a call to setsid(2) is made to
create a new session ID after the fork so no information about the
parent process that called listen(2) before forking is left.
So, the only option is to check if the user ID for the process
that originally listened on the AF_BUS socket and the one that
tries to update the match rules set is the same.
Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
---
net/bus/nfdbus/nfdbus.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
--- a/net/bus/nfdbus/nfdbus.c
+++ b/net/bus/nfdbus/nfdbus.c
@@ -253,12 +253,14 @@ static void nfdbus_nl_send_reply(struct
* nfdbus_check_perm - check if a pid is allowed to update match rules
* @sockaddr_bus: the socket address of the bus
* @pid: the process id that wants to update the match rules set
+ * @creds: the credentials for the process that wants to update the match rules
*
- * Test if a given process id is allowed to update the match rules set
- * for this bus. Only the process that owns the bus master listen socket
- * is allowed to update the match rules set for the bus.
+ * Test if a given process is allowed to update the match rules set
+ * for this bus. Only processes from the same user that owns the bus master
+ * listen socket are allowed to update the match rules set for the bus.
*/
-static bool nfdbus_check_perm(struct sockaddr_bus *sbusname, pid_t pid)
+static bool nfdbus_check_perm(struct sockaddr_bus *sbusname, pid_t pid,
+ struct ucred *creds)
{
struct net *net = get_net_ns_by_pid(pid);
struct sock *s;
@@ -289,7 +291,7 @@ static bool nfdbus_check_perm(struct soc
addr->name->sbus_family == sbusname->sbus_family &&
addr->name->sbus_addr.s_addr == BUS_MASTER_ADDR &&
bus_same_bus(addr->name, sbusname) &&
- pid_nr(s->sk_peer_pid) == pid) {
+ s->sk_peer_cred->uid == creds->uid) {
spin_unlock(&bus_address_lock);
return true;
}
@@ -312,8 +314,9 @@ static void cn_cmd_cb(struct cn_msg *msg
pr_debug("nfdbus: %s nsp->pid=%d pid=%d\n", __func__, nsp->pid, pid);
- if (!nfdbus_check_perm(&nlp->addr, pid)) {
- pr_debug(KERN_ERR "nfdbus: pid=%d is not allowed!\n", pid);
+ if (!nfdbus_check_perm(&nlp->addr, pid, &nsp->creds)) {
+ pr_debug(KERN_ERR "nfdbus: pid=%d uid=%d is not allowed!\n",
+ pid, nsp->creds.uid);
retcode = EPERM;
goto fail;
}