Skip to content

canonicalize() calls fail in restrictive environments (ACCESS_DENIED) #516

@venkatesh6114

Description

@venkatesh6114

Description:

When running MathCAT in restrictive environments (e.g., container), the calls to std::fs::canonicalize() fail with ACCESS_DENIED errors, preventing MathCAT from initializing.

Problem:

canonicalize() requires the OS to resolve symlinks and validate every component of the path, which involves filesystem-level permission checks. In environments with restricted filesystem access, this fails even when the target files are readable.

The affected locations are:
prefs.rs — PreferenceManager::initialize() (line ~263)
shim_filesystem.rs — canonicalize_shim() and read_to_string_shim()

Expected behavior

MathCAT should gracefully handle canonicalize failures by either

  1. falling back to constructing an absolute path manually (e.g., joining relative paths with the current working directory) or
  2. by providing new api like set_rules_dir_with_absolute_path(). I guess, the core logic only needs consistent absolute paths — full symlink resolution is not required.

For the internal testing, I have tried the first approach, it is working in restrictive environments.

prefs.rs:

 pub fn initialize(&mut self, rules_dir: PathBuf) -> Result<()> {
        #[cfg(not(feature = "include-zip"))]
        let rules_dir = match rules_dir.canonicalize() {
            Err(_e) => {
                // fallback code to absolute path - Start
                if rules_dir.is_absolute() {
                    rules_dir
                } else {
                    std::env::current_dir()
                        .unwrap_or_default()
                        .join(&rules_dir)
                }
                // fallback code to absolute path - end
            },
            Ok(rules_dir) =>  rules_dir,
        };

shim_filesystem.rs

        pub fn canonicalize_shim(path: &Path) -> std::io::Result<PathBuf> {
            match path.canonicalize() {
                Ok(p) => Ok(p),
                Err(_) => {
                    // Fallback: if canonicalize fails (e.g., ACCESS_DENIED),
                    // construct an absolute path manually
                    if path.is_absolute() {
                        Ok(path.to_path_buf())
                    } else {
                        Ok(std::env::current_dir().unwrap_or_default().join(path))
                    }
                }
            }
        }
       
        pub fn read_to_string_shim(path: &Path) -> Result<String> {
            let path = match path.canonicalize() {
                Ok(path) => path,
                Err(_) => path.to_path_buf(), // fallback option
            };
            info!("Reading file '{}'", &path.display());
            match std::fs::read_to_string(&path) {
                Ok(str) => return Ok(str),
                Err(e) => bail!("Read error while trying to read {}: {}", &path.display(), e),
            }
        } 

If anyone has any other better solutions to this problem, please share your suggestions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions