summaryrefslogtreecommitdiff
path: root/bsd-core/drm_auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsd-core/drm_auth.c')
-rw-r--r--bsd-core/drm_auth.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/bsd-core/drm_auth.c b/bsd-core/drm_auth.c
index 964f9a42..aa8238c4 100644
--- a/bsd-core/drm_auth.c
+++ b/bsd-core/drm_auth.c
@@ -1,6 +1,3 @@
-/* drm_auth.h -- IOCTLs for authentication -*- linux-c -*-
- * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
- */
/*-
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
@@ -31,6 +28,11 @@
*
*/
+/** @file drm_auth.c
+ * Implementation of the get/authmagic ioctls implementing the authentication
+ * scheme between the master and clients.
+ */
+
#include "drmP.h"
static int drm_hash_magic(drm_magic_t magic)
@@ -38,11 +40,16 @@ static int drm_hash_magic(drm_magic_t magic)
return magic & (DRM_HASH_SIZE-1);
}
+/**
+ * Returns the file private associated with the given magic number.
+ */
static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
{
drm_magic_entry_t *pt;
int hash = drm_hash_magic(magic);
+ DRM_SPINLOCK_ASSERT(&dev->dev_lock);
+
for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
if (pt->magic == magic) {
return pt->priv;
@@ -52,6 +59,10 @@ static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
return NULL;
}
+/**
+ * Inserts the given magic number into the hash table of used magic number
+ * lists.
+ */
static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
{
int hash;
@@ -59,6 +70,8 @@ static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
DRM_DEBUG("%d\n", magic);
+ DRM_SPINLOCK_ASSERT(&dev->dev_lock);
+
hash = drm_hash_magic(magic);
entry = malloc(sizeof(*entry), M_DRM, M_ZERO | M_NOWAIT);
if (!entry) return ENOMEM;
@@ -79,16 +92,21 @@ static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
return 0;
}
+/**
+ * Removes the given magic number from the hash table of used magic number
+ * lists.
+ */
static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
{
drm_magic_entry_t *prev = NULL;
drm_magic_entry_t *pt;
int hash;
+ DRM_SPINLOCK_ASSERT(&dev->dev_lock);
+
DRM_DEBUG("%d\n", magic);
hash = drm_hash_magic(magic);
- DRM_LOCK();
for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
if (pt->magic == magic) {
if (dev->magiclist[hash].head == pt) {
@@ -100,16 +118,22 @@ static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
if (prev) {
prev->next = pt->next;
}
- DRM_UNLOCK();
return 0;
}
}
- DRM_UNLOCK();
free(pt, M_DRM);
return EINVAL;
}
+/**
+ * Called by the client, this returns a unique magic number to be authorized
+ * by the master.
+ *
+ * The master may use its own knowledge of the client (such as the X
+ * connection that the magic is passed over) to determine if the magic number
+ * should be authenticated.
+ */
int drm_getmagic(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
static drm_magic_t sequence = 0;
@@ -122,15 +146,15 @@ int drm_getmagic(drm_device_t *dev, void *data, struct drm_file *file_priv)
DRM_LOCK();
do {
int old = sequence;
-
+
auth->magic = old+1;
-
+
if (!atomic_cmpset_int(&sequence, old, auth->magic))
continue;
} while (drm_find_file(dev, auth->magic));
file_priv->magic = auth->magic;
- DRM_UNLOCK();
drm_add_magic(dev, file_priv, auth->magic);
+ DRM_UNLOCK();
}
DRM_DEBUG("%u\n", auth->magic);
@@ -138,6 +162,9 @@ int drm_getmagic(drm_device_t *dev, void *data, struct drm_file *file_priv)
return 0;
}
+/**
+ * Marks the client associated with the given magic number as authenticated.
+ */
int drm_authmagic(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
drm_auth_t *auth = data;