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

Fix keyfile parsing of wireguard config when the prefix of allowed IPs is omited #366

Merged
merged 2 commits into from Jun 9, 2023

Conversation

daniloegea
Copy link
Collaborator

Description

Network Manager allows entering IPs without prefixes. Although WG docs says the format a.b.c.d/prefix should be used, it will accept only the IP address and default the prefix to /32. This change will append a /32 to the allowed IPs that don't have a prefix found in the keyfile.

Checklist

  • Runs make check successfully.
  • Retains 100% code coverage (make check-coverage).
  • New/changed keys in YAML format are documented.
  • (Optional) Adds example YAML for new feature.
  • (Optional) Closes an open bug in Launchpad.

@schopin-pro schopin-pro self-requested a review June 7, 2023 15:33
Copy link
Contributor

@schopin-pro schopin-pro left a comment

Choose a reason for hiding this comment

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

Nice work! A couple of nitpicks, but definitely merge-able immediately if need be.

@@ -511,7 +511,18 @@ parse_tunnels(GKeyFile* kf, NetplanNetDefinition* nd)
for (int i = 0; allowed_ips_split[i] != NULL; i++) {
gchar* ip = allowed_ips_split[i];
if (g_strcmp0(ip, "")) {
gchar* address = g_strdup(ip);
gchar* address = NULL;
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick (not-blocking): IMHO it's actually better to leave it uninitialized here.

In this case, the NULL value is an invalid value for address, as we're always assuming it be a valid string. Now, we know that, but the compiler doesn't, and so it won't necessarily help us when we're modifying the code later on and use it before its actual "semantic" initialization. Whereas just declaring it means the compiler will loudly complain, because it's pretty good at tracking those.

Yes it's a hypothetical, and the entire thing is highly subjective, I can easily imagine slyon disagreeing with me on that, hence my marking this as a nitpick. Feel free to disregard and mark this as resolved if you're not convinced ;)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I see your point and I think it's valid. But then, we probably shouldn't initialized anything with default values that are not considered valid in the context...

In any case, in this specific context, not initializing address apparently doesn't bother the compiler. Because we pass it to g_array_append_val which is a macro that will call g_array_append_vals passing a pointer to address (g_array_append_vals (a, &(v), 1)). I guess the compiler assumes that as we are passing a pointer to a variable, it will be initialized inside the function we called or something like that.

Copy link
Contributor

Choose a reason for hiding this comment

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

Way more simple than that: the compiler sees that no matter which codepath you take, address is written before it is read :). From its PoV there's no way g_array_append_vals would initialize address, as it can only mutate whatever it points to, not the pointer itself (which is what is uninitialized).

However, you're right in saying that gcc will not issue an uninitialized warning if you pass a pointer to your uninitialized variable to a function, unless it can conclusively prove it will read it before writing.

Take this sample:

#include <stdio.h>
void f(int* out);

int main()
{
    int i;
    f(&i);
    printf("%d", i);
    return 0;
}

void f(int* out)
{
    printf("%d", *out);
}

At default optimization level, it won't complain, even if you enable all warnings (-Wall -Wextra). However, if you enable -O3 (and keep -Wall), it'll loudly tell you about the uninitialized access, most likely because there's an inlining pass before the analysis for this warning is done.

Yes, my school of thought is that we should never have variables with semantically invalid values, unless there's a good reason (make the compiler shut up is a good reason ;-) )

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, leaving it to the compiler to do different things depending on what level of optimization you are using can lead to amazing surprises... Like this problem I had some time ago when my system failed to boot after an upgrade :)

https://cgit.freebsd.org/src/commit/stand/efi/loader/bootinfo.c?id=0d6600b579be769b85f049ef421023316f21b5c3

Not trying to compare both situations here but I think that this kind of problem should probably be caught by tests (and static analysis)...

tests/parser/base.py Show resolved Hide resolved
The parameter "regenerate" enable the caller to check or not if the
regenerated keyfile matches the input.

This will be used by tests that parse keyfiles with implicit
configuration. In this cases, the regenerated file will include this
configuration and will not match the input. For example, the Wireguard
property allowed-ips accept IPs without a prefix, but the prefix /32 is
implicitly used as it is required by Wireguard.
Network Manager doesn't fail if an IP in the allowed-ips list doesn't
have a prefix. In this case, WG will default to /32.

As the WG's documentation says the prefix must be used, Netplan will
fail the validation step if it's not present. To be able to parse a
keyfile and generate a YAML that will not fail validation, let's append
a /32 automatically to the value if it doesn't have a prefix defined by
the user.
@schopin-pro
Copy link
Contributor

schopin-pro commented Jun 9, 2023 via email

@schopin-pro schopin-pro merged commit b75c6fa into canonical:main Jun 9, 2023
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants