]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 26 May 2022 12:24:48 +0000 (14:24 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 26 May 2022 12:24:48 +0000 (14:24 +0200)
added patches:
media-vim2m-initialize-the-media-device-earlier.patch
media-vim2m-register-video-device-after-setting-up-internals.patch
secure_seq-use-the-64-bits-of-the-siphash-for-port-offset-calculation.patch
tcp-change-source-port-randomizarion-at-connect-time.patch

queue-5.10/media-vim2m-initialize-the-media-device-earlier.patch [new file with mode: 0644]
queue-5.10/media-vim2m-register-video-device-after-setting-up-internals.patch [new file with mode: 0644]
queue-5.10/secure_seq-use-the-64-bits-of-the-siphash-for-port-offset-calculation.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/tcp-change-source-port-randomizarion-at-connect-time.patch [new file with mode: 0644]

diff --git a/queue-5.10/media-vim2m-initialize-the-media-device-earlier.patch b/queue-5.10/media-vim2m-initialize-the-media-device-earlier.patch
new file mode 100644 (file)
index 0000000..d90b6ae
--- /dev/null
@@ -0,0 +1,53 @@
+From 1a28dce222a6ece725689ad58c0cf4a1b48894f4 Mon Sep 17 00:00:00 2001
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Date: Tue, 2 Feb 2021 15:49:23 +0100
+Subject: media: vim2m: initialize the media device earlier
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+commit 1a28dce222a6ece725689ad58c0cf4a1b48894f4 upstream.
+
+Before the video device node is registered, the v4l2_dev.mdev
+pointer must be set in order to correctly associate the video
+device with the media device. Move the initialization of the
+media device up.
+
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Mark-PK Tsai <mark-pk.tsai@mediatek.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/media/test-drivers/vim2m.c |   14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+--- a/drivers/media/test-drivers/vim2m.c
++++ b/drivers/media/test-drivers/vim2m.c
+@@ -1339,12 +1339,6 @@ static int vim2m_probe(struct platform_d
+               goto error_dev;
+       }
+-      ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
+-      if (ret) {
+-              v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
+-              goto error_m2m;
+-      }
+-
+ #ifdef CONFIG_MEDIA_CONTROLLER
+       dev->mdev.dev = &pdev->dev;
+       strscpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
+@@ -1353,7 +1347,15 @@ static int vim2m_probe(struct platform_d
+       media_device_init(&dev->mdev);
+       dev->mdev.ops = &m2m_media_ops;
+       dev->v4l2_dev.mdev = &dev->mdev;
++#endif
++      ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
++      if (ret) {
++              v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
++              goto error_m2m;
++      }
++
++#ifdef CONFIG_MEDIA_CONTROLLER
+       ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd,
+                                                MEDIA_ENT_F_PROC_VIDEO_SCALER);
+       if (ret) {
diff --git a/queue-5.10/media-vim2m-register-video-device-after-setting-up-internals.patch b/queue-5.10/media-vim2m-register-video-device-after-setting-up-internals.patch
new file mode 100644 (file)
index 0000000..d2cb575
--- /dev/null
@@ -0,0 +1,76 @@
+From cf7f34777a5b4100a3a44ff95f3d949c62892bdd Mon Sep 17 00:00:00 2001
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+Date: Tue, 10 Nov 2020 00:07:22 +0100
+Subject: media: vim2m: Register video device after setting up internals
+
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+
+commit cf7f34777a5b4100a3a44ff95f3d949c62892bdd upstream.
+
+Prevent NULL (or close to NULL) pointer dereference in various places by
+registering the video device only when the V4L2 m2m framework has been set
+up.
+
+Fixes: commit 96d8eab5d0a1 ("V4L/DVB: [v5,2/2] v4l: Add a mem-to-mem videobuf framework test device")
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Mark-PK Tsai <mark-pk.tsai@mediatek.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/media/test-drivers/vim2m.c |   20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+--- a/drivers/media/test-drivers/vim2m.c
++++ b/drivers/media/test-drivers/vim2m.c
+@@ -1325,12 +1325,6 @@ static int vim2m_probe(struct platform_d
+       vfd->lock = &dev->dev_mutex;
+       vfd->v4l2_dev = &dev->v4l2_dev;
+-      ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
+-      if (ret) {
+-              v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
+-              goto error_v4l2;
+-      }
+-
+       video_set_drvdata(vfd, dev);
+       v4l2_info(&dev->v4l2_dev,
+                 "Device registered as /dev/video%d\n", vfd->num);
+@@ -1345,6 +1339,12 @@ static int vim2m_probe(struct platform_d
+               goto error_dev;
+       }
++      ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
++      if (ret) {
++              v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
++              goto error_m2m;
++      }
++
+ #ifdef CONFIG_MEDIA_CONTROLLER
+       dev->mdev.dev = &pdev->dev;
+       strscpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
+@@ -1358,7 +1358,7 @@ static int vim2m_probe(struct platform_d
+                                                MEDIA_ENT_F_PROC_VIDEO_SCALER);
+       if (ret) {
+               v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller\n");
+-              goto error_dev;
++              goto error_v4l2;
+       }
+       ret = media_device_register(&dev->mdev);
+@@ -1373,11 +1373,13 @@ static int vim2m_probe(struct platform_d
+ error_m2m_mc:
+       v4l2_m2m_unregister_media_controller(dev->m2m_dev);
+ #endif
+-error_dev:
++error_v4l2:
+       video_unregister_device(&dev->vfd);
+       /* vim2m_device_release called by video_unregister_device to release various objects */
+       return ret;
+-error_v4l2:
++error_m2m:
++      v4l2_m2m_release(dev->m2m_dev);
++error_dev:
+       v4l2_device_unregister(&dev->v4l2_dev);
+ error_free:
+       kfree(dev);
diff --git a/queue-5.10/secure_seq-use-the-64-bits-of-the-siphash-for-port-offset-calculation.patch b/queue-5.10/secure_seq-use-the-64-bits-of-the-siphash-for-port-offset-calculation.patch
new file mode 100644 (file)
index 0000000..be94a0f
--- /dev/null
@@ -0,0 +1,139 @@
+From b2d057560b8107c633b39aabe517ff9d93f285e3 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Mon, 2 May 2022 10:46:08 +0200
+Subject: secure_seq: use the 64 bits of the siphash for port offset calculation
+
+From: Willy Tarreau <w@1wt.eu>
+
+commit b2d057560b8107c633b39aabe517ff9d93f285e3 upstream.
+
+SipHash replaced MD5 in secure_ipv{4,6}_port_ephemeral() via commit
+7cd23e5300c1 ("secure_seq: use SipHash in place of MD5"), but the output
+remained truncated to 32-bit only. In order to exploit more bits from the
+hash, let's make the functions return the full 64-bit of siphash_3u32().
+We also make sure the port offset calculation in __inet_hash_connect()
+remains done on 32-bit to avoid the need for div_u64_rem() and an extra
+cost on 32-bit systems.
+
+Cc: Jason A. Donenfeld <Jason@zx2c4.com>
+Cc: Moshe Kol <moshe.kol@mail.huji.ac.il>
+Cc: Yossi Gilad <yossi.gilad@mail.huji.ac.il>
+Cc: Amit Klein <aksecurity@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[SG: Adjusted context]
+Signed-off-by: Stefan Ghinea <stefan.ghinea@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/inet_hashtables.h |    2 +-
+ include/net/secure_seq.h      |    4 ++--
+ net/core/secure_seq.c         |    4 ++--
+ net/ipv4/inet_hashtables.c    |   10 ++++++----
+ net/ipv6/inet6_hashtables.c   |    4 ++--
+ 5 files changed, 13 insertions(+), 11 deletions(-)
+
+--- a/include/net/inet_hashtables.h
++++ b/include/net/inet_hashtables.h
+@@ -419,7 +419,7 @@ static inline void sk_rcv_saddr_set(stru
+ }
+ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+-                      struct sock *sk, u32 port_offset,
++                      struct sock *sk, u64 port_offset,
+                       int (*check_established)(struct inet_timewait_death_row *,
+                                                struct sock *, __u16,
+                                                struct inet_timewait_sock **));
+--- a/include/net/secure_seq.h
++++ b/include/net/secure_seq.h
+@@ -4,8 +4,8 @@
+ #include <linux/types.h>
+-u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
+-u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
++u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
++u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
+                              __be16 dport);
+ u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
+                  __be16 sport, __be16 dport);
+--- a/net/core/secure_seq.c
++++ b/net/core/secure_seq.c
+@@ -96,7 +96,7 @@ u32 secure_tcpv6_seq(const __be32 *saddr
+ }
+ EXPORT_SYMBOL(secure_tcpv6_seq);
+-u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
++u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
+                              __be16 dport)
+ {
+       const struct {
+@@ -146,7 +146,7 @@ u32 secure_tcp_seq(__be32 saddr, __be32
+ }
+ EXPORT_SYMBOL_GPL(secure_tcp_seq);
+-u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
++u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
+ {
+       net_secret_init();
+       return siphash_4u32((__force u32)saddr, (__force u32)daddr,
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -504,7 +504,7 @@ not_unique:
+       return -EADDRNOTAVAIL;
+ }
+-static u32 inet_sk_port_offset(const struct sock *sk)
++static u64 inet_sk_port_offset(const struct sock *sk)
+ {
+       const struct inet_sock *inet = inet_sk(sk);
+@@ -734,7 +734,7 @@ EXPORT_SYMBOL_GPL(inet_unhash);
+ static u32 table_perturb[1 << INET_TABLE_PERTURB_SHIFT];
+ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+-              struct sock *sk, u32 port_offset,
++              struct sock *sk, u64 port_offset,
+               int (*check_established)(struct inet_timewait_death_row *,
+                       struct sock *, __u16, struct inet_timewait_sock **))
+ {
+@@ -777,7 +777,9 @@ int __inet_hash_connect(struct inet_time
+       net_get_random_once(table_perturb, sizeof(table_perturb));
+       index = hash_32(port_offset, INET_TABLE_PERTURB_SHIFT);
+-      offset = (READ_ONCE(table_perturb[index]) + port_offset) % remaining;
++      offset = READ_ONCE(table_perturb[index]) + port_offset;
++      offset %= remaining;
++
+       /* In first pass we try ports of @low parity.
+        * inet_csk_get_port() does the opposite choice.
+        */
+@@ -854,7 +856,7 @@ ok:
+ int inet_hash_connect(struct inet_timewait_death_row *death_row,
+                     struct sock *sk)
+ {
+-      u32 port_offset = 0;
++      u64 port_offset = 0;
+       if (!inet_sk(sk)->inet_num)
+               port_offset = inet_sk_port_offset(sk);
+--- a/net/ipv6/inet6_hashtables.c
++++ b/net/ipv6/inet6_hashtables.c
+@@ -308,7 +308,7 @@ not_unique:
+       return -EADDRNOTAVAIL;
+ }
+-static u32 inet6_sk_port_offset(const struct sock *sk)
++static u64 inet6_sk_port_offset(const struct sock *sk)
+ {
+       const struct inet_sock *inet = inet_sk(sk);
+@@ -320,7 +320,7 @@ static u32 inet6_sk_port_offset(const st
+ int inet6_hash_connect(struct inet_timewait_death_row *death_row,
+                      struct sock *sk)
+ {
+-      u32 port_offset = 0;
++      u64 port_offset = 0;
+       if (!inet_sk(sk)->inet_num)
+               port_offset = inet6_sk_port_offset(sk);
index 06efea9e9d107f5c3c883447e87688af22d407ce..1ce760783ef99470ab48d59162cadc1b1827f01e 100644 (file)
@@ -2,3 +2,7 @@ lockdown-also-lock-down-previous-kgdb-use.patch
 staging-rtl8723bs-prevent-ssid-overflow-in-rtw_wx_set_scan.patch
 kvm-x86-properly-handle-apf-vs-disabled-lapic-situation.patch
 kvm-x86-mmu-fix-null-pointer-dereference-on-guest-invpcid.patch
+tcp-change-source-port-randomizarion-at-connect-time.patch
+secure_seq-use-the-64-bits-of-the-siphash-for-port-offset-calculation.patch
+media-vim2m-register-video-device-after-setting-up-internals.patch
+media-vim2m-initialize-the-media-device-earlier.patch
diff --git a/queue-5.10/tcp-change-source-port-randomizarion-at-connect-time.patch b/queue-5.10/tcp-change-source-port-randomizarion-at-connect-time.patch
new file mode 100644 (file)
index 0000000..d6a3784
--- /dev/null
@@ -0,0 +1,98 @@
+From 190cc82489f46f9d88e73c81a47e14f80a791e1a Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Tue, 9 Feb 2021 11:20:27 -0800
+Subject: tcp: change source port randomizarion at connect() time
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit 190cc82489f46f9d88e73c81a47e14f80a791e1a upstream.
+
+RFC 6056 (Recommendations for Transport-Protocol Port Randomization)
+provides good summary of why source selection needs extra care.
+
+David Dworken reminded us that linux implements Algorithm 3
+as described in RFC 6056 3.3.3
+
+Quoting David :
+   In the context of the web, this creates an interesting info leak where
+   websites can count how many TCP connections a user's computer is
+   establishing over time. For example, this allows a website to count
+   exactly how many subresources a third party website loaded.
+   This also allows:
+   - Distinguishing between different users behind a VPN based on
+       distinct source port ranges.
+   - Tracking users over time across multiple networks.
+   - Covert communication channels between different browsers/browser
+       profiles running on the same computer
+   - Tracking what applications are running on a computer based on
+       the pattern of how fast source ports are getting incremented.
+
+Section 3.3.4 describes an enhancement, that reduces
+attackers ability to use the basic information currently
+stored into the shared 'u32 hint'.
+
+This change also decreases collision rate when
+multiple applications need to connect() to
+different destinations.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: David Dworken <ddworken@google.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Stefan Ghinea <stefan.ghinea@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/inet_hashtables.c |   20 +++++++++++++++++---
+ 1 file changed, 17 insertions(+), 3 deletions(-)
+
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -722,6 +722,17 @@ void inet_unhash(struct sock *sk)
+ }
+ EXPORT_SYMBOL_GPL(inet_unhash);
++/* RFC 6056 3.3.4.  Algorithm 4: Double-Hash Port Selection Algorithm
++ * Note that we use 32bit integers (vs RFC 'short integers')
++ * because 2^16 is not a multiple of num_ephemeral and this
++ * property might be used by clever attacker.
++ * RFC claims using TABLE_LENGTH=10 buckets gives an improvement,
++ * we use 256 instead to really give more isolation and
++ * privacy, this only consumes 1 KB of kernel memory.
++ */
++#define INET_TABLE_PERTURB_SHIFT 8
++static u32 table_perturb[1 << INET_TABLE_PERTURB_SHIFT];
++
+ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+               struct sock *sk, u32 port_offset,
+               int (*check_established)(struct inet_timewait_death_row *,
+@@ -735,8 +746,8 @@ int __inet_hash_connect(struct inet_time
+       struct inet_bind_bucket *tb;
+       u32 remaining, offset;
+       int ret, i, low, high;
+-      static u32 hint;
+       int l3mdev;
++      u32 index;
+       if (port) {
+               head = &hinfo->bhash[inet_bhashfn(net, port,
+@@ -763,7 +774,10 @@ int __inet_hash_connect(struct inet_time
+       if (likely(remaining > 1))
+               remaining &= ~1U;
+-      offset = (hint + port_offset) % remaining;
++      net_get_random_once(table_perturb, sizeof(table_perturb));
++      index = hash_32(port_offset, INET_TABLE_PERTURB_SHIFT);
++
++      offset = (READ_ONCE(table_perturb[index]) + port_offset) % remaining;
+       /* In first pass we try ports of @low parity.
+        * inet_csk_get_port() does the opposite choice.
+        */
+@@ -817,7 +831,7 @@ next_port:
+       return -EADDRNOTAVAIL;
+ ok:
+-      hint += i + 2;
++      WRITE_ONCE(table_perturb[index], READ_ONCE(table_perturb[index]) + i + 2);
+       /* Head lock still held and bh's disabled */
+       inet_bind_hash(sk, tb, port);