-
Notifications
You must be signed in to change notification settings - Fork 60
crypto: Add a function to check for label and subsystem validity #1133
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
crypto: Add a function to check for label and subsystem validity #1133
Conversation
Summary of ChangesHello @vojtechtrefny, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request integrates a new validation utility, Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a new function, bd_crypto_luks_check_label, to validate the length of LUKS labels and subsystems, which is a valuable addition. However, the implementation contains a correctness issue regarding the maximum allowed length. The check incorrectly permits a length of 48 characters, whereas the limit should be 47 to account for the null terminator in the 48-byte buffer. This error also impacts the accompanying tests, which do not verify the correct boundary condition. I have provided specific suggestions to address these issues in both the function implementation and the tests.
src/plugins/crypto.c
Outdated
| if (label && strlen (label) > 48) { | ||
| g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_INVALID_PARAMS, | ||
| "Label for LUKS must be at most 48 characters long"); | ||
| return FALSE; | ||
| } | ||
|
|
||
| if (subsystem && strlen (subsystem) > 48) { | ||
| g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_INVALID_PARAMS, | ||
| "Subsystem for LUKS must be at most 48 characters long"); | ||
| return FALSE; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The maximum length for a LUKS2 label or subsystem is 47 characters, as the on-disk format reserves a 48-byte buffer which must include the NULL terminator. The current implementation incorrectly allows for a length of 48 characters.
The check should be against a maximum length of 47. Please update the length check and the corresponding error message. For better maintainability, consider defining a constant for the maximum length (47) and using it in both the check and the error message.
For reference, see the cryptsetup merge request that introduced this limit: https://gitlab.com/cryptsetup/cryptsetup/-/merge_requests/841. The final implementation there uses >= 48 (which is equivalent to > 47) for the check.
if (label && strlen (label) > 47) {
g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_INVALID_PARAMS,
"Label for LUKS must be at most 47 characters long");
return FALSE;
}
if (subsystem && strlen (subsystem) > 47) {
g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_INVALID_PARAMS,
"Subsystem for LUKS must be at most 47 characters long");
return FALSE;
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch!
tests/crypto_test.py
Outdated
| with self.assertRaisesRegex(GLib.GError, "Label for LUKS must be at most 48 characters long"): | ||
| BlockDev.crypto_luks_check_label(label="a" * 49) | ||
| with self.assertRaisesRegex(GLib.GError, "Subsystem for LUKS must be at most 48 characters long"): | ||
| BlockDev.crypto_luks_check_label(subsystem="a" * 49) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test for invalid label/subsystem length should be updated to reflect the correct maximum length of 47 characters. The test should check the boundary condition, i.e., a string of length 48 should be invalid.
Also, the expected error message in assertRaisesRegex needs to be updated to mention '47 characters'.
| with self.assertRaisesRegex(GLib.GError, "Label for LUKS must be at most 48 characters long"): | |
| BlockDev.crypto_luks_check_label(label="a" * 49) | |
| with self.assertRaisesRegex(GLib.GError, "Subsystem for LUKS must be at most 48 characters long"): | |
| BlockDev.crypto_luks_check_label(subsystem="a" * 49) | |
| with self.assertRaisesRegex(GLib.GError, "Label for LUKS must be at most 47 characters long"): | |
| BlockDev.crypto_luks_check_label(label="a" * 48) | |
| with self.assertRaisesRegex(GLib.GError, "Subsystem for LUKS must be at most 47 characters long"): | |
| BlockDev.crypto_luks_check_label(subsystem="a" * 48) |
|
/gemini review |
cryptsetup recently started imposing some limits on label and subsystem lenght so we should add a function for the users to be able to check if their label and subsystem are valid. This is similar to existing FS plugin functions. See also: https://gitlab.com/cryptsetup/cryptsetup/-/merge_requests/841
bf090bf to
26d8ed0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a new function bd_crypto_luks_check_label to validate LUKS2 label and subsystem lengths. The implementation is a good addition, but there's a critical issue with the length validation logic that could lead to a buffer overflow in cryptsetup. The maximum allowed length is 47 characters, not 48. I've provided a suggestion to fix this. Additionally, the corresponding tests should be updated to check for this boundary condition. My review includes comments with detailed explanations and code suggestions for these improvements.
| gboolean bd_crypto_luks_check_label (const gchar *label, const gchar *subsystem, GError **error) { | ||
| if (label && strlen (label) > 47) { | ||
| g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_INVALID_PARAMS, | ||
| "Label for LUKS must be at most 47 characters long"); | ||
| return FALSE; | ||
| } | ||
|
|
||
| if (subsystem && strlen (subsystem) > 47) { | ||
| g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_INVALID_PARAMS, | ||
| "Subsystem for LUKS must be at most 47 characters long"); | ||
| return FALSE; | ||
| } | ||
|
|
||
| return TRUE; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The length checks for both label and subsystem are incorrect. According to the cryptsetup source, the on-disk format for these fields is a 48-byte character array, which includes the null terminator. This means the maximum string length is 47 characters.
The current checks (> 48) allow strings of 48 characters, which would lead to a buffer overflow when used by cryptsetup.
The checks should be changed to > 47, and the error messages should be updated to reflect the correct maximum length.
gboolean bd_crypto_luks_check_label (const gchar *label, const gchar *subsystem, GError **error) {
if (label && strlen (label) > 47) {
g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_INVALID_PARAMS,
"Label for LUKS must be at most 47 characters long");
return FALSE;
}
if (subsystem && strlen (subsystem) > 47) {
g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_INVALID_PARAMS,
"Subsystem for LUKS must be at most 47 characters long");
return FALSE;
}
return TRUE;
}| with self.assertRaisesRegex(GLib.GError, "Label for LUKS must be at most 47 characters long"): | ||
| BlockDev.crypto_luks_check_label(label="a" * 48) | ||
| with self.assertRaisesRegex(GLib.GError, "Subsystem for LUKS must be at most 47 characters long"): | ||
| BlockDev.crypto_luks_check_label(subsystem="a" * 48) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests for the new function are good, but they are missing a check for the boundary condition. A string of length 48 should be invalid.
Please add tests for strings of exactly 48 characters for both label and subsystem to ensure the boundary is handled correctly. These tests should expect a GLib.GError. I've also updated the existing tests to check for the corrected error message.
| with self.assertRaisesRegex(GLib.GError, "Label for LUKS must be at most 47 characters long"): | |
| BlockDev.crypto_luks_check_label(label="a" * 48) | |
| with self.assertRaisesRegex(GLib.GError, "Subsystem for LUKS must be at most 47 characters long"): | |
| BlockDev.crypto_luks_check_label(subsystem="a" * 48) | |
| with self.assertRaisesRegex(GLib.GError, "Label for LUKS must be at most 47 characters long"): | |
| BlockDev.crypto_luks_check_label(label="a" * 48) | |
| with self.assertRaisesRegex(GLib.GError, "Label for LUKS must be at most 47 characters long"): | |
| BlockDev.crypto_luks_check_label(label="a" * 49) | |
| with self.assertRaisesRegex(GLib.GError, "Subsystem for LUKS must be at most 47 characters long"): | |
| BlockDev.crypto_luks_check_label(subsystem="a" * 48) | |
| with self.assertRaisesRegex(GLib.GError, "Subsystem for LUKS must be at most 47 characters long"): | |
| BlockDev.crypto_luks_check_label(subsystem="a" * 49) |
26d8ed0 to
115597a
Compare
632959e
into
storaged-project:master
cryptsetup recently started imposing some limits on label and subsystem lenght so we should add a function for the users to be able to check if their label and subsystem are valid. This is similar to existing FS plugin functions.
See also: https://gitlab.com/cryptsetup/cryptsetup/-/merge_requests/841