summaryrefslogtreecommitdiff
path: root/ipc/kdbus/endpoint.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/kdbus/endpoint.c')
-rw-r--r--ipc/kdbus/endpoint.c303
1 files changed, 0 insertions, 303 deletions
diff --git a/ipc/kdbus/endpoint.c b/ipc/kdbus/endpoint.c
deleted file mode 100644
index 5694ff6dc..000000000
--- a/ipc/kdbus/endpoint.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (C) 2013-2015 Kay Sievers
- * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
- * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
- * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
- * Copyright (C) 2013-2015 Linux Foundation
- * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
- *
- * kdbus is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- */
-
-#include <linux/fs.h>
-#include <linux/idr.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/sizes.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/uio.h>
-
-#include "bus.h"
-#include "connection.h"
-#include "domain.h"
-#include "endpoint.h"
-#include "handle.h"
-#include "item.h"
-#include "message.h"
-#include "policy.h"
-
-static void kdbus_ep_free(struct kdbus_node *node)
-{
- struct kdbus_ep *ep = container_of(node, struct kdbus_ep, node);
-
- WARN_ON(!list_empty(&ep->conn_list));
-
- kdbus_policy_db_clear(&ep->policy_db);
- kdbus_bus_unref(ep->bus);
- kdbus_user_unref(ep->user);
- kfree(ep);
-}
-
-static void kdbus_ep_release(struct kdbus_node *node, bool was_active)
-{
- struct kdbus_ep *ep = container_of(node, struct kdbus_ep, node);
-
- /* disconnect all connections to this endpoint */
- for (;;) {
- struct kdbus_conn *conn;
-
- mutex_lock(&ep->lock);
- conn = list_first_entry_or_null(&ep->conn_list,
- struct kdbus_conn,
- ep_entry);
- if (!conn) {
- mutex_unlock(&ep->lock);
- break;
- }
-
- /* take reference, release lock, disconnect without lock */
- kdbus_conn_ref(conn);
- mutex_unlock(&ep->lock);
-
- kdbus_conn_disconnect(conn, false);
- kdbus_conn_unref(conn);
- }
-}
-
-/**
- * kdbus_ep_new() - create a new endpoint
- * @bus: The bus this endpoint will be created for
- * @name: The name of the endpoint
- * @access: The access flags for this node (KDBUS_MAKE_ACCESS_*)
- * @uid: The uid of the node
- * @gid: The gid of the node
- * @is_custom: Whether this is a custom endpoint
- *
- * This function will create a new endpoint with the given
- * name and properties for a given bus.
- *
- * Return: a new kdbus_ep on success, ERR_PTR on failure.
- */
-struct kdbus_ep *kdbus_ep_new(struct kdbus_bus *bus, const char *name,
- unsigned int access, kuid_t uid, kgid_t gid,
- bool is_custom)
-{
- struct kdbus_ep *e;
- int ret;
-
- /*
- * Validate only custom endpoints names, default endpoints
- * with a "bus" name are created when the bus is created
- */
- if (is_custom) {
- ret = kdbus_verify_uid_prefix(name, bus->domain->user_namespace,
- uid);
- if (ret < 0)
- return ERR_PTR(ret);
- }
-
- e = kzalloc(sizeof(*e), GFP_KERNEL);
- if (!e)
- return ERR_PTR(-ENOMEM);
-
- kdbus_node_init(&e->node, KDBUS_NODE_ENDPOINT);
-
- e->node.free_cb = kdbus_ep_free;
- e->node.release_cb = kdbus_ep_release;
- e->node.uid = uid;
- e->node.gid = gid;
- e->node.mode = S_IRUSR | S_IWUSR;
- if (access & (KDBUS_MAKE_ACCESS_GROUP | KDBUS_MAKE_ACCESS_WORLD))
- e->node.mode |= S_IRGRP | S_IWGRP;
- if (access & KDBUS_MAKE_ACCESS_WORLD)
- e->node.mode |= S_IROTH | S_IWOTH;
-
- mutex_init(&e->lock);
- INIT_LIST_HEAD(&e->conn_list);
- kdbus_policy_db_init(&e->policy_db);
- e->bus = kdbus_bus_ref(bus);
-
- ret = kdbus_node_link(&e->node, &bus->node, name);
- if (ret < 0)
- goto exit_unref;
-
- /*
- * Transactions on custom endpoints are never accounted on the global
- * user limits. Instead, for each custom endpoint, we create a custom,
- * unique user, which all transactions are accounted on. Regardless of
- * the user using that endpoint, it is always accounted on the same
- * user-object. This budget is not shared with ordinary users on
- * non-custom endpoints.
- */
- if (is_custom) {
- e->user = kdbus_user_lookup(bus->domain, INVALID_UID);
- if (IS_ERR(e->user)) {
- ret = PTR_ERR(e->user);
- e->user = NULL;
- goto exit_unref;
- }
- }
-
- return e;
-
-exit_unref:
- kdbus_node_drain(&e->node);
- kdbus_node_unref(&e->node);
- return ERR_PTR(ret);
-}
-
-/**
- * kdbus_ep_ref() - increase the reference counter of a kdbus_ep
- * @ep: The endpoint to reference
- *
- * Every user of an endpoint, except for its creator, must add a reference to
- * the kdbus_ep instance using this function.
- *
- * Return: the ep itself
- */
-struct kdbus_ep *kdbus_ep_ref(struct kdbus_ep *ep)
-{
- if (ep)
- kdbus_node_ref(&ep->node);
- return ep;
-}
-
-/**
- * kdbus_ep_unref() - decrease the reference counter of a kdbus_ep
- * @ep: The ep to unref
- *
- * Release a reference. If the reference count drops to 0, the ep will be
- * freed.
- *
- * Return: NULL
- */
-struct kdbus_ep *kdbus_ep_unref(struct kdbus_ep *ep)
-{
- if (ep)
- kdbus_node_unref(&ep->node);
- return NULL;
-}
-
-/**
- * kdbus_ep_is_privileged() - check whether a file is privileged
- * @ep: endpoint to operate on
- * @file: file to test
- *
- * Return: True if @file is privileged in the domain of @ep.
- */
-bool kdbus_ep_is_privileged(struct kdbus_ep *ep, struct file *file)
-{
- return !ep->user &&
- file_ns_capable(file, ep->bus->domain->user_namespace,
- CAP_IPC_OWNER);
-}
-
-/**
- * kdbus_ep_is_owner() - check whether a file should be treated as bus owner
- * @ep: endpoint to operate on
- * @file: file to test
- *
- * Return: True if @file should be treated as bus owner on @ep
- */
-bool kdbus_ep_is_owner(struct kdbus_ep *ep, struct file *file)
-{
- return !ep->user &&
- (uid_eq(file->f_cred->euid, ep->bus->node.uid) ||
- kdbus_ep_is_privileged(ep, file));
-}
-
-/**
- * kdbus_cmd_ep_make() - handle KDBUS_CMD_ENDPOINT_MAKE
- * @bus: bus to operate on
- * @argp: command payload
- *
- * Return: NULL or newly created endpoint on success, ERR_PTR on failure.
- */
-struct kdbus_ep *kdbus_cmd_ep_make(struct kdbus_bus *bus, void __user *argp)
-{
- const char *item_make_name;
- struct kdbus_ep *ep = NULL;
- struct kdbus_cmd *cmd;
- int ret;
-
- struct kdbus_arg argv[] = {
- { .type = KDBUS_ITEM_NEGOTIATE },
- { .type = KDBUS_ITEM_MAKE_NAME, .mandatory = true },
- };
- struct kdbus_args args = {
- .allowed_flags = KDBUS_FLAG_NEGOTIATE |
- KDBUS_MAKE_ACCESS_GROUP |
- KDBUS_MAKE_ACCESS_WORLD,
- .argv = argv,
- .argc = ARRAY_SIZE(argv),
- };
-
- ret = kdbus_args_parse(&args, argp, &cmd);
- if (ret < 0)
- return ERR_PTR(ret);
- if (ret > 0)
- return NULL;
-
- item_make_name = argv[1].item->str;
-
- ep = kdbus_ep_new(bus, item_make_name, cmd->flags,
- current_euid(), current_egid(), true);
- if (IS_ERR(ep)) {
- ret = PTR_ERR(ep);
- ep = NULL;
- goto exit;
- }
-
- if (!kdbus_node_activate(&ep->node)) {
- ret = -ESHUTDOWN;
- goto exit;
- }
-
-exit:
- ret = kdbus_args_clear(&args, ret);
- if (ret < 0) {
- if (ep) {
- kdbus_node_drain(&ep->node);
- kdbus_ep_unref(ep);
- }
- return ERR_PTR(ret);
- }
- return ep;
-}
-
-/**
- * kdbus_cmd_ep_update() - handle KDBUS_CMD_ENDPOINT_UPDATE
- * @ep: endpoint to operate on
- * @argp: command payload
- *
- * Return: >=0 on success, negative error code on failure.
- */
-int kdbus_cmd_ep_update(struct kdbus_ep *ep, void __user *argp)
-{
- struct kdbus_cmd *cmd;
- int ret;
-
- struct kdbus_arg argv[] = {
- { .type = KDBUS_ITEM_NEGOTIATE },
- { .type = KDBUS_ITEM_NAME, .multiple = true },
- { .type = KDBUS_ITEM_POLICY_ACCESS, .multiple = true },
- };
- struct kdbus_args args = {
- .allowed_flags = KDBUS_FLAG_NEGOTIATE,
- .argv = argv,
- .argc = ARRAY_SIZE(argv),
- };
-
- ret = kdbus_args_parse(&args, argp, &cmd);
- if (ret != 0)
- return ret;
-
- ret = kdbus_policy_set(&ep->policy_db, args.items, args.items_size,
- 0, true, ep);
- return kdbus_args_clear(&args, ret);
-}