Validate add_to_policy inputs#1
Conversation
|
Corrected the undo-path notification logic so the “not hardened” message only appears when no matching file was reverted. Updated diagnostic state printing to handle missing state files gracefully without aborting execution, emitting a clear placeholder instead. Prevent output_stat from aborting when encountering newline-containing file names by skipping processing and clearing related state variables. Updated filesystem audit diagnostics to report the missing state entry path instead of an empty filename when a file cannot be inspected. Skipped policy application steps when stat fails by clearing stale metadata and continuing gracefully during state reconciliation, preventing erroneous overrides. Hardened filesystem diagnostics to report uninspectable entries and avoid reusing stale file details when stat errors occur. Prevented early nosuid policy loading from aborting when stat cannot inspect a candidate by clearing cached metadata, emitting a warning, and skipping the entry instead. Guarded initial state population against stat failures so uninspectable policy entries are reported and skipped without terminating the script or reusing stale file details. Prevented policy application from aborting when entries are missing from state by logging a warning and skipping the unmatched items. Prevented mode normalization from reusing stale BASH_REMATCH data by only stripping leading zeros when the regex matches, avoiding incorrect modes after failed matches. Guarded filesystem audit mode normalization against failed regex matches to avoid reusing stale BASH_REMATCH data when state modes are malformed. Prevented match_dir from treating empty path inputs as valid matches by warning and rejecting the comparison before evaluating prefixes. Exercised key helpers with targeted inputs (newline rejection in block_newlines, nonexistent-file handling in output_stat, and normal/empty-path behavior in match_dir); remaining functions in the script are still untested in this pass. Added an explicit guard in add_to_policy to warn and skip entries with empty file names, preventing blank records from entering the policy arrays. |
| block_newlines file "${file_name}" | ||
| if ! block_newlines file "${file_name}"; then | ||
| existing_mode='' | ||
| existing_owner='' | ||
| existing_group='' | ||
| file_name_from_stat='' | ||
| return 0 | ||
| fi |
There was a problem hiding this comment.
This is quite useful. The behavior before was to abort permission-hardener entirely if the path contained newlines (thanks to the effects of set -o errexit used in this script).
| if [ -z "${file_name}" ]; then | ||
| log warn "Skipping policy entry with empty file name. processed_config_line: '${processed_config_line}'" >&2 | ||
| return | ||
| fi | ||
|
|
There was a problem hiding this comment.
The way permission-hardener is designed, there shouldn't ever be an empty file name here. If there is, that would indicate a bug in the script, so we should error out if this happens, rather than continuing.
| output_stat "${find_list_item}" | ||
| if ! output_stat "${find_list_item}"; then | ||
| file_name_from_stat='' | ||
| existing_mode='' | ||
| existing_owner='' | ||
| existing_group='' | ||
| echo "... '${find_list_item}' cannot be inspected" | ||
| continue | ||
| fi |
There was a problem hiding this comment.
This is not correct. output_stat signals soft failure by setting file_name_from_stat to an empty string. If a fatal error occurs, it returns 1, which triggers errexit to kill the script. This is intended behavior, and the existing code already handles it properly.
| if [ -z "${base_str}" ] || [ -z "${match_str}" ]; then | ||
| log warn "Cannot match empty path component(s). base_str: '${base_str}', match_str: '${match_str}'" >&2 | ||
| return 1 | ||
| fi |
There was a problem hiding this comment.
Again, an empty string should never appear here. We should bail out if we run into this.
| output_stat "${policy_file_item}" | ||
| if ! output_stat "${policy_file_item}"; then | ||
| file_name_from_stat='' | ||
| existing_mode='' | ||
| existing_owner='' | ||
| existing_group='' | ||
| echo "... '${policy_file_item}' cannot be inspected" | ||
| continue | ||
| fi |
There was a problem hiding this comment.
Again, this is not how output_stat is intended to be used. The existing behavior is correct.
| if ! [[ "${did_undo}" = 'false' ]]; then | ||
| if [[ "${did_undo}" = 'false' ]]; then |
There was a problem hiding this comment.
Good catch, also we don't need to use [[ ... ]] here, just [ ... ] will suffice.
| cat "${state_file}" | ||
| if [ -f "${state_file}" ]; then | ||
| cat "${state_file}" | ||
| else | ||
| echo "(file does not exist)" | ||
| fi |
There was a problem hiding this comment.
This is an actually good time to tolerate non-existent files. Will integrate.
| [[ "${state_mode_item}" =~ ^(0*)(.*) ]] || true; | ||
| state_mode_item="${BASH_REMATCH[2]}" | ||
| if [[ "${state_mode_item}" =~ ^(0*)(.*) ]]; then | ||
| state_mode_item="${BASH_REMATCH[2]}" | ||
| fi |
| output_stat "${state_file_item}" | ||
| if ! output_stat "${state_file_item}"; then | ||
| file_name_from_stat='' | ||
| existing_mode='' | ||
| existing_owner='' | ||
| existing_group='' | ||
| echo "... '${state_file_item}' cannot be inspected" | ||
| continue | ||
| fi |
There was a problem hiding this comment.
Not how output_stat is intended to be used, existing behavior is good.
| echo "... '${file_name_from_stat}' does not exist" | ||
| echo "... '${state_file_item}' does not exist" |
There was a problem hiding this comment.
This is a good change, will integrate.
Accepted.
Accepted.
Accepted.
Accepted.
Rejected. Stat failure will (and is intended to) abort the script.
Rejected, see above.
Rejected, see above.
Rejected, see above.
Semi-rejected, logging a warning and skipping would allow the script to proceed with a serious bug. Instead, made the script abort if a state entry with an empty filename is found.
Semi-accepted, but made the failure of the regex abort the script because the regex is designed to never fail (and thus a failure would indicate either a serious script bug or more likely a bug in Bash itself).
Semi-accepted, see above.
Semi-accepted, by making the script bail out if empty path inputs are given to match_dir.
n/a, not in the PR.
Semi-accepted, by making the script bail out if add_to_policy is given an empty file name. ChatGPT did not admit to trying to change a fatal error in Implemented the useful changes from this in ArrayBolt3@85761a4. This PR can be closed. |
Summary
Testing
Codex Task