coreos / ignition

First boot installer and configuration tool

Home Page:https://coreos.github.io/ignition/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ignition should fail validation if a file conflicts with the parent directory of another file/link/dir

marmijo opened this issue · comments

Bug

Operating System Version

Any

Ignition Version

All

Environment

All

Expected Behavior

Ignition should not allow internally inconsistent configs

Actual Behavior

Users can specify a file that would conflict with the parent directory of another file/link/dir. Ignition should fail validation if files/links/dirs conflict with implicit parent directories.

Reproduction Steps

1 - Write a config with a file at /foo/bar and a file /foo/bar/baz
OR
1 - Write a config with a file at /foo/bar and a directory at /foo/bar/baz
OR
1 - Write a config with a file at /foo/bar and a link at /foo/bar/baz

Other Information

On top of general validation for this issue, the validation added by Ignition PR#1456 may need to be updated to include the fix as well.

Hey @marmijo, could you please provide more context about this?
I'm trying to understand the reproduction steps more clearly.
Do I need to write a configuration using Butane and then check the resulting Ignition file?

Thank you! 😸

Hi Yasmin. Yes, you could use butane to create the ignition config. To reproduce, you'll need the resulting ignition config that has the file/link/dir conflicts specified like the ones above and run it through ignition validation. It currently doesn't fail validation but it should. It should be noted that butane isn't needed to write an ignition config, so ignition validation code is needed here.

Basically, it's possible to create an ignition config with two files that conflict with one another in such a way that one file would be an implicit parent directory of the other e.g. /var/home/core/log (as a file) and /var/home/core/log/output.txt (which now declares log as a directory).

Note: when we add this verification, we need to try and not reduce functionality.

Its completely reasonable to have a file /home/bar/zed and a dir home/bar/zed/
with a file in it at /home/bar/zed/zed

AFAIK, Linux disallows dirs/files/links/pipes with the same name in the same directory. It shouldn't be possible to create /home/bar/zed/zed if /home/bar/zed already exists as a file/link.
The same is true for creating a file/link at /home/bar/zed when /home/bar/zed/zed already exists.

@marmijo Wdyt about simply validating that files end with an extension ?
I think it solves thie issue more directly. and more cleanly. Checking for collisions feels clumsy.

@prestist That doesn't really fix it. It's perfectly valid for directories to have "extensions" and files not to.

I don't think it'd be too hard to validate this. See e.g. getOrderedCreationList() which already knows how to sort paths from most shallow to deepest. So you can sort all entries, then go down the list from the top. For each entry, check if its path is within the path of the previous entry. If so, verify that the previous entry is a directory. If not, fail.

Obviously, this validation can't catch symlinks that only exist on the host (e.g. if /foo/bar is a symlink to /foo/baz and the user wants a file at /foo/baz and a file at /foo/bar/baz). Those will just fail at runtime like today.

@jlebon ah, okay that was a wiff on my part, I assumed that directorys would not have extensions, what purpose does that serve for (my own knowledge) ?

Thats great, thank you for the pointer to getOrderedCreationList. @yasminvalim and my self were going through some of her tests, and I started stumbling a bit on the tests, because I was thinking that it could be possible that the directory is externally derived, however if we are using the config as truth, then with the example 1 - Write a config with a file at /foo/bar and a directory at /foo/bar/baz if we instead had
1 - Write a config with a file at /foo/bar and a directory at /foo/bar/baz and a directory at /foo/bar would be valid right?
otherwise we assume user error?

@jlebon ah, okay that was a wiff on my part, I assumed that directorys would not have extensions, what purpose does that serve for (my own knowledge) ?

The base name is mostly an arbitrary string. Indeed, by convention files tend to have extensions and directories tend not to. An common example of directories with an extension are the systemd dropin dirs (i.e. <service>.d or <target>.wants). You can run something like find / -name '*.*' -type d on your system if you want to find more examples.

if we are using the config as truth, then with the example 1 - Write a config with a file at /foo/bar and a directory at /foo/bar/baz if we instead had 1 - Write a config with a file at /foo/bar and a directory at /foo/bar/baz and a directory at /foo/bar would be valid right?

That would give duplicate entries which should already fail validation today.