From: "Lukas Wagner" <l.wagner@proxmox.com>
To: "Thomas Lamprecht" <t.lamprecht@proxmox.com>,
"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:19:40 +0200 [thread overview]
Message-ID: <DIJ50FJUXRLY.344IK0CO8NZM1@proxmox.com> (raw)
In-Reply-To: <20260515090637.950992-1-t.lamprecht@proxmox.com>
On Fri May 15, 2026 at 11:06 AM CEST, Thomas Lamprecht wrote:
> 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.
>
Fixed for the next revision, thanks!
>> + /// 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.
>
Fixed for the next revision, thanks!
>> +/// 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`).
>
Fixed for the next revision, thanks!
> [...]
>> +impl BlockingWritableCacheNamespace {
>> + /// Remote a cache entry.
>
> nit: s/Remote/Remove/ (and on `WritableCacheNamespace::remove`).
Fixed for the next revision, thanks!
>
> [...]
>> +// 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.
Ack, will switch to a regex-based verification in the next revision!
Thanks for the feedback!
next prev parent reply other threads:[~2026-05-15 9:20 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
2026-05-15 9:19 ` Lukas Wagner [this message]
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=DIJ50FJUXRLY.344IK0CO8NZM1@proxmox.com \
--to=l.wagner@proxmox.com \
--cc=pdm-devel@lists.proxmox.com \
--cc=t.lamprecht@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