Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package v4l2loopback for openSUSE:Factory 
checked in at 2026-07-18 22:25:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/v4l2loopback (Old)
 and      /work/SRC/openSUSE:Factory/.v4l2loopback.new.24530 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "v4l2loopback"

Sat Jul 18 22:25:00 2026 rev:29 rq:1366517 version:0.15.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/v4l2loopback/v4l2loopback.changes        
2026-04-28 12:02:03.507685811 +0200
+++ /work/SRC/openSUSE:Factory/.v4l2loopback.new.24530/v4l2loopback.changes     
2026-07-18 22:26:14.456612708 +0200
@@ -1,0 +2,11 @@
+Sat Jul 18 04:57:47 UTC 2026 - <[email protected]>
+
+- Update to version 0.15.4:
+  * Released 0.15.4
+  * Make sure that user-provided max_buffers does not exceed MAX_BUFFERS
+  * Lock image during memcpy access
+  * Use full ordering for buffer mapped flag
+  * trim req_count early
+  * [ci] try again to run kmod-compile on fedora>=41
+
+-------------------------------------------------------------------

Old:
----
  v4l2loopback-0.15.3.tar.xz

New:
----
  v4l2loopback-0.15.4.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ v4l2loopback.spec ++++++
--- /var/tmp/diff_new_pack.EoGC5S/_old  2026-07-18 22:26:15.356642926 +0200
+++ /var/tmp/diff_new_pack.EoGC5S/_new  2026-07-18 22:26:15.356642926 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package v4l2loopback
 #
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -30,7 +30,7 @@
 %{!?_modulesloaddir: %define _modulesloaddir /usr/lib/modules-load.d/}
 
 Name:           v4l2loopback
-Version:        0.15.3
+Version:        0.15.4
 Release:        0
 Summary:        A kernel module to create V4L2 loopback devices
 License:        GPL-2.0-or-later

++++++ _service ++++++
--- /var/tmp/diff_new_pack.EoGC5S/_old  2026-07-18 22:26:15.392644135 +0200
+++ /var/tmp/diff_new_pack.EoGC5S/_new  2026-07-18 22:26:15.396644269 +0200
@@ -4,7 +4,7 @@
     <param name="scm">git</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
-    <param name="revision">v0.15.3</param>
+    <param name="revision">v0.15.4</param>
     <param name="changesgenerate">enable</param>
   </service>
   <service name="recompress" mode="manual">

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.EoGC5S/_old  2026-07-18 22:26:15.420645075 +0200
+++ /var/tmp/diff_new_pack.EoGC5S/_new  2026-07-18 22:26:15.424645209 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/v4l2loopback/v4l2loopback.git</param>
-              <param 
name="changesrevision">a7e4a4dea36187ad3550c797d647bcc50faced42</param></service></servicedata>
+              <param 
name="changesrevision">0f9ee86760b7f2bea174b7e3e7a1d38845da0ab4</param></service></servicedata>
 (No newline at EOF)
 

++++++ v4l2loopback-0.15.3.tar.xz -> v4l2loopback-0.15.4.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/v4l2loopback-0.15.3/.github/workflows/kmod-compatibility-checks.yml 
new/v4l2loopback-0.15.4/.github/workflows/kmod-compatibility-checks.yml
--- old/v4l2loopback-0.15.3/.github/workflows/kmod-compatibility-checks.yml     
2025-11-24 14:15:11.000000000 +0100
+++ new/v4l2loopback-0.15.4/.github/workflows/kmod-compatibility-checks.yml     
2026-06-24 15:50:52.000000000 +0200
@@ -96,7 +96,7 @@
           not_dnf5=true; if dnf5 --version >/dev/null; then not_dnf5=false; fi
           ${not_dnf5} || echo "running dnf5-based distribution 
(Fedora>=41,...)"
           ${not_dnf5} || dnf5 upgrade -y --refresh
-          ${not_dnf5} || dnf5 install -y --setopt=install_weak_deps=False 
--skip-unavailable lsb-release dkms kernel-devel kernel-headers 
kernel-modules-core
+          ${not_dnf5} || dnf5 install -y --setopt=install_weak_deps=False 
--skip-unavailable lsb-release dkms kernel-devel kernel-headers 
kernel-modules-core || dnf5 install -y --setopt=install_weak_deps=False 
--skip-unavailable lsb-release dkms kernel-devel kernel-headers 
kernel-modules-cor
           not_dnf=true; if ${not_dnf5} && dnf --version>/dev/null; then 
not_dnf=false; fi
           ${not_dnf} || echo "running dnf-based distribution (Fedora<41,...)"
           ${not_dnf} || dnf upgrade -y --refresh
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/v4l2loopback-0.15.3/ChangeLog 
new/v4l2loopback-0.15.4/ChangeLog
--- old/v4l2loopback-0.15.3/ChangeLog   2025-11-24 14:15:11.000000000 +0100
+++ new/v4l2loopback-0.15.4/ChangeLog   2026-06-24 15:50:52.000000000 +0200
@@ -1,3 +1,20 @@
+v4l2loopback (0.15.4) unstable; urgency=medium
+
+  [ IOhannes m zmölnig ]
+  * [ci] try again to run kmod-compile on fedora>=41
+  * Make sure that user-provided max_buffers does not exceed MAX_BUFFERS
+    Thanks: Team 42-b3yond-6ug <https://b3yond.org/>
+    Thanks: snpshtwrx & Johnny Nguyen
+
+  [ Jakub Acs ]
+  * Trim req_count early
+
+  [ stephematician ]
+  * Use full ordering for buffer mapped flag
+  * Lock image during memcpy access
+
+ -- IOhannes m zmölnig (Debian/GNU) <[email protected]>  Wed, 24 Jun 2026 
15:45:41 +0200
+
 v4l2loopback (0.15.3) unstable; urgency=medium
 
   [ IOhannes m zmölnig ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/v4l2loopback-0.15.3/dkms.conf 
new/v4l2loopback-0.15.4/dkms.conf
--- old/v4l2loopback-0.15.3/dkms.conf   2025-11-24 14:15:11.000000000 +0100
+++ new/v4l2loopback-0.15.4/dkms.conf   2026-06-24 15:50:52.000000000 +0200
@@ -1,5 +1,5 @@
 PACKAGE_NAME="v4l2loopback"
-PACKAGE_VERSION="0.15.3"
+PACKAGE_VERSION="0.15.4"
 
 # V4L2_COLORSPACE_DCI_P3
 BUILD_EXCLUSIVE_KERNEL_MIN="4.4"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/v4l2loopback-0.15.3/v4l2loopback.c 
new/v4l2loopback-0.15.4/v4l2loopback.c
--- old/v4l2loopback-0.15.3/v4l2loopback.c      2025-11-24 14:15:11.000000000 
+0100
+++ new/v4l2loopback-0.15.4/v4l2loopback.c      2026-06-24 15:50:52.000000000 
+0200
@@ -879,7 +879,9 @@
 
 /* forward declarations */
 static void client_usage_queue_event(struct video_device *vdev);
-static bool any_buffers_mapped(struct v4l2_loopback_device *dev);
+static bool any_mapped_buffer(struct v4l2_loopback_device *dev);
+static void get_buffer(struct v4l2l_buffer *buf);
+static void put_buffer(struct v4l2l_buffer *buf);
 static int allocate_buffers(struct v4l2_loopback_device *dev,
                            struct v4l2_pix_format *pix_format);
 static void init_buffers(struct v4l2_loopback_device *dev, u32 bytes_used,
@@ -1372,7 +1374,7 @@
                if (result < 0)
                        return result;
                if (!dev->keep_format) {
-                       if (has_no_owners(dev) && !any_buffers_mapped(dev))
+                       if (has_no_owners(dev) && !any_mapped_buffer(dev))
                                free_buffers(dev);
                }
                mutex_unlock(&dev->image_mutex);
@@ -1585,7 +1587,7 @@
                flags |= V4L2_BUF_FLAG_DONE;    \
        } while (0)
 
-static bool any_buffers_mapped(struct v4l2_loopback_device *dev)
+static bool any_mapped_buffer(struct v4l2_loopback_device *dev)
 {
        u32 index;
        for (index = 0; index < dev->buffer_count; ++index)
@@ -1594,6 +1596,18 @@
        return false;
 }
 
+static void get_buffer(struct v4l2l_buffer *buf)
+{
+       if (atomic_inc_return(&buf->use_count))
+               buf->buffer.flags |= V4L2_BUF_FLAG_MAPPED;
+}
+
+static void put_buffer(struct v4l2l_buffer *buf)
+{
+       if (atomic_dec_and_test(&buf->use_count))
+               buf->buffer.flags &= ~V4L2_BUF_FLAG_MAPPED;
+}
+
 static void prepare_buffer_queue(struct v4l2_loopback_device *dev, int count)
 {
        struct v4l2l_buffer *bufd, *n;
@@ -1651,6 +1665,9 @@
                reqbuf->memory, req_count, dev->used_buffer_count,
                dev->buffer_count);
 
+       if (req_count > dev->buffer_count)
+               req_count = dev->buffer_count;
+
        switch (reqbuf->memory) {
        case V4L2_MEMORY_MMAP:
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)
@@ -1719,7 +1736,7 @@
        if (has_other_owners(opener, dev) && dev->used_buffer_count > 0) {
                /* allow 'allocation' of existing number of buffers */
                req_count = dev->used_buffer_count;
-       } else if (any_buffers_mapped(dev)) {
+       } else if (any_mapped_buffer(dev)) {
                /* do not allow re-allocation if buffers are mapped */
                result = -EBUSY;
                goto exit_reqbufs_unlock;
@@ -1727,10 +1744,6 @@
 
        MARK();
        opener->buffer_count = 0;
-
-       if (req_count > dev->buffer_count)
-               req_count = dev->buffer_count;
-
        if (has_no_owners(dev)) {
                result = allocate_buffers(dev, &dev->pix_format);
                if (result < 0)
@@ -1810,17 +1823,24 @@
        timer_delete_sync(&dev->sustain_timer);
        timer_delete_sync(&dev->timeout_timer);
 
-       spin_lock_bh(&dev->list_lock);
-       list_move_tail(&buf->list_head, &dev->outbufs_list);
-       spin_unlock_bh(&dev->list_lock);
+       mutex_lock(&dev->image_mutex);
+       if (dev->used_buffer_count != 0) {
+               spin_lock_bh(&dev->list_lock);
+               list_move_tail(&buf->list_head, &dev->outbufs_list);
+               spin_unlock_bh(&dev->list_lock);
 
-       spin_lock_bh(&dev->lock);
-       dev->bufpos2index[v4l2l_mod64(dev->write_position,
-                                     dev->used_buffer_count)] =
-               buf->buffer.index;
-       ++dev->write_position;
-       dev->reread_count = 0;
+               spin_lock_bh(&dev->lock);
+               dev->bufpos2index[v4l2l_mod64(dev->write_position,
+                                             dev->used_buffer_count)] =
+                       buf->buffer.index;
 
+               ++dev->write_position;
+               dev->reread_count = 0;
+               spin_unlock_bh(&dev->lock);
+       }
+       mutex_unlock(&dev->image_mutex);
+
+       spin_lock_bh(&dev->lock);
        check_timers(dev);
        spin_unlock_bh(&dev->lock);
 }
@@ -1934,6 +1954,11 @@
                return -EAGAIN;
        wait_event_interruptible(dev->read_event, can_read(dev, opener));
 
+       mutex_lock(&dev->image_mutex);
+       if (!dev->image || dev->used_buffer_count == 0) {
+               mutex_unlock(&dev->image_mutex);
+               return -EINVAL;
+       }
        spin_lock_bh(&dev->lock);
        if (dev->write_position == opener->read_position) {
                if (dev->reread_count > opener->reread_count + 2)
@@ -1953,21 +1978,20 @@
        }
        timeout_happened = dev->timeout_happened && (dev->timeout_jiffies > 0);
        dev->timeout_happened = 0;
+       index = dev->bufpos2index[pos];
+       if (timeout_happened)
+               get_buffer(&dev->buffers[index]);
+
        spin_unlock_bh(&dev->lock);
+       mutex_unlock(&dev->image_mutex);
 
-       index = dev->bufpos2index[pos];
        if (timeout_happened) {
-               if (index >= dev->used_buffer_count) {
-                       dprintkrw("get_capture_buffer() read position is at "
-                                 "an unallocated buffer [index=%u]\n",
-                                 index);
-                       return -EFAULT;
-               }
                /* although allocated on-demand, timeout_image is freed only
                 * in free_buffers(), so we don't need to worry about it being
                 * deallocated suddenly */
                memcpy(dev->image + dev->buffers[index].buffer.m.offset,
                       dev->timeout_image, dev->buffer_size);
+               put_buffer(&dev->buffers[index]);
        }
        return (int)index;
 }
@@ -2182,22 +2206,16 @@
 /* file operations */
 static void vm_open(struct vm_area_struct *vma)
 {
-       struct v4l2l_buffer *buf;
+       struct v4l2l_buffer *buf = vma->vm_private_data;
        MARK();
-
-       buf = vma->vm_private_data;
-       atomic_inc(&buf->use_count);
-       buf->buffer.flags |= V4L2_BUF_FLAG_MAPPED;
+       get_buffer(buf);
 }
 
 static void vm_close(struct vm_area_struct *vma)
 {
-       struct v4l2l_buffer *buf;
+       struct v4l2l_buffer *buf = vma->vm_private_data;
        MARK();
-
-       buf = vma->vm_private_data;
-       if (atomic_dec_and_test(&buf->use_count))
-               buf->buffer.flags &= ~V4L2_BUF_FLAG_MAPPED;
+       put_buffer(buf);
 }
 
 static struct vm_operations_struct vm_ops = {
@@ -2274,8 +2292,8 @@
 
        vma->vm_ops = &vm_ops;
        vma->vm_private_data = buffer;
+       get_buffer(buffer);
 
-       vm_open(vma);
 exit_mmap_unlock:
        mutex_unlock(&dev->image_mutex);
        return result;
@@ -2454,14 +2472,26 @@
        index = get_capture_buffer(file);
        if (index < 0)
                return index;
+
+       mutex_lock(&dev->image_mutex);
+       if (!dev->image) {
+               mutex_unlock(&dev->image_mutex);
+               return -EINVAL;
+       }
+       get_buffer(&dev->buffers[index]);
+       mutex_unlock(&dev->image_mutex);
+
        b = &dev->buffers[index].buffer;
        if (count > b->bytesused)
                count = b->bytesused;
+
        if (copy_to_user((void *)buf, (void *)(dev->image + b->m.offset),
                         count)) {
                printk(KERN_ERR "v4l2-loopback read() failed copy_to_user()\n");
+               put_buffer(&dev->buffers[index]);
                return -EFAULT;
        }
+       put_buffer(&dev->buffers[index]);
        return count;
 }
 
@@ -2480,15 +2510,25 @@
 
        if (count > dev->buffer_size)
                count = dev->buffer_size;
+
+       mutex_lock(&dev->image_mutex);
+       if (!dev->image || dev->used_buffer_count == 0) {
+               mutex_unlock(&dev->image_mutex);
+               return -EINVAL;
+       }
        index = v4l2l_mod64(dev->write_position, dev->used_buffer_count);
-       b = &dev->buffers[index].buffer;
+       get_buffer(&dev->buffers[index]);
+       mutex_unlock(&dev->image_mutex);
 
+       b = &dev->buffers[index].buffer;
        if (copy_from_user((void *)(dev->image + b->m.offset), (void *)buf,
                           count)) {
                printk(KERN_ERR
                       "v4l2-loopback write() failed copy_from_user()\n");
+               put_buffer(&dev->buffers[index]);
                return -EFAULT;
        }
+       put_buffer(&dev->buffers[index]);
        b->bytesused = count;
 
        v4l2l_get_timestamp(b);
@@ -2508,7 +2548,7 @@
        dprintk("free_buffers() with image@%p\n", dev->image);
        if (!dev->image)
                return;
-       if (!has_no_owners(dev) || any_buffers_mapped(dev))
+       if (!has_no_owners(dev) || any_mapped_buffer(dev))
                /* maybe an opener snuck in before image_mutex was acquired */
                printk(KERN_WARNING
                       "v4l2-loopback free_buffers() buffers of video device "
@@ -2558,7 +2598,7 @@
                image_size, buffer_size, dev->buffer_count);
        if (dev->image) {
                /* check that no buffers are expected in user-space */
-               if (!has_no_owners(dev) || any_buffers_mapped(dev))
+               if (!has_no_owners(dev) || any_mapped_buffer(dev))
                        return -EBUSY;
                dprintk("allocate_buffers() existing size=%lubytes\n",
                        dev->image_size);
@@ -2762,6 +2802,10 @@
 
        int nr = -1;
 
+       /* Fix: Ensure buffer count does not exceed the statically allocated 
array size */
+       if (_max_buffers > MAX_BUFFERS)
+               _max_buffers = MAX_BUFFERS;
+
        if (conf) {
                const int output_nr = conf->output_nr;
 #ifdef SPLIT_DEVICES
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/v4l2loopback-0.15.3/v4l2loopback.h 
new/v4l2loopback-0.15.4/v4l2loopback.h
--- old/v4l2loopback-0.15.3/v4l2loopback.h      2025-11-24 14:15:11.000000000 
+0100
+++ new/v4l2loopback-0.15.4/v4l2loopback.h      2026-06-24 15:50:52.000000000 
+0200
@@ -12,7 +12,7 @@
 
 #define V4L2LOOPBACK_VERSION_MAJOR 0
 #define V4L2LOOPBACK_VERSION_MINOR 15
-#define V4L2LOOPBACK_VERSION_BUGFIX 3
+#define V4L2LOOPBACK_VERSION_BUGFIX 4
 
 /* /dev/v4l2loopback interface */
 

Reply via email to