[libcamera-devel] libcamera: Open files with O_CLOEXEC
diff mbox series

Message ID 20230326100155.7532-1-laurent.pinchart@ideasonboard.com
State Accepted
Commit 436b38fd89fe4324d2342084ef477a7a8809a001
Headers show
Series
  • [libcamera-devel] libcamera: Open files with O_CLOEXEC
Related show

Commit Message

Laurent Pinchart March 26, 2023, 10:01 a.m. UTC
Files opened internally in libcamera without the O_CLOEXEC file will
remain open upon a call to one of the exec(3) functions. As exec()
doesn't destroy local or global objects, this can lead to various side
effects. Avoid this by opening file descriptors with O_CLOEXEC for all
internal files.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/ipa/vimc/vimc.cpp                            | 2 +-
 src/libcamera/base/file.cpp                      | 5 ++++-
 src/libcamera/media_device.cpp                   | 2 +-
 src/libcamera/pipeline/raspberrypi/dma_heaps.cpp | 2 +-
 4 files changed, 7 insertions(+), 4 deletions(-)

Comments

Umang Jain March 27, 2023, 4:07 a.m. UTC | #1
Hi Laurent,

Thank you for the patch

On 3/26/23 3:31 PM, Laurent Pinchart via libcamera-devel wrote:
> Files opened internally in libcamera without the O_CLOEXEC file will
> remain open upon a call to one of the exec(3) functions. As exec()
> doesn't destroy local or global objects, this can lead to various side
> effects. Avoid this by opening file descriptors with O_CLOEXEC for all
> internal files.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>

> ---
>   src/ipa/vimc/vimc.cpp                            | 2 +-
>   src/libcamera/base/file.cpp                      | 5 ++++-
>   src/libcamera/media_device.cpp                   | 2 +-
>   src/libcamera/pipeline/raspberrypi/dma_heaps.cpp | 2 +-
>   4 files changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/src/ipa/vimc/vimc.cpp b/src/ipa/vimc/vimc.cpp
> index d5fabaf13ec6..2c255778990a 100644
> --- a/src/ipa/vimc/vimc.cpp
> +++ b/src/ipa/vimc/vimc.cpp
> @@ -168,7 +168,7 @@ void IPAVimc::initTrace()
>   	if (ret)
>   		return;
>   
> -	ret = ::open(ipa::vimc::VimcIPAFIFOPath.c_str(), O_WRONLY);
> +	ret = ::open(ipa::vimc::VimcIPAFIFOPath.c_str(), O_WRONLY | O_CLOEXEC);
>   	if (ret < 0) {
>   		ret = errno;
>   		LOG(IPAVimc, Error) << "Failed to open vimc IPA test FIFO: "
> diff --git a/src/libcamera/base/file.cpp b/src/libcamera/base/file.cpp
> index fb3e276d6ccd..d1ab1aa57462 100644
> --- a/src/libcamera/base/file.cpp
> +++ b/src/libcamera/base/file.cpp
> @@ -163,6 +163,9 @@ bool File::exists() const
>    * attempt to create the file with initial permissions set to 0666 (modified by
>    * the process' umask).
>    *
> + * The file is opened with the O_CLOEXEC flag, and will be closed automatically
> + * when a new binary is executed with one of the exec(3) functions.
> + *
>    * The error() status is updated.
>    *
>    * \return True on success, false otherwise
> @@ -178,7 +181,7 @@ bool File::open(File::OpenMode mode)
>   	if (mode & OpenModeFlag::WriteOnly)
>   		flags |= O_CREAT;
>   
> -	fd_ = UniqueFD(::open(name_.c_str(), flags, 0666));
> +	fd_ = UniqueFD(::open(name_.c_str(), flags | O_CLOEXEC, 0666));
>   	if (!fd_.isValid()) {
>   		error_ = -errno;
>   		return false;
> diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp
> index 52c8e66e9e99..2949816b4a64 100644
> --- a/src/libcamera/media_device.cpp
> +++ b/src/libcamera/media_device.cpp
> @@ -477,7 +477,7 @@ int MediaDevice::open()
>   		return -EBUSY;
>   	}
>   
> -	fd_ = UniqueFD(::open(deviceNode_.c_str(), O_RDWR));
> +	fd_ = UniqueFD(::open(deviceNode_.c_str(), O_RDWR | O_CLOEXEC));
>   	if (!fd_.isValid()) {
>   		int ret = -errno;
>   		LOG(MediaDevice, Error)
> diff --git a/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp b/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
> index 6b644406c90f..317b1fc17161 100644
> --- a/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
> +++ b/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
> @@ -37,7 +37,7 @@ namespace RPi {
>   DmaHeap::DmaHeap()
>   {
>   	for (const char *name : heapNames) {
> -		int ret = ::open(name, O_RDWR, 0);
> +		int ret = ::open(name, O_RDWR | O_CLOEXEC, 0);
>   		if (ret < 0) {
>   			ret = errno;
>   			LOG(RPI, Debug) << "Failed to open " << name << ": "
Kieran Bingham March 27, 2023, 3:17 p.m. UTC | #2
Quoting Laurent Pinchart via libcamera-devel (2023-03-26 11:01:55)
> Files opened internally in libcamera without the O_CLOEXEC file will
> remain open upon a call to one of the exec(3) functions. As exec()
> doesn't destroy local or global objects, this can lead to various side
> effects. Avoid this by opening file descriptors with O_CLOEXEC for all
> internal files.

This seems more prolific than it should be.

It makes me think we should enforce it with a helper instead but I'm not
sure if that's much different to adding a checkstyle rule!?

Anyway, this seems reasonable otherwise.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

--
Kieran

> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  src/ipa/vimc/vimc.cpp                            | 2 +-
>  src/libcamera/base/file.cpp                      | 5 ++++-
>  src/libcamera/media_device.cpp                   | 2 +-
>  src/libcamera/pipeline/raspberrypi/dma_heaps.cpp | 2 +-
>  4 files changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/src/ipa/vimc/vimc.cpp b/src/ipa/vimc/vimc.cpp
> index d5fabaf13ec6..2c255778990a 100644
> --- a/src/ipa/vimc/vimc.cpp
> +++ b/src/ipa/vimc/vimc.cpp
> @@ -168,7 +168,7 @@ void IPAVimc::initTrace()
>         if (ret)
>                 return;
>  
> -       ret = ::open(ipa::vimc::VimcIPAFIFOPath.c_str(), O_WRONLY);
> +       ret = ::open(ipa::vimc::VimcIPAFIFOPath.c_str(), O_WRONLY | O_CLOEXEC);
>         if (ret < 0) {
>                 ret = errno;
>                 LOG(IPAVimc, Error) << "Failed to open vimc IPA test FIFO: "
> diff --git a/src/libcamera/base/file.cpp b/src/libcamera/base/file.cpp
> index fb3e276d6ccd..d1ab1aa57462 100644
> --- a/src/libcamera/base/file.cpp
> +++ b/src/libcamera/base/file.cpp
> @@ -163,6 +163,9 @@ bool File::exists() const
>   * attempt to create the file with initial permissions set to 0666 (modified by
>   * the process' umask).
>   *
> + * The file is opened with the O_CLOEXEC flag, and will be closed automatically
> + * when a new binary is executed with one of the exec(3) functions.
> + *
>   * The error() status is updated.
>   *
>   * \return True on success, false otherwise
> @@ -178,7 +181,7 @@ bool File::open(File::OpenMode mode)
>         if (mode & OpenModeFlag::WriteOnly)
>                 flags |= O_CREAT;
>  
> -       fd_ = UniqueFD(::open(name_.c_str(), flags, 0666));
> +       fd_ = UniqueFD(::open(name_.c_str(), flags | O_CLOEXEC, 0666));
>         if (!fd_.isValid()) {
>                 error_ = -errno;
>                 return false;
> diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp
> index 52c8e66e9e99..2949816b4a64 100644
> --- a/src/libcamera/media_device.cpp
> +++ b/src/libcamera/media_device.cpp
> @@ -477,7 +477,7 @@ int MediaDevice::open()
>                 return -EBUSY;
>         }
>  
> -       fd_ = UniqueFD(::open(deviceNode_.c_str(), O_RDWR));
> +       fd_ = UniqueFD(::open(deviceNode_.c_str(), O_RDWR | O_CLOEXEC));
>         if (!fd_.isValid()) {
>                 int ret = -errno;
>                 LOG(MediaDevice, Error)
> diff --git a/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp b/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
> index 6b644406c90f..317b1fc17161 100644
> --- a/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
> +++ b/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
> @@ -37,7 +37,7 @@ namespace RPi {
>  DmaHeap::DmaHeap()
>  {
>         for (const char *name : heapNames) {
> -               int ret = ::open(name, O_RDWR, 0);
> +               int ret = ::open(name, O_RDWR | O_CLOEXEC, 0);
>                 if (ret < 0) {
>                         ret = errno;
>                         LOG(RPI, Debug) << "Failed to open " << name << ": "
> -- 
> Regards,
> 
> Laurent Pinchart
>
Laurent Pinchart April 5, 2023, 4:19 a.m. UTC | #3
Hi Kieran,

On Mon, Mar 27, 2023 at 04:17:17PM +0100, Kieran Bingham wrote:
> Quoting Laurent Pinchart via libcamera-devel (2023-03-26 11:01:55)
> > Files opened internally in libcamera without the O_CLOEXEC file will
> > remain open upon a call to one of the exec(3) functions. As exec()
> > doesn't destroy local or global objects, this can lead to various side
> > effects. Avoid this by opening file descriptors with O_CLOEXEC for all
> > internal files.
> 
> This seems more prolific than it should be.
> 
> It makes me think we should enforce it with a helper instead but I'm not
> sure if that's much different to adding a checkstyle rule!?

Wider usage of the File class may help.

> Anyway, this seems reasonable otherwise.
> 
> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
>
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > ---
> >  src/ipa/vimc/vimc.cpp                            | 2 +-
> >  src/libcamera/base/file.cpp                      | 5 ++++-
> >  src/libcamera/media_device.cpp                   | 2 +-
> >  src/libcamera/pipeline/raspberrypi/dma_heaps.cpp | 2 +-
> >  4 files changed, 7 insertions(+), 4 deletions(-)
> > 
> > diff --git a/src/ipa/vimc/vimc.cpp b/src/ipa/vimc/vimc.cpp
> > index d5fabaf13ec6..2c255778990a 100644
> > --- a/src/ipa/vimc/vimc.cpp
> > +++ b/src/ipa/vimc/vimc.cpp
> > @@ -168,7 +168,7 @@ void IPAVimc::initTrace()
> >         if (ret)
> >                 return;
> >  
> > -       ret = ::open(ipa::vimc::VimcIPAFIFOPath.c_str(), O_WRONLY);
> > +       ret = ::open(ipa::vimc::VimcIPAFIFOPath.c_str(), O_WRONLY | O_CLOEXEC);
> >         if (ret < 0) {
> >                 ret = errno;
> >                 LOG(IPAVimc, Error) << "Failed to open vimc IPA test FIFO: "
> > diff --git a/src/libcamera/base/file.cpp b/src/libcamera/base/file.cpp
> > index fb3e276d6ccd..d1ab1aa57462 100644
> > --- a/src/libcamera/base/file.cpp
> > +++ b/src/libcamera/base/file.cpp
> > @@ -163,6 +163,9 @@ bool File::exists() const
> >   * attempt to create the file with initial permissions set to 0666 (modified by
> >   * the process' umask).
> >   *
> > + * The file is opened with the O_CLOEXEC flag, and will be closed automatically
> > + * when a new binary is executed with one of the exec(3) functions.
> > + *
> >   * The error() status is updated.
> >   *
> >   * \return True on success, false otherwise
> > @@ -178,7 +181,7 @@ bool File::open(File::OpenMode mode)
> >         if (mode & OpenModeFlag::WriteOnly)
> >                 flags |= O_CREAT;
> >  
> > -       fd_ = UniqueFD(::open(name_.c_str(), flags, 0666));
> > +       fd_ = UniqueFD(::open(name_.c_str(), flags | O_CLOEXEC, 0666));
> >         if (!fd_.isValid()) {
> >                 error_ = -errno;
> >                 return false;
> > diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp
> > index 52c8e66e9e99..2949816b4a64 100644
> > --- a/src/libcamera/media_device.cpp
> > +++ b/src/libcamera/media_device.cpp
> > @@ -477,7 +477,7 @@ int MediaDevice::open()
> >                 return -EBUSY;
> >         }
> >  
> > -       fd_ = UniqueFD(::open(deviceNode_.c_str(), O_RDWR));
> > +       fd_ = UniqueFD(::open(deviceNode_.c_str(), O_RDWR | O_CLOEXEC));
> >         if (!fd_.isValid()) {
> >                 int ret = -errno;
> >                 LOG(MediaDevice, Error)
> > diff --git a/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp b/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
> > index 6b644406c90f..317b1fc17161 100644
> > --- a/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
> > +++ b/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
> > @@ -37,7 +37,7 @@ namespace RPi {
> >  DmaHeap::DmaHeap()
> >  {
> >         for (const char *name : heapNames) {
> > -               int ret = ::open(name, O_RDWR, 0);
> > +               int ret = ::open(name, O_RDWR | O_CLOEXEC, 0);
> >                 if (ret < 0) {
> >                         ret = errno;
> >                         LOG(RPI, Debug) << "Failed to open " << name << ": "

Patch
diff mbox series

diff --git a/src/ipa/vimc/vimc.cpp b/src/ipa/vimc/vimc.cpp
index d5fabaf13ec6..2c255778990a 100644
--- a/src/ipa/vimc/vimc.cpp
+++ b/src/ipa/vimc/vimc.cpp
@@ -168,7 +168,7 @@  void IPAVimc::initTrace()
 	if (ret)
 		return;
 
-	ret = ::open(ipa::vimc::VimcIPAFIFOPath.c_str(), O_WRONLY);
+	ret = ::open(ipa::vimc::VimcIPAFIFOPath.c_str(), O_WRONLY | O_CLOEXEC);
 	if (ret < 0) {
 		ret = errno;
 		LOG(IPAVimc, Error) << "Failed to open vimc IPA test FIFO: "
diff --git a/src/libcamera/base/file.cpp b/src/libcamera/base/file.cpp
index fb3e276d6ccd..d1ab1aa57462 100644
--- a/src/libcamera/base/file.cpp
+++ b/src/libcamera/base/file.cpp
@@ -163,6 +163,9 @@  bool File::exists() const
  * attempt to create the file with initial permissions set to 0666 (modified by
  * the process' umask).
  *
+ * The file is opened with the O_CLOEXEC flag, and will be closed automatically
+ * when a new binary is executed with one of the exec(3) functions.
+ *
  * The error() status is updated.
  *
  * \return True on success, false otherwise
@@ -178,7 +181,7 @@  bool File::open(File::OpenMode mode)
 	if (mode & OpenModeFlag::WriteOnly)
 		flags |= O_CREAT;
 
-	fd_ = UniqueFD(::open(name_.c_str(), flags, 0666));
+	fd_ = UniqueFD(::open(name_.c_str(), flags | O_CLOEXEC, 0666));
 	if (!fd_.isValid()) {
 		error_ = -errno;
 		return false;
diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp
index 52c8e66e9e99..2949816b4a64 100644
--- a/src/libcamera/media_device.cpp
+++ b/src/libcamera/media_device.cpp
@@ -477,7 +477,7 @@  int MediaDevice::open()
 		return -EBUSY;
 	}
 
-	fd_ = UniqueFD(::open(deviceNode_.c_str(), O_RDWR));
+	fd_ = UniqueFD(::open(deviceNode_.c_str(), O_RDWR | O_CLOEXEC));
 	if (!fd_.isValid()) {
 		int ret = -errno;
 		LOG(MediaDevice, Error)
diff --git a/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp b/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
index 6b644406c90f..317b1fc17161 100644
--- a/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
+++ b/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp
@@ -37,7 +37,7 @@  namespace RPi {
 DmaHeap::DmaHeap()
 {
 	for (const char *name : heapNames) {
-		int ret = ::open(name, O_RDWR, 0);
+		int ret = ::open(name, O_RDWR | O_CLOEXEC, 0);
 		if (ret < 0) {
 			ret = errno;
 			LOG(RPI, Debug) << "Failed to open " << name << ": "