xf86drm: Don't consider node names longer than the maximum allowed

This fixes the logic that decides if a node name is valid to use the
same length restrictions that are used in drmDeviceAlloc, which expects
node names to conform to a specific naming scheme (On OSes except
OpenBSD this means `/dev/dri/renderD123`). This addresses the problem of
node names that are longer than expected, while still allowing symlinks
to work.

I've also applied the same fix to the OpenBSD path, while bringing the
check that `snprintf` didn't error from OpenBSD to the main path.

Signed-off-by: Dylan Baker <dylan.c.baker@intel.com>
Tested-by: Mark Janes <markjanes@swizzler.org>
Tested-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
main
Dylan Baker 2024-02-08 12:11:18 -08:00
parent 1aa800d464
commit 7c5c742de8
1 changed files with 18 additions and 2 deletions

View File

@ -4471,14 +4471,24 @@ process_device(drmDevicePtr *device, const char *d_name,
{
struct stat sbuf;
char node[PATH_MAX + 1];
int node_type, subsystem_type;
int node_type, subsystem_type, written;
unsigned int maj, min;
const int max_node_length = ALIGN(drmGetMaxNodeName(), sizeof(void *));
node_type = drmGetNodeType(d_name);
if (node_type < 0)
return -1;
snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, d_name);
written = snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, d_name);
if (written < 0)
return -1;
/* anything longer than this will be truncated in drmDeviceAlloc.
* Account for NULL byte
*/
if (written + 1 > max_node_length)
return -1;
if (stat(node, &sbuf))
return -1;
@ -4585,6 +4595,7 @@ drm_public int drmGetDeviceFromDevId(dev_t find_rdev, uint32_t flags, drmDeviceP
const char *dev_name;
int node_type, subsystem_type;
int maj, min, n, ret;
const int max_node_length = ALIGN(drmGetMaxNodeName(), sizeof(void *));
if (device == NULL)
return -EINVAL;
@ -4603,9 +4614,14 @@ drm_public int drmGetDeviceFromDevId(dev_t find_rdev, uint32_t flags, drmDeviceP
if (!dev_name)
return -EINVAL;
/* anything longer than this will be truncated in drmDeviceAlloc.
* Account for NULL byte
*/
n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min);
if (n == -1 || n >= PATH_MAX)
return -errno;
if (written + 1 > max_node_length)
return -EINVAL
if (stat(node, &sbuf))
return -EINVAL;