diff options
author | Aleksa Sarai <cyphar@cyphar.com> | 2024-10-10 07:40:34 +1100 |
---|---|---|
committer | Christian Brauner <brauner@kernel.org> | 2024-10-21 16:51:30 +0200 |
commit | 424a55a4a9087887fcfcee561648df497701a4a2 (patch) | |
tree | cf1a662809d0418965836b87335ffddbef43067e /drivers/fpga/microchip-spi.c | |
parent | 8e929cb546ee42c9a61d24fae60605e9e3192354 (diff) | |
download | linux-424a55a4a9087887fcfcee561648df497701a4a2.tar.gz linux-424a55a4a9087887fcfcee561648df497701a4a2.tar.bz2 linux-424a55a4a9087887fcfcee561648df497701a4a2.zip |
uaccess: add copy_struct_to_user helper
This is based on copy_struct_from_user(), but there is one additional
case to consider when creating a syscall that returns an
extensible-struct to userspace -- how should data in the struct that
cannot fit into the userspace struct be handled (ksize > usize)?
There are three possibilies:
1. The interface is like sched_getattr(2), where new information will
be silently not provided to userspace. This is probably what most
interfaces will want to do, as it provides the most possible
backwards-compatibility.
2. The interface is like lsm_list_modules(2), where you want to return
an error like -EMSGSIZE if not providing information could result in
the userspace program making a serious mistake (such as one that
could lead to a security problem) or if you want to provide some
flag to userspace so they know that they are missing some
information.
3. The interface is like statx(2), where there some kind of a request
mask that indicates what data userspace would like. One could
imagine that statx2(2) (using extensible structs) would want to
return -EMSGSIZE if the user explicitly requested a field that their
structure is too small to fit, but not return an error if the field
was not explicitly requested. This is kind of a mix between (1) and
(2) based on the requested mask.
The copy_struct_to_user() helper includes a an extra argument that is
used to return a boolean flag indicating whether there was a non-zero
byte in the trailing bytes that were not copied to userspace. This can
be used in the following ways to handle all three cases, respectively:
1. Just pass NULL, as you don't care about this case.
2. Return an error (say -EMSGSIZE) if the argument was set to true by
copy_struct_to_user().
3. If the argument was set to true by copy_struct_to_user(), check if
there is a flag that implies a field larger than usize.
This is the only case where callers of copy_struct_to_user() should
check usize themselves. This will probably require scanning an array
that specifies what flags were added for each version of the flags
struct and returning an error if the request mask matches any of the
flags that were added in versions of the struct that are larger than
usize.
At the moment we don't have any users of (3), so this patch doesn't
include any helpers to make the necessary scanning easier, but it should
be fairly easy to add some if necessary.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
Link: https://lore.kernel.org/r/20241010-extensible-structs-check_fields-v3-1-d2833dfe6edd@cyphar.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'drivers/fpga/microchip-spi.c')
0 files changed, 0 insertions, 0 deletions