public inbox for pdm-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Thomas Lamprecht <t.lamprecht@proxmox.com>
To: Lukas Wagner <l.wagner@proxmox.com>
Cc: pdm-devel@lists.proxmox.com
Subject: Re: [PATCH datacenter-manager 1/4] add persistent, generic, namespaced key-value cache implementation
Date: Fri, 15 May 2026 11:06:29 +0200	[thread overview]
Message-ID: <20260515090637.950992-1-t.lamprecht@proxmox.com> (raw)
In-Reply-To: <20260513135457.573414-2-l.wagner@proxmox.com>

On Wed, 13 May 2026 15:54:54 +0200, Lukas Wagner wrote:
> diff --git a/server/src/namespaced_cache.rs b/server/src/namespaced_cache.rs
> new file mode 100644
> --- /dev/null
> +++ b/server/src/namespaced_cache.rs
> @@ -0,0 +1,742 @@
[...]
> +/// A generic, namespaced cache with optional value expiration.
> +pub struct NamespacedCache {
> +    base_directory: PathBuf,
> +    file_options: CreateOptions,
> +    dir_options: CreateOptions,
> +}
> +
> +impl NamespacedCache {
> +    /// Create a new cache instance.
> +    ///
> +    /// Cache entries will be persisted in the provided `base_directory`.
> +    /// `dir_options` are the [`CreateOptions`] used the namespace directories, while `file_options`

nit: s/used the/used for the/ in the doc.

> +    /// are the ones for persisted cache entries.
> +    pub fn new<P: Into<PathBuf>>(
> +        base_directory: P,
> +        dir_options: CreateOptions,
> +        file_options: CreateOptions,
> +    ) -> Self {

tiny nit: Struct and new constructr disagree on parameter order
(file_options/dir_options vs.  dir_options/file_options), but both are
the same type.

> +/// A writable cache namespace (blocking interface).
> +pub struct BlockingWritableCacheNamespace {
> +    inner: WriteableInner,
> +}
> +
> +/// A writable cache namespace (async interface).
> +pub struct WritableCacheNamespace {
> +    inner: Arc<WriteableInner>,
> +}
> +
> +struct WriteableInner {

nit: public types are `Writable`, inner is `Writeable` - unify the
spelling here (e.g.  rename to `WritableInner`).

[...]
> +impl BlockingWritableCacheNamespace {
> +    /// Remote a cache entry.

nit: s/Remote/Remove/ (and on `WritableCacheNamespace::remove`).

[...]
> +// Make sure that an identifier is safe to use as a cache key.
> +//
> +// At the moment, this only checks for '../', as to ensure that the base directory
> +// is not escaped.
> +fn ensure_valid_key(key: &str) -> Result<(), CacheError> {
> +    if key.contains("../") {
> +        return Err(CacheError::InvalidKey(key.into()));
> +    }
> +
> +    Ok(())
> +}
> +
> +// Make sure that an identifier is safe to use as a namespace.
> +//
> +// At the moment, this ensures that there is no '../' in the namespace, as well as that the
> +// identifier does not start with '/'.
> +fn ensure_valid_namespace(namespace: &str) -> Result<(), CacheError> {
> +    if namespace.contains("../") || namespace.starts_with("/") {
> +        return Err(CacheError::InvalidNamespace(namespace.into()));
> +    }
> +
> +    Ok(())
> +}

Something that I missed for the RRD fix back then w.r.t. "ensure that
the base directory is not escaped", but it's not enough to only reject
the `../` substring, as with that a couple of inputs still slip through:

 - a key like `/etc/foo` passes; joining an absolute path replaces the
   prefix, so the write ends up at `/etc/foo.json` outside the cache.
 - a namespace of just `".."` passes too (no `../` substring, no leading
   `/`), and then `base.join("..")` walks one level up.

No caller hits either today (keys are hardcoded and namespaces always go
through `format_remote_namespace`), but allowing only a known-good
character set (like the SAFE_ID regex) would match the stated intent
more directly than blocking specific substrings.




  reply	other threads:[~2026-05-15  9:07 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-13 13:54 [PATCH datacenter-manager 0/4] add generic, per-remote (and global) cache for remote API responses Lukas Wagner
2026-05-13 13:54 ` [PATCH datacenter-manager 1/4] add persistent, generic, namespaced key-value cache implementation Lukas Wagner
2026-05-15  9:06   ` Thomas Lamprecht [this message]
2026-05-15  9:19     ` Lukas Wagner
2026-05-13 13:54 ` [PATCH datacenter-manager 2/4] add api_cache as a specialized wrapper around the namespaced cache Lukas Wagner
2026-05-15  9:06   ` Thomas Lamprecht
2026-05-15  9:22     ` Lukas Wagner
2026-05-13 13:54 ` [PATCH datacenter-manager 3/4] api: resources: subscriptions: switch over to api_cache Lukas Wagner
2026-05-15  9:06   ` Thomas Lamprecht
2026-05-15  9:49     ` Lukas Wagner
2026-05-13 13:54 ` [PATCH datacenter-manager 4/4] remote-updates: switch over to new api_cache Lukas Wagner
2026-05-15  9:06   ` Thomas Lamprecht
2026-05-15 12:56     ` Lukas Wagner
2026-05-15  8:30 ` superseded: [PATCH datacenter-manager 0/4] add generic, per-remote (and global) cache for remote API responses Lukas Wagner
  -- strict thread matches above, loose matches on Subject: below --
2026-05-08 15:03 [RFC " Lukas Wagner
2026-05-08 15:03 ` [PATCH datacenter-manager 1/4] add persistent, generic, namespaced key-value cache implementation Lukas Wagner
2026-05-12 12:29   ` Wolfgang Bumiller
2026-05-13  8:45     ` Lukas Wagner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260515090637.950992-1-t.lamprecht@proxmox.com \
    --to=t.lamprecht@proxmox.com \
    --cc=l.wagner@proxmox.com \
    --cc=pdm-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal