Commit b7d0949f authored by Martin Krastev's avatar Martin Krastev Committed by Zack Rusin

drm/vmwgfx: Refactor vmw_mksstat_remove_ioctl to expect pgid match with...

drm/vmwgfx: Refactor vmw_mksstat_remove_ioctl to expect pgid match with vmw_mksstat_add_ioctl to authorise removal.

Original vmw_mksstat_remove_ioctl expected pid to match the corresponding vmw_mksstat_add_ioctl.
That made impossible en-masse removals by one pid, which is a valid use case, so pid match was
discarded. Current change enforces a broader pgid match as a form of protection from arbitrary
processes interrupting an ongoing mks-guest-stats.
Reviewed-by: default avatarZack Rusin <zackr@vmware.com>
Signed-off-by: default avatarMartin Krastev <krastevm@vmware.com>
Signed-off-by: default avatarZack Rusin <zackr@vmware.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210609172307.131929-8-zackr@vmware.com
parent 8d9a8d9b
...@@ -1111,7 +1111,7 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data, ...@@ -1111,7 +1111,7 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data,
hypervisor_ppn_add((PPN64)page_to_pfn(page)); hypervisor_ppn_add((PPN64)page_to_pfn(page));
dev_priv->mksstat_user_pages[slot] = page; dev_priv->mksstat_user_pages[slot] = page;
atomic_set(&dev_priv->mksstat_user_pids[slot], current->pid); atomic_set(&dev_priv->mksstat_user_pids[slot], task_pgrp_vnr(current));
arg->id = slot; arg->id = slot;
...@@ -1158,37 +1158,31 @@ int vmw_mksstat_remove_ioctl(struct drm_device *dev, void *data, ...@@ -1158,37 +1158,31 @@ int vmw_mksstat_remove_ioctl(struct drm_device *dev, void *data,
struct vmw_private *const dev_priv = vmw_priv(dev); struct vmw_private *const dev_priv = vmw_priv(dev);
const size_t slot = arg->id; const size_t slot = arg->id;
pid_t pid0; pid_t pgid, pid;
if (slot >= ARRAY_SIZE(dev_priv->mksstat_user_pids)) if (slot >= ARRAY_SIZE(dev_priv->mksstat_user_pids))
return -EINVAL; return -EINVAL;
DRM_DEV_INFO(dev->dev, "pid=%d arg.id=%lu\n", current->pid, slot); DRM_DEV_INFO(dev->dev, "pid=%d arg.id=%lu\n", current->pid, slot);
pid0 = atomic_read(&dev_priv->mksstat_user_pids[slot]); pgid = task_pgrp_vnr(current);
pid = atomic_cmpxchg(&dev_priv->mksstat_user_pids[slot], pgid, MKSSTAT_PID_RESERVED);
if (!pid0) if (!pid)
return 0; return 0;
if (pid0 != MKSSTAT_PID_RESERVED) { if (pid == pgid) {
const pid_t pid1 = atomic_cmpxchg(&dev_priv->mksstat_user_pids[slot], pid0, MKSSTAT_PID_RESERVED); struct page *const page = dev_priv->mksstat_user_pages[slot];
if (!pid1) BUG_ON(!page);
return 0;
if (pid1 == pid0) {
struct page *const page = dev_priv->mksstat_user_pages[slot];
BUG_ON(!page); dev_priv->mksstat_user_pages[slot] = NULL;
atomic_set(&dev_priv->mksstat_user_pids[slot], 0);
dev_priv->mksstat_user_pages[slot] = NULL;
atomic_set(&dev_priv->mksstat_user_pids[slot], 0);
hypervisor_ppn_remove((PPN64)page_to_pfn(page)); hypervisor_ppn_remove((PPN64)page_to_pfn(page));
vmw_mksstat_cleanup_descriptor(page); vmw_mksstat_cleanup_descriptor(page);
return 0; return 0;
}
} }
return -EAGAIN; return -EAGAIN;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment