diff --git a/xf86drm.c b/xf86drm.c index e67391b1..ac7af0d6 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -2743,6 +2743,24 @@ drm_public int drmDropMaster(int fd) return drmIoctl(fd, DRM_IOCTL_DROP_MASTER, NULL); } +drm_public bool drmIsMaster(int fd) +{ + /* Detect master by attempting something that requires master. + * + * Authenticating magic tokens requires master and 0 is an + * internal kernel detail which we could use. Attempting this on + * a master fd would fail therefore fail with EINVAL because 0 + * is invalid. + * + * A non-master fd will fail with EACCES, as the kernel checks + * for master before attempting to do anything else. + * + * Since we don't want to leak implementation details, use + * EACCES. + */ + return drmAuthMagic(fd, 0) != -EACCES; +} + drm_public char *drmGetDeviceNameFromFd(int fd) { char name[128]; diff --git a/xf86drm.h b/xf86drm.h index 7773d71a..9e920db9 100644 --- a/xf86drm.h +++ b/xf86drm.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #if defined(__cplusplus) @@ -733,6 +734,7 @@ extern void drmMsg(const char *format, ...) DRM_PRINTFLIKE(1, 2); extern int drmSetMaster(int fd); extern int drmDropMaster(int fd); +extern bool drmIsMaster(int fd); #define DRM_EVENT_CONTEXT_VERSION 4