1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-11 12:46:49 +00:00

fix(storages): pool sources take real device and export paths, a leading special character is refused

The source check of a new logical or NFS pool accepted only letters,
digits and "/", which refused paths such as /dev/mapper/vg0-data,
/dev/disk/by-id/wwn-..., /dev/disk/by-path/pci-0000:00:1f.2-ata-1 or
/export/vm_images. The target check let any first character but "-"
through, so a quote, "<" or "&" reached the pool XML and libvirt failed
on it.

Target and source now share one expression: letters, digits, "/", "_",
".", ":" and "-" (not first, not right after "/"), still in linear time.
The Vagrant computes' NFS export becomes /srv/wvc-nfs, created through the
page in the live pool test.
This commit is contained in:
catborise 2026-10-19 12:09:34 +03:00
parent baeb023da2
commit c8b0cb3a4a
4 changed files with 44 additions and 12 deletions

View file

@ -3,6 +3,12 @@ import re
from django import forms
from django.utils.translation import gettext_lazy as _
# pool target and source paths, both put into the pool XML: letters, digits,
# "/", "_", ".", ":" (/dev/disk/by-path names) and "-" not first and not right
# after "/". Written without nested repetition, which backtracked
# exponentially on crafted input.
POOL_PATH = re.compile(r"(?!-)(?:[/0-9a-zA-Z_.:]|(?<!/)-)+")
class AddStgPool(forms.Form):
name = forms.CharField(
@ -38,10 +44,7 @@ class AddStgPool(forms.Form):
def clean_target(self):
storage_type = self.cleaned_data["stg_type"]
target = self.cleaned_data["target"]
# letters, digits, "_", ".", "/" and "-" not right after "/"; not
# starting with "-". Written without nested repetition, which
# backtracked exponentially on crafted input.
have_symbol = re.match(r"^[^-](?:[/0-9a-zA-Z_.]|(?<!/)-)*$", target)
have_symbol = POOL_PATH.fullmatch(target)
if storage_type in ["dir", "netfs"] and not have_symbol:
raise forms.ValidationError(
_("The target must not contain any special characters")
@ -53,7 +56,7 @@ class AddStgPool(forms.Form):
def clean_source(self):
storage_type = self.cleaned_data["stg_type"]
source = self.cleaned_data["source"]
have_symbol = re.match(r"^[a-zA-Z0-9\/]+$", source)
have_symbol = POOL_PATH.fullmatch(source)
if storage_type in ["logical", "netfs"]:
if not source:
raise forms.ValidationError(_("No device or path has been entered"))