Skip to content

ENT-10961, CFE-1840: Files promise can now modify immutable bit in file system attributes #5752

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 38 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d7e8ff3
Added utility functions to override immutable bit
larsewi Mar 28, 2025
4ebc7b2
Added body syntax for controlling file system attributes
larsewi Jan 28, 2025
5243590
Files promise can now modify immutable bit in file system attributes
larsewi Feb 6, 2025
1e74204
Added argument to NOOP OverrideImmutable functions
larsewi Apr 1, 2025
c07955f
Combined OverrideImmutable[Commit|Abort] functions
larsewi Apr 1, 2025
d5ada41
Content attribute can now override immutable bit
larsewi Apr 1, 2025
c9ba31d
Store override_immutable variable in EvalContext
larsewi Apr 3, 2025
0c53319
Added function to override immutable bit and rename file
larsewi Apr 3, 2025
83e0ed8
copy_from attribute can now override immutable bit
larsewi Apr 3, 2025
b69401b
Added function to override immutable bit and delete file
larsewi Apr 3, 2025
f8db2b0
delete attribute can now override immutable bit
larsewi Apr 3, 2025
1e6b326
edit_line and edit_xml attributes can now override immutable bit
larsewi Apr 4, 2025
d1f222a
override_fsattrs.c: refactored code
larsewi May 22, 2025
2cf862f
Touch attribute can now override immutable bit
larsewi May 22, 2025
048e9a6
Made functions for temporarily clear/reset immutable bit public
larsewi May 23, 2025
d5394a0
Transformer attribute can now override immutable bit
larsewi May 23, 2025
81bc75e
OverrideImmutableRename() new file inherits immutable flag of old
larsewi May 26, 2025
2db3cf9
Rename attribute can now override immutable bit
larsewi May 26, 2025
ec88ef0
Perms attribute can now override immutable bit
larsewi May 26, 2025
1823cff
acl attribute can now override immutable bit
larsewi May 26, 2025
dab2d99
evalfunction.c: Removed trailing whitespace
larsewi May 28, 2025
983faa4
Added policy function to get ACLs
larsewi May 28, 2025
4b6c26e
Added acceptance test for getacls()
larsewi Jun 2, 2025
4053710
Added acceptance test to set immutable bit
larsewi Jun 13, 2025
c99718d
Added acceptance test to clear immutable bit
larsewi Jun 13, 2025
5b13fea
Added acceptance test for immutable with content
larsewi Jun 13, 2025
841a313
Added acceptance test for immutable with copy_from
larsewi Jun 13, 2025
f75ea3b
Added acceptance test for immutable with delete
larsewi Jun 13, 2025
8e85661
Added acceptance test for immutable with edit_line
larsewi Jun 13, 2025
9f2b689
Added acceptance test for immutable with edit_xml
larsewi Jun 13, 2025
23b6519
Added acceptance test for immutable with perms
larsewi Jun 13, 2025
6b0b70d
Added acceptance test for immutable with touch
larsewi Jun 13, 2025
587ed51
Added acceptance test for immutable with edit_template
larsewi Jun 13, 2025
4369f2f
Added acceptance test for immutable with acl
larsewi Jun 13, 2025
40a4547
Added acceptance test for immutable with transformer
larsewi Jun 13, 2025
b0ce49b
Added acceptance test for immutable with rename
larsewi Jun 13, 2025
c61fe03
Added context to log messages in OverrideImmutableCommit
larsewi Jun 13, 2025
7dc51ff
Make it more clear what the override argument does
larsewi Jun 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions cf-agent/verify_files.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
static PromiseResult FindFilePromiserObjects(EvalContext *ctx, const Promise *pp);
static PromiseResult VerifyFilePromise(EvalContext *ctx, char *path, const Promise *pp);
static PromiseResult WriteContentFromString(EvalContext *ctx, const char *path, const Attributes *attr,
const Promise *pp, bool override_immutable);
const Promise *pp);

/*****************************************************************************/

Expand Down Expand Up @@ -406,7 +406,7 @@ static PromiseResult VerifyFilePromise(EvalContext *ctx, char *path, const Promi
/* If we encounter any promises to mutate the file and the immutable
* attribute in body fsattrs is "true", we will override the immutable bit
* by temporarily clearing it when ever needed. */
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* by temporarily clearing it when ever needed. */
* by temporarily clearing it whenever needed. */

const bool override_immutable = a.havefsattrs && a.fsattrs.haveimmutable && a.fsattrs.immutable && is_immutable;
EvalContextOverrideImmutableSet(ctx, a.havefsattrs && a.fsattrs.haveimmutable && a.fsattrs.immutable && is_immutable);
Copy link
Contributor

Choose a reason for hiding this comment

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

It's already in the attributes and we do pass those into gazillions functions already, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not passed everywhere. We also would need to pass the is_immutable variable each function.


if (lstat(changes_path, &oslb) == -1) /* Careful if the object is a link */
{
Expand Down Expand Up @@ -617,7 +617,7 @@ static PromiseResult VerifyFilePromise(EvalContext *ctx, char *path, const Promi
Log(LOG_LEVEL_VERBOSE, "Replacing '%s' with content '%s'",
path, a.content);

PromiseResult render_result = WriteContentFromString(ctx, path, &a, pp, override_immutable);
PromiseResult render_result = WriteContentFromString(ctx, path, &a, pp);
result = PromiseResultUpdate(result, render_result);

goto exit;
Expand Down Expand Up @@ -711,6 +711,9 @@ static PromiseResult VerifyFilePromise(EvalContext *ctx, char *path, const Promi
}

exit:
/* Reset this to false before next file promise */
EvalContextOverrideImmutableSet(ctx, false);

free(chrooted_path);
if (AttrHasNoAction(&a))
{
Expand Down Expand Up @@ -766,7 +769,7 @@ static PromiseResult VerifyFilePromise(EvalContext *ctx, char *path, const Promi
/*****************************************************************************/

static PromiseResult WriteContentFromString(EvalContext *ctx, const char *path, const Attributes *attr,
const Promise *pp, bool override_immutable)
const Promise *pp)
{
assert(path != NULL);
assert(attr != NULL);
Expand Down Expand Up @@ -794,6 +797,7 @@ static PromiseResult WriteContentFromString(EvalContext *ctx, const char *path,

if (!HashesMatch(existing_content_digest, promised_content_digest, CF_DEFAULT_DIGEST))
{
bool override_immutable = EvalContextOverrideImmutableGet(ctx);
if (!MakingChanges(ctx, pp, attr, &result,
"update file '%s' with content '%s'",
path, attr->content))
Expand Down
13 changes: 13 additions & 0 deletions libpromises/eval_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,21 @@ struct EvalContext_
RemoteVarPromisesMap *remote_var_promises;

bool dump_reports;
bool override_immutable;
};

void EvalContextOverrideImmutableSet(EvalContext *ctx, bool should_override)
{
assert(ctx != NULL);
ctx->override_immutable = should_override;
}

bool EvalContextOverrideImmutableGet(EvalContext *ctx)
{
assert(ctx != NULL);
return ctx->override_immutable;
}

void EvalContextSetConfig(EvalContext *ctx, const GenericAgentConfig *config)
{
assert(ctx != NULL);
Expand Down
3 changes: 3 additions & 0 deletions libpromises/eval_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ void EvalContextHeapPersistentSave(EvalContext *ctx, const char *name, unsigned
void EvalContextHeapPersistentRemove(const char *context);
void EvalContextHeapPersistentLoadAll(EvalContext *ctx);

void EvalContextOverrideImmutableSet(EvalContext *ctx, bool should_override);
bool EvalContextOverrideImmutableGet(EvalContext *ctx);

/**
* Sets negated classes (persistent classes that should not be defined).
*
Expand Down