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

c/snap-confine, i/udev, i/ifacetest: update snap-confine and snap-device-helper to understand component hook security tags #13775

Merged

Conversation

andrewphelpsj
Copy link
Member

@andrewphelpsj andrewphelpsj commented Apr 1, 2024

This PR teaches snap-confine and snap-device-helper how to parse security tags that represent component hooks.

An example of a security tag from a component hook would be: snap.name+comp.hook.install
And one with an instance key: snap.name_instance+comp.hook.install

Something important to note is how these are encoded as udev tags. Currently, when converting a security tag to a udev tag, we replace all . characters in the tag with _ characters because systemd limits udev tags to having only alphanumeric characters, with the addition of the characters - and _. Since security tags can now contain +
characters, those will be encoded as two consecutive _ characters.

For example:

"snap.name+comp.hook.install" -> "snap_name__comp_hook_install"
"snap.name_instance+comp.hook.install" -> "snap_name_instance__comp_hook_install"

This allows the conversion to maintain its reversibility.

@github-actions github-actions bot added the Needs Documentation -auto- Label automatically added which indicates the change needs documentation label Apr 1, 2024
@bboozzoo
Copy link
Contributor

bboozzoo commented Apr 2, 2024

shellcheck appears to be unhappy:


In tests/main/component-hooks/comp-with-install-hook/meta/hooks/install line 5:
printf "GET /ip HTTP/1.0\r\n\r\n" | nc httpbin.org 80 2>&1 > "${SNAP_COMMON}/install-logs" 
                                                      ^--^ SC2069 (warning): To redirect stdout+stderr, 2>&1 must be last (or use '{ cmd > file; } 2>&1' to clarify).

@andrewphelpsj andrewphelpsj force-pushed the component-hooks-run branch 2 times, most recently from 5e4f87d to 236f2ea Compare April 2, 2024 19:59
@codecov-commenter
Copy link

codecov-commenter commented Apr 3, 2024

Codecov Report

Attention: Patch coverage is 5.26316% with 18 lines in your changes missing coverage. Please review.

Project coverage is 78.71%. Comparing base (c01787f) to head (a6de4f3).
Report is 27 commits behind head on master.

Files Patch % Lines
interfaces/ifacetest/app_set.go 0.00% 18 Missing ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #13775      +/-   ##
==========================================
- Coverage   78.72%   78.71%   -0.02%     
==========================================
  Files        1053     1053              
  Lines      137711   138127     +416     
==========================================
+ Hits       108419   108731     +312     
- Misses      22494    22580      +86     
- Partials     6798     6816      +18     
Flag Coverage Δ
unittests 78.71% <5.26%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@andrewphelpsj andrewphelpsj force-pushed the component-hooks-run branch 3 times, most recently from c43b233 to 429cad9 Compare April 8, 2024 17:50
@andrewphelpsj andrewphelpsj force-pushed the component-hooks-run branch 4 times, most recently from 035b839 to c5d6971 Compare April 17, 2024 15:22
@andrewphelpsj andrewphelpsj force-pushed the component-hooks-run branch 3 times, most recently from eb91528 to c9a9f92 Compare May 7, 2024 14:42
@andrewphelpsj andrewphelpsj force-pushed the component-hooks-run branch 2 times, most recently from 73fa729 to 6cd4807 Compare May 15, 2024 07:44
@andrewphelpsj andrewphelpsj force-pushed the component-hooks-run branch 3 times, most recently from c3f7fdf to 1582077 Compare May 23, 2024 16:26
@andrewphelpsj andrewphelpsj force-pushed the component-hooks-run branch 2 times, most recently from a7b0050 to cb379d3 Compare June 11, 2024 18:15
@github-actions github-actions bot removed the Needs Documentation -auto- Label automatically added which indicates the change needs documentation label Jun 11, 2024
@andrewphelpsj andrewphelpsj force-pushed the component-hooks-run branch 4 times, most recently from bcb8dbc to 686b2f6 Compare June 20, 2024 13:10
@andrewphelpsj
Copy link
Member Author

It looks like the inclusive naming check is picking up some of the snap-confine files that were changed. I think that we probably don't want to include a bunch of renames in this PR, but we don't have a way to skip that check right now. I could add a tag (and a check in the action for that tag) that would allow us to skip it if we want.

Copy link
Member

@alfonsosanchezbeato alfonsosanchezbeato left a comment

Choose a reason for hiding this comment

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

Looks good, some comments but mainly nitpicks.

cmd/libsnap-confine-private/snap.h Outdated Show resolved Hide resolved
cmd/libsnap-confine-private/snap.c Outdated Show resolved Hide resolved
cmd/libsnap-confine-private/snap.c Show resolved Hide resolved
cmd/libsnap-confine-private/snap.c Show resolved Hide resolved
Copy link
Member

@alfonsosanchezbeato alfonsosanchezbeato left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

cmd/libsnap-confine-private/snap.c Show resolved Hide resolved
@ernestl ernestl requested a review from jslarraz July 11, 2024 13:40
char *prefix, size_t prefix_size,
char *suffix, size_t suffix_size)
{
if (string == NULL) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe those are too evident, but we may still want to add a couple of simple test cases for (string == NULL) and (prefix == NULL && suffix == NULL)

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks! Done in fc05b1b.

Copy link
Contributor

@jslarraz jslarraz left a comment

Choose a reason for hiding this comment

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

LGTM, just one minor comment about some extra tests, but feel free to ignore it if you think they do not add much value.

I think it will be worth giving @alexmurray a chance to take a look at it before merging just to be sure I'm not overlooking anything

Copy link
Contributor

@alexmurray alexmurray left a comment

Choose a reason for hiding this comment

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

LGTM!

@alexmurray alexmurray removed Security-High Needs security review Can only be merged once security gave a :+1: labels Jul 18, 2024
Copy link
Contributor

@zyga zyga left a comment

Choose a reason for hiding this comment

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

Please check my comment on reverse_component_separator_encoding. I left some nitpicks in othe places.

}
if (n > SNAP_NAME_LEN) {
err = sc_error_init(SC_SNAP_DOMAIN, err_code,
"%s must be shorter than 40 characters",
Copy link
Contributor

Choose a reason for hiding this comment

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

You can use some preprocessor magic to inject SNAP_NAME_LEN as a value there, at compile time, with #SNAP_NAME_LEN. See https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html

Alternatively just %d and pass the limit as an argument.

*
* For example:
* snap+component => "snap" & "component"
*
Copy link
Contributor

Choose a reason for hiding this comment

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

Please clarify that snap name and component name are copied into the given buffers.

*
* The size of prefix must be large enough to hold the prefix part of the
* string, and the size of suffix must be large enough to hold the suffix part
* of the string.
Copy link
Contributor

Choose a reason for hiding this comment

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

I was thinking about this and I kind of think that it's "probably" better to just use strdup+strtok instead.

No need to fuss around with buffers and handle them by hand. One allocation for all the needs for handling typical tag names. Each token can be replaced with \0 for a ready-to-use string.

cmd/libsnap-confine-private/string-utils.c Show resolved Hide resolved
// expression currently contains 9 capture groups, but we only care about these 3,
// which unfortunately are not within the first 3 submatches, but rather group 1,
// 2, and 7, so for completeness capture all the groups.
enum { num_matches = 9 };
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick, this should probably be just const int, enum feels not much like C.

Copy link
Member Author

Choose a reason for hiding this comment

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

Using a const int would result in this being a variable-length array, if you compile with -Wvla, you'll see a warning.

Example:

phelps@arch ~/tmp> cat main.c
int main() {
    const int size = 10;
    int array[size];
    return 0;
}
phelps@arch ~/tmp> gcc -Wvla -o main ./main.c
./main.c: In function ‘main’:
./main.c:3:5: warning: ISO C90 forbids variable length array ‘array’ [-Wvla]
    3 |     int array[size];
      |     ^~~
phelps@arch ~/tmp> cat other.c
int main() {
    enum { size = 10 };
    int array[size];
    return 0;
}
phelps@arch ~/tmp> gcc -Wvla -o main ./other.c

Alfonso suggested the enum over a #define, but I don't really have a strong opinion.

Copy link
Contributor

Choose a reason for hiding this comment

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

TIL

{
/* Don't even check overly long tags. */
if (strlen(security_tag) > SNAP_SECURITY_TAG_MAX_LEN) {
return false;
}
const char *whitelist_re =
"^snap\\.([a-z0-9](-?[a-z0-9])*(_[a-z0-9]{1,10})?)\\.([a-zA-Z0-9](-?[a-zA-Z0-9])*|hook\\.[a-z](-?[a-z0-9])*)$";
"^snap\\.([a-z0-9](-?[a-z0-9])*(_[a-z0-9]{1,10})?)(\\.[a-zA-Z0-9](-?[a-zA-Z0-9])*|(\\+([a-z0-9](-?[a-z0-9])*))?\\.hook\\.[a-z](-?[a-z0-9])*)$";
Copy link
Contributor

Choose a reason for hiding this comment

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

We should clarify exactly what is the allowed pattern, as now there's a disagreement between snapd and snapcraft. Can you circle back to the spec and make sure it says what is allowed (digits).

cmd/libsnap-confine-private/snap.c Outdated Show resolved Hide resolved
cmd/snap-device-helper/snap-device-helper.c Show resolved Hide resolved
Copy link
Contributor

@zyga zyga left a comment

Choose a reason for hiding this comment

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

LGTM

I'll follow up on some string operations but this is okay.

@alfonsosanchezbeato alfonsosanchezbeato merged commit 98b4e32 into canonical:master Jul 22, 2024
45 of 53 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
Development

Successfully merging this pull request may close these issues.

8 participants