Skip to content
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

net: Ensure a tmp with exec permissions for dhcp #1690

Merged
merged 4 commits into from Sep 1, 2022

Conversation

aciba90
Copy link
Contributor

@aciba90 aciba90 commented Aug 25, 2022

Proposed Commit Message

net: Ensure a tmp with exec permissions for dhcp

In the case cloudinit.temp_utils points to a fs mounted as noexec
and needs_exe=True, fallback to use
os.join.path(Distro.usr_lib_exec, "cloud-init/clouddir) that
will be mounted with exec perms.

LP: #1962343

Additional Context

https://bugs.launchpad.net/cloud-init/+bug/1962343
https://warthogs.atlassian.net/browse/SC-958

Test Steps

Execute tests/integration_tests/datasources/test_tmp_noexec.py

Checklist:

  • My code follows the process laid out in the documentation
  • I have updated or added any unit tests accordingly
  • I have updated or added any documentation accordingly

@aciba90 aciba90 marked this pull request as ready for review August 25, 2022 13:22
@holmanb holmanb self-assigned this Aug 26, 2022
cloudinit/distros/__init__.py Outdated Show resolved Hide resolved
@@ -41,7 +41,9 @@ class NoDHCPLeaseMissingDhclientError(NoDHCPLeaseError):
"""Raised when unable to find dhclient."""


def maybe_perform_dhcp_discovery(nic=None, dhcp_log_func=None):
def maybe_perform_dhcp_discovery(
nic=None, dhcp_log_func=None, alt_exe_dir=None
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps needs_exe=True to temp_utils.tmpdir() should just do the right thing and avoid requiring alt_exe_dir passed around?

Copy link
Member

Choose a reason for hiding this comment

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

I was wondering about that too (or some other way to reduce the number of repeated changes), however doing that would couple temp_utils to distro. Is maybe that why @aciba90 didn't do this originally? I don't know off the top of my head if such a change would cause circular import issues, but it might.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored to expose the target tmp_dir and let callers (datasources, modules) determine if the dir is mounted in a noexec point and give an exec dir via the distro in use.

@cjp256
Copy link
Contributor

cjp256 commented Aug 29, 2022

Thank you for fixing this!! :D

Copy link
Member

@holmanb holmanb left a comment

Choose a reason for hiding this comment

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

Thanks for this @aciba90!

I have one comment about a debug log that I think should be a warning, and a request/suggestion to check that the alt_exe_dir is itself executable. Once that and @cjp256's comments are addressed, I think this will be ready to merge.

cloudinit/distros/__init__.py Outdated Show resolved Hide resolved
cloudinit/temp_utils.py Outdated Show resolved Hide resolved
cloudinit/temp_utils.py Outdated Show resolved Hide resolved
cloudinit/net/ephemeral.py Show resolved Hide resolved
In the case cloudinit.temp_utils points to a fs mounted as noexec
and needs_exe=True, fallback to use
os.join.path(Distro.usr_lib_exec, "cloud-init/clouddir) that
will be mounted with exec perms.
It exposes the target tmp_dir and let callers (datasources,
modules) determine if the dir is mounted in a noexec point
and give a exec dir via the distro in use.
@aciba90
Copy link
Contributor Author

aciba90 commented Aug 30, 2022

Thanks, @cjp256 and @holmanb, for the constructive comments!

I have addressed your comments by exposing a function to let the callers of cloudinit.temp_utils know in advance what will be a tmp mount-point, to let them select the correct one.

This is ready to be reviewed after CI passes. Please, let me know if there are more concerns.

@aciba90 aciba90 requested review from cjp256 and holmanb and removed request for cjp256 August 30, 2022 11:53
Copy link
Member

@holmanb holmanb left a comment

Choose a reason for hiding this comment

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

I really like the integration test addition.

I assume fstab failing to mount on boot would cause the test to fail, but do you think we should add an assertion that ensures the test can't pass if not mounted noexec? If you think this is completely redundant, feel free to push back on this.

@aciba90
Copy link
Contributor Author

aciba90 commented Aug 31, 2022

I really like the integration test addition.

I assume fstab failing to mount on boot would cause the test to fail, but do you think we should add an assertion that ensures the test can't pass if not mounted noexec? If you think this is completely redundant, feel free to push back on this.

Thanks, @holmanb, for the review and suggestion. I think it is a great idea to assert test preconditions. I have done so and retested it.

@aciba90 aciba90 requested a review from holmanb August 31, 2022 09:17
args = [tuple()]
_args = list(args)
if len(_args) == 0 and "args" not in kwargs:
_args.append(tuple())
Copy link
Member

@holmanb holmanb Sep 1, 2022

Choose a reason for hiding this comment

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

If this branch is taken, then _args will be set to [()] and later on line 315 we will be concatenating a list and a tuple, which will cause a typerror.

_args[0] = [tmpf] + _args[0]

and a traceback like:

Traceback (most recent call last):
  File "/home/holmanb/cloud-init-a/tmp.py", line 24, in <module>
    subp_blob_in_tempfile(None, None)
  File "/home/holmanb/cloud-init-a/tmp.py", line 22, in subp_blob_in_tempfile
    _args[0] = [tmpf] + _args[0]
TypeError: can only concatenate list (not "tuple") to list

Copy link
Member

@holmanb holmanb left a comment

Choose a reason for hiding this comment

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

I just noticed one last nit. It's not something you caused, but since we're modifying this chunk of code I think we should fix it. Pyright picks up the error on main, but not on your branch. The problem still exists, however, it just gets hidden from type analyzers in the changes here. I suspect a fix should be as simple as s/tuple()/list()/g on line highlighted in the comment.

I'll merge once that issue is fixed (I'd merge now but I want a second opinion on my suggestion).

Copy link
Member

@holmanb holmanb left a comment

Choose a reason for hiding this comment

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

Actually it has only one call sight, and we can see that kwargs contains args, so we can simplify a bit. I'm going to merge this and we'll do a little cleanup PR for that shortly.

LGTM. Thanks!

@holmanb holmanb merged commit 919e22d into canonical:main Sep 1, 2022
@aciba90 aciba90 deleted the tmp_noexec branch September 2, 2022 09:23
@cjp256
Copy link
Contributor

cjp256 commented Sep 2, 2022

Thanks Alberto @aciba90!

@aciba90
Copy link
Contributor Author

aciba90 commented Sep 2, 2022

Thanks Alberto @aciba90!

Thank you, @cjp256, for the reviews and feedback!

@aciba90 aciba90 mentioned this pull request Sep 5, 2022
3 tasks
aciba90 added a commit to aciba90/cloud-init that referenced this pull request Sep 26, 2022
In the case cloudinit.temp_utils points to a fs mounted as noexec
and needs_exe=True, fallback to use
os.join.path(Distro.usr_lib_exec, "cloud-init/clouddir) that
will be mounted with exec perms.

LP: #1962343
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.

None yet

3 participants