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

Fixing kernel commandline parameter validation #148

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ita93
Copy link
Contributor

@ita93 ita93 commented May 14, 2023

According to linux kernel document, the value of command line parameter can contains spaces (with double quotes) or equals.

Summary of the PR

Please summarize here why the changes in this PR are needed.

Requirements

Before submitting your PR, please make sure you addressed the following
requirements:

  • All commits in this PR are signed (with git commit -s), and the commit
    message has max 60 characters for the summary and max 75 characters for each
    description line.
  • All added/changed functionality has a corresponding unit/integration
    test.
  • All added/changed public-facing functionality has entries in the "Upcoming
    Release" section of CHANGELOG.md (if no such section exists, please create one).
  • Any newly added unsafe code is properly documented.

@ita93 ita93 requested review from alxiord, sameo and rbradford as code owners May 14, 2023 17:02
@roypat
Copy link
Collaborator

roypat commented May 15, 2023

Heyo, thanks for the contribution. Just a few questions, mainly for my own understanding since I couldn't find the answer in the linux docs >.>

What would happen if the value passed looks like "hello" world", e.g. with a spurious quote in the middle? Do we need to also error out in that case? Also, are single quotes allowed for the purpose of preserving spaces?

From a usability perspective, would it make sense to instead detect if the value the user passes us contains spaces, and add the quotes for them (with maybe some escaping logic for quotes already in the string, although I'm not sure the linux command line allows for escaping them).

@ita93
Copy link
Contributor Author

ita93 commented May 16, 2023

Heyo, thanks for the contribution. Just a few questions, mainly for my own understanding since I couldn't find the answer in the linux docs >.>

What would happen if the value passed looks like "hello" world", e.g. with a spurious quote in the middle? Do we need to also error out in that case? Also, are single quotes allowed for the purpose of preserving spaces?

Only double quotes are allowed. You can't escape " in the value, your example string is invalid.

From a usability perspective, would it make sense to instead detect if the value the user passes us contains spaces, and add the quotes for them (with maybe some escaping logic for quotes already in the string, although I'm not sure the linux command line allows for escaping them).

Maybe a good idea.

@roypat
Copy link
Collaborator

roypat commented May 17, 2023

Heyo, thanks for the contribution. Just a few questions, mainly for my own understanding since I couldn't find the answer in the linux docs >.>
What would happen if the value passed looks like "hello" world", e.g. with a spurious quote in the middle? Do we need to also error out in that case? Also, are single quotes allowed for the purpose of preserving spaces?

Only double quotes are allowed. You can't escape " in the value, your example string is invalid.

I see, thanks for explaining! In that case, we should also validate that no quotes are contained in the middle of values, e.g. if value[1..value.len() - 1].contains('"') {...}

From a usability perspective, would it make sense to instead detect if the value the user passes us contains spaces, and add the quotes for them (with maybe some escaping logic for quotes already in the string, although I'm not sure the linux command line allows for escaping them).

Maybe a good idea.

If we don't have to deal with any complex escaping logic, I think we should do this. Unless I'm missing something, it'd just be

  1. reject strings that contain quotes anywhere but the beginning or end
  2. reject strings with unbalanced quotes
  3. check if string contains spaces.
    3.1. If it does, and it is unquoted, add quotes, otherwise leaves as is

What do others think?

@andreitraistaru
Copy link
Collaborator

Heyo, thanks for the contribution. Just a few questions, mainly for my own understanding since I couldn't find the answer in the linux docs >.>
What would happen if the value passed looks like "hello" world", e.g. with a spurious quote in the middle? Do we need to also error out in that case? Also, are single quotes allowed for the purpose of preserving spaces?

Only double quotes are allowed. You can't escape " in the value, your example string is invalid.

I see, thanks for explaining! In that case, we should also validate that no quotes are contained in the middle of values, e.g. if value[1..value.len() - 1].contains('"') {...}

From a usability perspective, would it make sense to instead detect if the value the user passes us contains spaces, and add the quotes for them (with maybe some escaping logic for quotes already in the string, although I'm not sure the linux command line allows for escaping them).

Maybe a good idea.

If we don't have to deal with any complex escaping logic, I think we should do this. Unless I'm missing something, it'd just be

1. reject strings that contain quotes anywhere but the beginning or end

2. reject strings with unbalanced quotes

3. check if string contains spaces.
   3.1. If it does, and it is unquoted, add quotes, otherwise leaves as is

What do others think?

Thanks @ita93 and @roypat for getting involved into this!

I do agree with the first 2 points (for point 2, we even have a function here that could help us with the implementation).
For point 3, I would agree to do the checking but I'm not quite sure if it would be the right approach to alter the value of the parameter in any way. I mean, if we get a wrong value for a kernel param, I do not consider the Cmdline's responsibility to correct it and store in the Cmdline as it should. For point 3, I would still reject the insertion and that's it. What do you think?

Also, what happens if we receive a parameter's value like "foo1 bar1" "foo2 bar3"? Should we also reject such a string (the case when we get nested double quotes that are balanced)? Not sure from the linux docs, but to me it looks like an invalid value as well...

@ita93
Copy link
Contributor Author

ita93 commented May 26, 2023

Thanks @ita93 and @roypat for getting involved into this!

I do agree with the first 2 points (for point 2, we even have a function here that could help us with the implementation). For point 3, I would agree to do the checking but I'm not quite sure if it would be the right approach to alter the value of the parameter in any way. I mean, if we get a wrong value for a kernel param, I do not consider the Cmdline's responsibility to correct it and store in the Cmdline as it should. For point 3, I would still reject the insertion and that's it. What do you think?

I think that we should follow the purpose of the original function - validating the input, that is all.

Also, what happens if we receive a parameter's value like "foo1 bar1" "foo2 bar3"? Should we also reject such a string (the case when we get nested double quotes that are balanced)? Not sure from the linux docs, but to me it looks like an invalid value as well...

As my understanding, this input may still generate a valid kernel commandline, however, the "foo2 bar3" won't belong to the current key. IMO, we should not accept this kind of input as a value of key=value pair.
We should enforce the value to have two double quotes, one at the start and one at the end of the string if there are any spaces, that is what the kernel expects

@ita93 ita93 force-pushed the fix/value_validation branch from e2610af to 9db1c32 Compare June 4, 2023 03:06
@ita93 ita93 force-pushed the fix/value_validation branch 2 times, most recently from c085ab6 to db4d7a4 Compare June 4, 2023 05:26
@andreeaflorescu
Copy link
Member

There is no activity on this PR for some time, @ita93 are you still interested in getting this merged? If not, can you please close the PR?

@ita93
Copy link
Contributor Author

ita93 commented Jan 24, 2024

There is no activity on this PR for some time, @ita93 are you still interested in getting this merged? If not, can you please close the PR?

Sorry for the late reply, I'm still interested in this one. I will try posting it in Slack to ask for a reviewing

@ita93 ita93 requested a review from ShadowCurse as a code owner November 6, 2024 16:08
@roypat
Copy link
Collaborator

roypat commented Nov 14, 2024

(replying now since I saw you rebased this recently, sorry for dropping the ball last year!)

Going over the old discussion from last year, I think the only thing left here is to handle the "hello "world" and "foo1 bar1" "foo2 bar3" examples above, and also reject them, right? Also, this should probably get a Changelog entry

@rbradford
Copy link
Collaborator

You should also rebase your commits to drop the merges.

@roypat
Copy link
Collaborator

roypat commented Nov 14, 2024

You should also rebase your commits to drop the merges.

I think they're all merge commits created by the github UI (they're all empty), so they'll be dropped if we merge by rebasing

@ita93 ita93 force-pushed the fix/value_validation branch from 1afbee4 to cd4ee10 Compare November 21, 2024 13:04
@ita93
Copy link
Contributor Author

ita93 commented Nov 22, 2024

Going over the old discussion from last year, I think the only thing left here is to handle the "hello "world" and "foo1 bar1" "foo2 bar3" examples above, and also reject them, right? Also, this should probably get a Changelog entry

Hi, I've added a changelog entry in the newest commit.
In summary, the rules will be:

  • reject strings that contain quotes anywhere but the beginning or end
  • reject strings that contain spaces but are not quoted.

CHANGELOG.md Show resolved Hide resolved
Copy link
Contributor

@TimePrinciple TimePrinciple left a comment

Choose a reason for hiding this comment

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

Some thoughts :)

Comment on lines 88 to 101
fn is_quoted(s: &str) -> bool {
if let Some(first_char) = s.chars().next() {
if let Some(last_char) = s.chars().last() {
return first_char == '"' && last_char == '"';
}
}
false
}
Copy link
Contributor

Choose a reason for hiding this comment

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

IMHO this implementation would accept input with only a '"' character, should we check if next() and last() actually pointing different location 🤔, or else we check the length of s which should be at least 2 characters long

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi, I've updated this function as per your suggestion. Can you help me to review it again, please?

@ita93 ita93 force-pushed the fix/value_validation branch 3 times, most recently from 8f71b30 to ac22037 Compare November 26, 2024 06:47
roypat
roypat previously approved these changes Nov 26, 2024
Copy link
Collaborator

@roypat roypat left a comment

Choose a reason for hiding this comment

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

Thanks! Could you squash the last commit such that we don't have commits that modify code introduces in earlier commits though?

@ita93 ita93 force-pushed the fix/value_validation branch 2 times, most recently from f01fb8a to 772ee95 Compare November 27, 2024 09:29
According to linux kernel document, the value of command line parameter
can contains spaces (with double quotes) or equals.
This change will also reject the parameter value that contains quotes in
the middle.

Signed-off-by: Nguyen Dinh Phi <[email protected]>
@ita93 ita93 force-pushed the fix/value_validation branch from 772ee95 to 2d5e73b Compare November 27, 2024 09:32
Copy link
Collaborator

@rbradford rbradford left a comment

Choose a reason for hiding this comment

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

Rubber stamping after @roypat's review.

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.

6 participants