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

Template addition #1

Open
wants to merge 2 commits into
base: sailfish_patch_master
Choose a base branch
from

Conversation

LaakkonenJussi
Copy link
Owner

No description provided.

Copy link

@spiiroin spiiroin left a comment

Choose a reason for hiding this comment

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

Random observations about WIP code

int key_len;

if (!tmpl_list) {
*err = -ENOENT;

Choose a reason for hiding this comment

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

Is this error reason detail really necessary? Existing code does not use this kind of pattern and even here in the new code that value seems to be ignored except for diagnostic logging.

Copy link
Owner Author

Choose a reason for hiding this comment

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

I think this is a remnant of code decay here. I had at first an approach to be more lib-like pass the list as parameter but I decided to hide all that functionality.

if (!str)
new_string = process_key_value(new_string, token, err);
else
new_string = append_to_string(new_string, token);

Choose a reason for hiding this comment

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

I'm confused about this "starting from second token" thing. What is that all about? [Checking that option/command itself is not a macro has already been checked earlier].

... also: '$' is removed from the 1st token when it looks like the intent might have been to pass it as-is and unmodified?

Copy link
Owner Author

Choose a reason for hiding this comment

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

Will add check that if there is a lone $ it means an error. If that is any of the internal macros it will be replaced in the string, yeah, not the best way but since I resorted using strtok_r() I guess that is unavoidable unless that is to be done by hand, which may induce more errors..

See also https://github.com/LaakkonenJussi/firejail/pull/1/files#r630917495

Copy link
Owner Author

Choose a reason for hiding this comment

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

I'd suppose this is resolved but @spiiroin do you still have something that needs to be clarified or do you think this needs fixing? I added comments to code and to commit msg about this as well.


if (ptr == NULL) {
fprintf(stderr, "Ignoring line \"%s\", contains "
"invalid template keys (err %d)\n",

Choose a reason for hiding this comment

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

Noting that error code value is not really used by the code itself: as places where those errors are triggered also contain error logging with details -> what are the chances that anybody reading the logs is also interested to know that all that human readable stuff is also known as "(err -127)".

Copy link
Owner Author

Choose a reason for hiding this comment

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

Maybe I should in general simplify that error use. Existing code does not use much different error codes but I guess here it could be good to report something that describes the actual cause. I did remove most of that to be as internal in template.c for reporting errors, might be enough?

continue;
}

/* Only the first iteration is the template */

Choose a reason for hiding this comment

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

I think I lost the plot completely.

Copy link
Owner Author

@LaakkonenJussi LaakkonenJussi May 12, 2021

Choose a reason for hiding this comment

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

Well since this tokenizes first by $ there can be cases of: include /path/to/${template1}/something/${template2}/somewhere ->

1: tokens are a:/path/to, b:{template1}something/ and c:{template2}/somewhere
2: pass only a and b to this functon
3: Only the first item, in b:template1 and c:template2 are considered proper keys, the remains is just added to string.

I have an external test app for checking these cases. So in general when parsing the whole string in no circumstances the string should start in profile/permission file with a template.

Choose a reason for hiding this comment

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

Ok, thanks for the clarification (this is "second level slicer" and you probably meant "2: pass only b and c to this function"?).

If needed, how does one have literal '$' / '{' chars in the final product? I have a feeling that eventually this kind of simple slicing loop will fail to handle something and becomes confusingly complex with special case handling or needs to be replaced with a bit more holistic decode+tokenize logic that allows escaping etc.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Yes, b and c in that 2. My bad.

I have the process_key_value() implemented in a way that if there is an internal macro it will have its ${INTERNAL_MACRO} format in the string. I'm eager to fix that macro.c to have simpler checker but lets see..

Copy link
Owner Author

Choose a reason for hiding this comment

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

And I'm not sure how complex this really needs to be. But anyways I haven't worked with Firejail for long so there may be something I've missed but from my point of view the lines in the profiles/permissions do seem to be quite simple.

@LaakkonenJussi LaakkonenJussi force-pushed the template_addition branch 11 times, most recently from 0180d17 to af73b1e Compare May 19, 2021 10:08
@LaakkonenJussi LaakkonenJussi force-pushed the template_addition branch 2 times, most recently from e8761e7 to 8aceebe Compare May 20, 2021 09:15
Do not read the profile files when processing arguments. Instead prepend
them to a list that is processed after the arguments are processed in
order to be able to replace all template keys in the profile file lines.
The list is reversed before processing to have the profile files read in
the given order. Each item in the list is free'd after it has been
processed.
@LaakkonenJussi LaakkonenJussi force-pushed the template_addition branch 3 times, most recently from 6f6fd8c to 1a2a3ff Compare May 26, 2021 09:49
Implement template addition to pass templates as key value pairs as cmd
line parameters to replace the keys in read profile file lines to allow
more customization and flexibility. This adds a new file called
template.c which contains all the functionality.

Motivation for this is to have the possibility to create profile files
where a specific key exists that can be customized per application that
is being run with firejail. For example, application name can be used in
a D-Bus name that is requested to be owned to avoid collision with other
applications requiring the same base name. This can be passed directly
then to firejail as a cmd line parameter when starting the application.

All templates are to be given via cmd line parameters in format:
 --template=KEY:VALUE

The keys and values are stored in a single linked list within template.c,
which is free'd when the keys in all read profile file (including
included profiles) lines have been replaced.

Each key can exist only once, existing hardcoded macros cannot be
overwritten. If any of these is violated firejail exits. A template key
cannot start with a digit and must contain alphanumeric chars only.

Each value must conform to following rules:
 - length is < 255 (D-Bus name length)
 - can contain alphabetical (a-zA-Z), integer (0-9) and '_-/.' chars but
   no '..'

In order to use the same DBUS_MAX_NAME_LENGTH it is moved from dbus.c to
firejail.h.

When processing the profile file lines the template keys are expected to
be written as other macros, ${TEMPLATE_KEY}. Template cannot be in the
beginning of the line. If the read line contains other internal macros
they are not replaced as they are processed later with more strict and
specific checks. It is known that using strtok_r() and doing the
tokenization in two steps, first by '$' and then by '{}' invalid
definitions such as ${{TEMPLATE_KEY2}} will pass the checks. The process
of replacing the keys can be described as follows to ease the
understanding of the code:

1. "whitelist ${HOME}/${key1}/path/to/${key2}.somewhere" tokens are:
    a: whitelist
    b: {HOME}/
    c: {key1}/path/to/
    d: {key2}.somewhere
2. Keys in the first token 'a' are ignored, it is the start of new str
3. Tokens 'b', 'c' and 'd' are passed to process_key_value
4. Each of the template keys are replaced with corresponding values, as
${HOME} is internal macro it is not replaced but added as is. Only the
first items in tokens, 'key1' and 'key2' are considered as proper keys to
have the values replaced, the remains are just added to the str.
5. Resulting string would be then:
   "whitelist ${HOME}/value1/path/to/value2.somewhere"

In order to avoid unnecessary duplication of each read profile line the
line is first checked to have at least one template key. If the template
key is not found firejail will exit with an error.

Man pages for firejail and firejail-profile are updated to include this
addition.
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.

2 participants