[libcamera-devel] [PATCH 1/2] v4l2: v4l2_compat: Intercept open64, openat64, and mmap64
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Wed Jun 17 02:28:22 CEST 2020
Hi Paul,
Thank you for the patch.
On Tue, Jun 16, 2020 at 07:56:32PM +0900, Paul Elder wrote:
> Some applications (eg. Firefox, Google Chrome, Skype) use import open64,
use or import ?
> openat64, and mmap64 instead of their non-64 versions that we currently
> intercept. Intercept these calls as well.
>
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> ---
> src/v4l2/meson.build | 1 +
> src/v4l2/v4l2_camera_proxy.cpp | 2 +-
> src/v4l2/v4l2_camera_proxy.h | 3 ++-
> src/v4l2/v4l2_compat.cpp | 29 ++++++++++++++++++++++++++++-
> src/v4l2/v4l2_compat_manager.cpp | 2 +-
> src/v4l2/v4l2_compat_manager.h | 5 +++--
> 6 files changed, 36 insertions(+), 6 deletions(-)
>
> diff --git a/src/v4l2/meson.build b/src/v4l2/meson.build
> index 0fb941e..f2e4aaf 100644
> --- a/src/v4l2/meson.build
> +++ b/src/v4l2/meson.build
> @@ -15,6 +15,7 @@ v4l2_compat_cpp_args = [
> # file operations, disable transparent large file support.
> '-U_FILE_OFFSET_BITS',
> '-D_FILE_OFFSET_BITS=32',
> + '-D_LARGEFILE64_SOURCE',
This deserves an explanation in the commit message.
> '-fvisibility=hidden',
> ]
>
> diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
> index 17477ab..59af209 100644
> --- a/src/v4l2/v4l2_camera_proxy.cpp
> +++ b/src/v4l2/v4l2_camera_proxy.cpp
> @@ -75,7 +75,7 @@ void V4L2CameraProxy::close()
> }
>
> void *V4L2CameraProxy::mmap(void *addr, size_t length, int prot, int flags,
> - off_t offset)
> + __off64_t offset)
> {
> LOG(V4L2Compat, Debug) << "Servicing mmap";
>
> diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
> index 7c65c88..b5a9801 100644
> --- a/src/v4l2/v4l2_camera_proxy.h
> +++ b/src/v4l2/v4l2_camera_proxy.h
> @@ -11,6 +11,7 @@
> #include <linux/videodev2.h>
> #include <map>
> #include <memory>
> +#include <sys/mman.h>
> #include <sys/types.h>
> #include <vector>
>
> @@ -28,7 +29,7 @@ public:
> int open(bool nonBlocking);
> void dup();
> void close();
> - void *mmap(void *addr, size_t length, int prot, int flags, off_t offset);
> + void *mmap(void *addr, size_t length, int prot, int flags, __off64_t offset);
Can't you use off64_t ? Types starting with a double underscore are
internal to the libc implementation. While this will work with glibc and
uclibc, musl doesn't provide __off64_t, but provides off64_t.
> int munmap(void *addr, size_t length);
>
> int ioctl(unsigned long request, void *arg);
> diff --git a/src/v4l2/v4l2_compat.cpp b/src/v4l2/v4l2_compat.cpp
> index 2a9a176..ead36e6 100644
> --- a/src/v4l2/v4l2_compat.cpp
> +++ b/src/v4l2/v4l2_compat.cpp
> @@ -38,6 +38,16 @@ LIBCAMERA_PUBLIC int open(const char *path, int oflag, ...)
> oflag, mode);
> }
>
> +LIBCAMERA_PUBLIC int open64(const char *path, int oflag, ...)
> +{
> + mode_t mode = 0;
> + if (oflag & O_CREAT || oflag & O_TMPFILE)
> + extract_va_arg(mode_t, mode, oflag);
> +
> + return V4L2CompatManager::instance()->openat(AT_FDCWD, path,
> + oflag | O_LARGEFILE, mode);
> +}
> +
> /* _FORTIFY_SOURCE redirects open to __open_2 */
> LIBCAMERA_PUBLIC int __open_2(const char *path, int oflag)
> {
> @@ -53,6 +63,16 @@ LIBCAMERA_PUBLIC int openat(int dirfd, const char *path, int oflag, ...)
> return V4L2CompatManager::instance()->openat(dirfd, path, oflag, mode);
> }
>
> +LIBCAMERA_PUBLIC int openat64(int dirfd, const char *path, int oflag, ...)
> +{
> + mode_t mode = 0;
> + if (oflag & O_CREAT || oflag & O_TMPFILE)
> + extract_va_arg(mode_t, mode, oflag);
> +
> + return V4L2CompatManager::instance()->openat(dirfd, path,
> + oflag | O_LARGEFILE, mode);
> +}
> +
> LIBCAMERA_PUBLIC int __openat_2(int dirfd, const char *path, int oflag)
> {
> return openat(dirfd, path, oflag);
> @@ -69,7 +89,14 @@ LIBCAMERA_PUBLIC int close(int fd)
> }
>
> LIBCAMERA_PUBLIC void *mmap(void *addr, size_t length, int prot, int flags,
> - int fd, off_t offset)
> + int fd, __off_t offset)
> +{
> + return V4L2CompatManager::instance()->mmap(addr, length, prot, flags,
> + fd, offset);
> +}
> +
> +LIBCAMERA_PUBLIC void *mmap64(void *addr, size_t length, int prot, int flags,
> + int fd, __off64_t offset)
With musl, when _LARGEFILE64_SOURCE is define, mmap64 is handled with
#define mmap64 mmap
#define off64_t off_t
Other functions are handled in a similar way. You will thus have an
issue here.
There doesn't seem to be an easy way to detect musl (as in #ifdef
__MUSL__ for instance), but I think we can address this with
#ifndef mmap64
LIBCAMERA_PUBLIC void *mmap64(void *addr, size_t length, int prot, int flags,
int fd, __off64_t offset)
{
...
}
#endif
as with glibc and uclibc mmap64 is a function, not a macro. Same for the
other functions.
> {
> return V4L2CompatManager::instance()->mmap(addr, length, prot, flags,
> fd, offset);
> diff --git a/src/v4l2/v4l2_compat_manager.cpp b/src/v4l2/v4l2_compat_manager.cpp
> index 56533c4..f928760 100644
> --- a/src/v4l2/v4l2_compat_manager.cpp
> +++ b/src/v4l2/v4l2_compat_manager.cpp
> @@ -200,7 +200,7 @@ int V4L2CompatManager::close(int fd)
> }
>
> void *V4L2CompatManager::mmap(void *addr, size_t length, int prot, int flags,
> - int fd, off_t offset)
> + int fd, __off64_t offset)
> {
> V4L2CameraProxy *proxy = getProxy(fd);
> if (!proxy)
> diff --git a/src/v4l2/v4l2_compat_manager.h b/src/v4l2/v4l2_compat_manager.h
> index 14338a5..baf23ae 100644
> --- a/src/v4l2/v4l2_compat_manager.h
> +++ b/src/v4l2/v4l2_compat_manager.h
> @@ -11,6 +11,7 @@
> #include <fcntl.h>
> #include <map>
> #include <memory>
> +#include <sys/mman.h>
> #include <sys/types.h>
> #include <vector>
>
> @@ -30,7 +31,7 @@ public:
> using close_func_t = int (*)(int fd);
> using ioctl_func_t = int (*)(int fd, unsigned long request, ...);
> using mmap_func_t = void *(*)(void *addr, size_t length, int prot,
> - int flags, int fd, off_t offset);
> + int flags, int fd, __off64_t offset);
> using munmap_func_t = int (*)(void *addr, size_t length);
The redirection is performed with
get_symbol(fops_.openat, "openat");
get_symbol(fops_.dup, "dup");
get_symbol(fops_.close, "close");
get_symbol(fops_.ioctl, "ioctl");
get_symbol(fops_.mmap, "mmap");
get_symbol(fops_.munmap, "munmap");
Don't you thus redirect to 32-bit versions ? Shouldn't this become
openat64 and mmap64 ?
The uclibc implementation is very similar to glibc, but musl is quite
different. I would thus recommend at least compile-testing the series
against musl. You can build a minimal musl-based rootfs with buildroot
and use that to "cross-compile" libcamera (not sure if compiling for x86
on x86 technically counts as cross-compilation :-)) for musl.
>
> openat_func_t openat;
> @@ -51,7 +52,7 @@ public:
> int dup(int oldfd);
> int close(int fd);
> void *mmap(void *addr, size_t length, int prot, int flags,
> - int fd, off_t offset);
> + int fd, __off64_t offset);
> int munmap(void *addr, size_t length);
> int ioctl(int fd, unsigned long request, void *arg);
>
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list