-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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
Add missing system calls for ADC driver subsystem #15001
Conversation
The source data is never modified. Signed-off-by: Andrew Boie <[email protected]>
The original value of 256 was selected more or less randomly and special cases keep proliferating. Until we have a formal method of proving maximum syscall stack depth, set to 1024. Signed-off-by: Andrew Boie <[email protected]>
Setting callbacks is forbidden from user mode. Some heavier code changes will be needed to support adc_read_async(), this patch just exposes the config and read functions for now. Test case updated to run partially in user mode. Signed-off-by: Andrew Boie <[email protected]>
Codecov Report
@@ Coverage Diff @@
## master #15001 +/- ##
=======================================
Coverage 52.92% 52.92%
=======================================
Files 309 309
Lines 45268 45268
Branches 10451 10451
=======================================
Hits 23956 23956
Misses 16544 16544
Partials 4768 4768 Continue to review full report at Codecov.
|
} | ||
|
||
if (dst->options) { | ||
if (z_user_from_copy(options, dst->options, |
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.
shouldn't copy from src->options
?
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.
at this point in the code, src and dst have the same contents since we just previously copied src (a pointer into user memory) into dst (a pointer on the supervisor mode call stack)
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.
this is not making sense to me though. Why do you need this check and copy then ? dst is an uninitialised variable:
Z_SYSCALL_HANDLER(adc_read, dev, user_sequence)
{
struct adc_sequence sequence;
struct adc_sequence_options options;
Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, read));
Z_OOPS(Z_SYSCALL_VERIFY_MSG(copy_sequence(&sequence, &options,
(struct adc_sequence *)user_sequence),
"invalid ADC sequence"));
if (sequence.options != NULL) {
Z_OOPS(Z_SYSCALL_VERIFY_MSG(sequence.options->callback == NULL,
"ADC sequence callbacks forbidden from user mode"));
}
return z_impl_adc_read((struct device *)dev, &sequence);
}
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.
you need to copy user_sequence (lives somehere in user memory) into kernel memory (sequence) in order to prevent TOCTOU issues. notice I am not passing user_sequence to the syscall implementation.
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.
yeah, but this code is not copying user sequence, it is copying sequence
that was allocate in this function stack and was not initialized. Well, it seems that I'm not understanding it :/
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.
you're not reading the code right, you have it backwards. user_sequence=src sequence=dst
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.
that is the problem, in copy_sequence
you are not using user_sequence=src
but sequece=dst
static bool copy_sequence(struct adc_sequence *dst,
struct adc_sequence_options *options,
struct adc_sequence *src)
{
...
if (dst->options) { /* dst == sequence that is no uninitialised */
if (z_user_from_copy(options, dst->options,
sizeof(struct adc_sequence_options)) != 0) {
printk("couldn't copy adc_options struct\n");
return false;
}
dst->options = options;
}
...
}
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.
Please post the whole function.
You will see that immediately before the check to dst->options, all of src got copied into dst. It is initialized.
dst->options points to a different memory buffer provided by the user, we copy it and then update dst->options.
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.
I missed that first copy, damn it. My bad, sorry for all noise
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.
Looks ok, only one comment to check.
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.
aside from flavio's comment, this looks good.
default 512 if COVERAGE_GCOV | ||
default 384 if ARC | ||
default 256 | ||
default 1024 |
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.
I agree with the rationale, here, but, I see that the priv stack starts getting too big
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.
not sure what you mean by too big
The actual minimum value for this, that satisfies maximum depth for all kernel/driver syscalls is unknown at this time.
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.
Looks fine to me (only did a high-level pass)
I apologize I haven't managed to add this comment before this PR got merged. |
Tested on frdm_k64f and sam_e70_xplained
Partial fix for #14084