lkml.org 
[lkml]   [2021]   [Dec]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH] media: omap3isp: Use struct_group() for memcpy() region
    On Mon, Dec 13, 2021 at 05:24:16PM -0600, Gustavo A. R. Silva wrote:
    > On Thu, Nov 18, 2021 at 10:43:52AM -0800, Kees Cook wrote:
    > > In preparation for FORTIFY_SOURCE performing compile-time and run-time
    > > field bounds checking for memcpy(), memmove(), and memset(), avoid
    > > intentionally writing across neighboring fields. Wrap the target region
    > > in struct_group(). This additionally fixes a theoretical misalignment
    > > of the copy (since the size of "buf" changes between 64-bit and 32-bit,
    > > but this is likely never built for 64-bit).
    > >
    > > FWIW, I think this code is totally broken on 64-bit (which appears to
    > > not be a "real" build configuration): it would either always fail (with
    > > an uninitialized data->buf_size) or would cause corruption in userspace
    > > due to the copy_to_user() in the call path against an uninitialized
    > > data->buf value:
    > >
    > > omap3isp_stat_request_statistics_time32(...)
    > > struct omap3isp_stat_data data64;
    > > ...
    > > omap3isp_stat_request_statistics(stat, &data64);
    > >
    > > int omap3isp_stat_request_statistics(struct ispstat *stat,
    > > struct omap3isp_stat_data *data)
    > > ...
    > > buf = isp_stat_buf_get(stat, data);
    > >
    > > static struct ispstat_buffer *isp_stat_buf_get(struct ispstat *stat,
    > > struct omap3isp_stat_data *data)
    > > ...
    > > if (buf->buf_size > data->buf_size) {
    > > ...
    > > return ERR_PTR(-EINVAL);
    > > }
    > > ...
    > > rval = copy_to_user(data->buf,
    > > buf->virt_addr,
    > > buf->buf_size);
    > >
    > > Regardless, additionally initialize data64 to be zero-filled to avoid
    > > undefined behavior.
    > >
    > > Fixes: 378e3f81cb56 ("media: omap3isp: support 64-bit version of omap3isp_stat_data")
    > > Signed-off-by: Kees Cook <keescook@chromium.org>
    > > ---
    > > drivers/media/platform/omap3isp/ispstat.c | 5 +++--
    > > include/uapi/linux/omap3isp.h | 21 +++++++++++++--------
    > > 2 files changed, 16 insertions(+), 10 deletions(-)
    > >
    > > diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c
    > > index 5b9b57f4d9bf..68cf68dbcace 100644
    > > --- a/drivers/media/platform/omap3isp/ispstat.c
    > > +++ b/drivers/media/platform/omap3isp/ispstat.c
    > > @@ -512,7 +512,7 @@ int omap3isp_stat_request_statistics(struct ispstat *stat,
    > > int omap3isp_stat_request_statistics_time32(struct ispstat *stat,
    > > struct omap3isp_stat_data_time32 *data)
    > > {
    > > - struct omap3isp_stat_data data64;
    > > + struct omap3isp_stat_data data64 = { };
    > > int ret;
    > >
    > > ret = omap3isp_stat_request_statistics(stat, &data64);
    > > @@ -521,7 +521,8 @@ int omap3isp_stat_request_statistics_time32(struct ispstat *stat,
    > >
    > > data->ts.tv_sec = data64.ts.tv_sec;
    > > data->ts.tv_usec = data64.ts.tv_usec;
    > > - memcpy(&data->buf, &data64.buf, sizeof(*data) - sizeof(data->ts));
    > > + data->buf = (uintptr_t)data64.buf;
    >
    > Shouldn't this be
    >
    > data->buf = (uintptr_t)(void *)data64.buf;
    >
    > instead?

    This is already a void *:

    struct omap3isp_stat_data {
    ...
    void __user *buf;
    };

    But I agree, the mix of structures in here is confusing! :)

    -Kees

    --
    Kees Cook

    \
     
     \ /
      Last update: 2021-12-15 18:39    [W:4.946 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site