Skip to content

Conversation

elliefm
Copy link
Contributor

@elliefm elliefm commented Aug 22, 2025

#5573 reports that, when Cyrus is configured with mail and search indexes being stored in the same directory, like this:

defaultpartition: default
partition-default: /var/spool/imap
defaultsearchtier: default
defaultsearchpartition-default: /var/spool/imap

... then compacting the xapian indexes will remove all the mail and metadata files. Seems like xapian, at least, expects total control over the directories it's configured to use. Given that, Cyrus shouldn't be allowed to start up in this configuration.

I don't think it makes sense for any of the *partition-* settings to share directories with one another. Even if some combination doesn't currently break, I don't believe we expect these to overlap, so that combination might break in the future.

This PR adds a sanity check to make sure that no partitions are sharing directories, nor are descendants of one another. If this sort of sharing is detected, master and squatter will now refuse to start, as will any other cyrus service or tool that requests partition data (via the CONFIG_NEED_PARTITION_DATA argument to cyrus_init()). Details of the collisions are logged to syslog. cyr_info conf-lint will detect and report the bad entries in the same way it reports other bad entries.

The sanity checking is based on string comparisons of the configured paths; actual filesystem details are not examined. So it's probably possible to subvert the checks using symlinks or other trickiness, but I don't think I care -- just don't do that.

For implementation reasons, if multiple partitions are configured as descendants of the same other partition, only the parent and one of the descendants can be reported. That's enough to prevent starting up with a bad configuration, but a really bad configuration might need several rounds of test/fix to identify and resolve all the issues.

If people already have configuration like this, what they can do to fix it prior to (or after) upgrading? Presumably rearrange their storage, then update their imapd.conf to describe the new layout. Hopefully they already know how to do this.

@elliefm elliefm force-pushed the v313/cyr-2103-sanity-check-dup-partitions branch 7 times, most recently from f5547f9 to 7dd7b08 Compare August 27, 2025 01:09
@elliefm elliefm marked this pull request as ready for review August 27, 2025 02:11
@elliefm elliefm linked an issue Aug 27, 2025 that may be closed by this pull request
Copy link
Member

@rsto rsto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks to do what the PR says it does, but I'd appreciate it getting somewhat more documented. I don't think a future reader will understand easily what that code does.

0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, /* interesting */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the interesting bit?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like SP has been moved to sort after /. Is that correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment here only highlights which lines are actually different from a straight 00-ff order; the details are explained below, on the function where the lookup table is used.

Looks like SP has been moved to sort after /. Is that correct?

Not quite...

The 0x20 ... 0x2f rows have been rearranged to be 0x21 ... 0x2f, 0x20. This means when you look up index / (0x2f), the value retrieved is 0x20, which is the first printable. When you look up any other other index in the 0x2_ range (punctuation), the value you get back is one higher than it would otherwise have been, to compensate for 0x2f having been changed. This means / sorts before all other printable characters, but otherwise the relative sorting is unchanged. It does look like SP was moved, but this table is values retrieved, not the input chars, so actually it is / that was moved.

The comment on the function below says:

* Treats '/' (0x2f) as lower than other printables so that
 * file paths sort pre-order, depth-first.
 * XXX This should probably be in lib/bsearch.c, but that's in
 * XXX libcyrus, which we don't have here.
 */
static int cmpstringp_path(const void *aa, const void *bb)
{

Is this not sufficient?

Copy link
Contributor

@ksmurchison ksmurchison left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code is approved. I agree with rsto that it could use some more commentary.

Copy link
Contributor

@wolfsage wolfsage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice safety check.

I don't think it accounts for symlinks. Should it? Or should the docs specify it has this weakness if not?

Beyond that, I think we should strarray_free's previous declaration as noted...

@elliefm
Copy link
Contributor Author

elliefm commented Aug 29, 2025

I don't think it accounts for symlinks. Should it? Or should the docs specify it has this weakness if not?

I addressed that in the PR description already:

The sanity checking is based on string comparisons of the configured paths; actual filesystem details are not examined. So it's probably possible to subvert the checks using symlinks or other trickiness, but I don't think I care -- just don't do that.

If some sysadmin knows they can't configure multiple partitions to the same path (because Cyrus is refusing to start, or cyr_info conf-lint is complaining), but they manage to fudge things enough to trick the sanity checker into allowing it, the consequences are all theirs.

@elliefm elliefm force-pushed the v313/cyr-2103-sanity-check-dup-partitions branch from fa67b36 to 37b13b9 Compare August 29, 2025 03:04
@wolfsage
Copy link
Contributor

I don't think it accounts for symlinks. Should it? Or should the docs specify it has this weakness if not?

I addressed that in the PR description already:

Apologies, I had read the commit messages but skimmed the pr desc too quickly

@elliefm elliefm requested a review from wolfsage September 3, 2025 01:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

squatter deleted all of my users' mail when I told it to compact
4 participants