about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--pkgs/applications/version-management/git/default.nix4
-rw-r--r--pkgs/development/libraries/glib/default.nix4
-rw-r--r--pkgs/development/libraries/glibc/2.38-master.patch.gzbin79225 -> 89075 bytes
-rw-r--r--pkgs/development/libraries/glibc/common.nix4
-rw-r--r--pkgs/development/libraries/tpm2-tss/default.nix4
-rw-r--r--pkgs/development/python-modules/aiohttp/3.8.6-CVE-2024-30251.patch665
-rw-r--r--pkgs/development/python-modules/aiohttp/default.nix1
-rw-r--r--pkgs/development/python-modules/django/4.nix16
-rw-r--r--pkgs/development/python-modules/python-jose/default.nix14
-rw-r--r--pkgs/os-specific/linux/util-linux/default.nix8
-rw-r--r--pkgs/servers/sql/postgresql/default.nix20
11 files changed, 715 insertions, 25 deletions
diff --git a/pkgs/applications/version-management/git/default.nix b/pkgs/applications/version-management/git/default.nix
index 1b92778e65ccb..3339575b7391b 100644
--- a/pkgs/applications/version-management/git/default.nix
+++ b/pkgs/applications/version-management/git/default.nix
@@ -29,7 +29,7 @@ assert sendEmailSupport -> perlSupport;
 assert svnSupport -> perlSupport;
 
 let
-  version = "2.42.0";
+  version = "2.42.2";
   svn = subversionClient.override { perlBindings = perlSupport; };
   gitwebPerlLibs = with perlPackages; [ CGI HTMLParser CGIFast FCGI FCGIProcManager HTMLTagCloud ];
 in
@@ -42,7 +42,7 @@ stdenv.mkDerivation (finalAttrs: {
 
   src = fetchurl {
     url = "https://www.kernel.org/pub/software/scm/git/git-${version}.tar.xz";
-    hash = "sha256-MnghDp/SmUuEhN1+Pd2eqLlA71IXDNtgbaqU2IfJOw0=";
+    hash = "sha256-R3/xAbahVqS88JyOh0KT6pvBr8vGvHo9b50KL0lwkEQ=";
   };
 
   outputs = [ "out" ] ++ lib.optional withManual "doc";
diff --git a/pkgs/development/libraries/glib/default.nix b/pkgs/development/libraries/glib/default.nix
index fa3936386ed97..5a9a07fdd2b15 100644
--- a/pkgs/development/libraries/glib/default.nix
+++ b/pkgs/development/libraries/glib/default.nix
@@ -50,11 +50,11 @@ in
 
 stdenv.mkDerivation (finalAttrs: {
   pname = "glib";
-  version = "2.78.4";
+  version = "2.78.6";
 
   src = fetchurl {
     url = "mirror://gnome/sources/glib/${lib.versions.majorMinor finalAttrs.version}/glib-${finalAttrs.version}.tar.xz";
-    sha256 = "sha256-JLjgZy3KEgzDLTlLzLhYROcy4E/nXRi7BXOy28dUj2M=";
+    sha256 = "sha256-JEhUZU3YLH68svjiRhVtKgXrnNGtB+16d5ZZtGAsn64=";
   };
 
   patches = lib.optionals stdenv.isDarwin [
diff --git a/pkgs/development/libraries/glibc/2.38-master.patch.gz b/pkgs/development/libraries/glibc/2.38-master.patch.gz
index 4b9fd43a54e35..3babd2f706dfa 100644
--- a/pkgs/development/libraries/glibc/2.38-master.patch.gz
+++ b/pkgs/development/libraries/glibc/2.38-master.patch.gz
Binary files differdiff --git a/pkgs/development/libraries/glibc/common.nix b/pkgs/development/libraries/glibc/common.nix
index 649b81980f10e..90d6e0fc1c29f 100644
--- a/pkgs/development/libraries/glibc/common.nix
+++ b/pkgs/development/libraries/glibc/common.nix
@@ -44,7 +44,7 @@
 
 let
   version = "2.38";
-  patchSuffix = "-66";
+  patchSuffix = "-77";
   sha256 = "sha256-+4KZiZiyspllRnvBtp0VLpwwfSzzAcnq+0VVt3DvP9I=";
 in
 
@@ -60,7 +60,7 @@ stdenv.mkDerivation ({
     [
       /* No tarballs for stable upstream branch, only https://sourceware.org/git/glibc.git and using git would complicate bootstrapping.
           $ git fetch --all -p && git checkout origin/release/2.38/master && git describe
-          glibc-2.38-66-ge1135387de
+          glibc-2.38-77-gf510d75ff7
           $ git show --minimal --reverse glibc-2.38.. | gzip -9n --rsyncable - > 2.38-master.patch.gz
 
          To compare the archive contents zdiff can be used.
diff --git a/pkgs/development/libraries/tpm2-tss/default.nix b/pkgs/development/libraries/tpm2-tss/default.nix
index 628f32a91c69d..d6bd6c94d27fe 100644
--- a/pkgs/development/libraries/tpm2-tss/default.nix
+++ b/pkgs/development/libraries/tpm2-tss/default.nix
@@ -15,13 +15,13 @@ in
 
 stdenv.mkDerivation rec {
   pname = "tpm2-tss";
-  version = "4.0.1";
+  version = "4.0.2";
 
   src = fetchFromGitHub {
     owner = "tpm2-software";
     repo = pname;
     rev = version;
-    sha256 = "sha256-75yiKVZrR1vcCwKp4tDO4A9JB0KDM0MXPJ1N85kAaRk=";
+    hash = "sha256-8JQxv0NPnUZCJsUAJ9J40GVfJs4nXyM1zRobL+h7gos=";
   };
 
   outputs = [ "out" "man" "dev" ];
diff --git a/pkgs/development/python-modules/aiohttp/3.8.6-CVE-2024-30251.patch b/pkgs/development/python-modules/aiohttp/3.8.6-CVE-2024-30251.patch
new file mode 100644
index 0000000000000..bc5cac9c47d03
--- /dev/null
+++ b/pkgs/development/python-modules/aiohttp/3.8.6-CVE-2024-30251.patch
@@ -0,0 +1,665 @@
+From 87893e51b9425487017b132a9ef11ecb32a1e36f Mon Sep 17 00:00:00 2001
+From: Sam Bull <git@sambull.org>
+Date: Sun, 7 Apr 2024 13:19:31 +0100
+Subject: [PATCH 1/3] Fix handling of multipart/form-data (#8280) (#8302)
+
+https://datatracker.ietf.org/doc/html/rfc7578
+(cherry picked from commit 7d0be3fee540a3d4161ac7dc76422f1f5ea60104)
+(cherry picked from commit cebe526b9c34dc3a3da9140409db63014bc4cf19)
+---
+ CHANGES/8280.bugfix.rst         |   1 +
+ CHANGES/8280.deprecation.rst    |   2 +
+ aiohttp/formdata.py             |  12 +++-
+ aiohttp/multipart.py            | 121 +++++++++++++++++++++-----------
+ tests/test_client_functional.py |  44 +-----------
+ tests/test_multipart.py         |  68 ++++++++++++++----
+ tests/test_web_functional.py    |  27 ++-----
+ 7 files changed, 155 insertions(+), 120 deletions(-)
+ create mode 100644 CHANGES/8280.bugfix.rst
+ create mode 100644 CHANGES/8280.deprecation.rst
+
+diff --git a/CHANGES/8280.bugfix.rst b/CHANGES/8280.bugfix.rst
+new file mode 100644
+index 00000000..3aebe36f
+--- /dev/null
++++ b/CHANGES/8280.bugfix.rst
+@@ -0,0 +1 @@
++Fixed ``multipart/form-data`` compliance with :rfc:`7578` -- by :user:`Dreamsorcerer`.
+diff --git a/CHANGES/8280.deprecation.rst b/CHANGES/8280.deprecation.rst
+new file mode 100644
+index 00000000..302dbb2f
+--- /dev/null
++++ b/CHANGES/8280.deprecation.rst
+@@ -0,0 +1,2 @@
++Deprecated ``content_transfer_encoding`` parameter in :py:meth:`FormData.add_field()
++<aiohttp.FormData.add_field>` -- by :user:`Dreamsorcerer`.
+diff --git a/aiohttp/formdata.py b/aiohttp/formdata.py
+index e7cd24ca..2b75b3de 100644
+--- a/aiohttp/formdata.py
++++ b/aiohttp/formdata.py
+@@ -1,4 +1,5 @@
+ import io
++import warnings
+ from typing import Any, Iterable, List, Optional
+ from urllib.parse import urlencode
+ 
+@@ -53,7 +54,12 @@ class FormData:
+         if isinstance(value, io.IOBase):
+             self._is_multipart = True
+         elif isinstance(value, (bytes, bytearray, memoryview)):
++            msg = (
++                "In v4, passing bytes will no longer create a file field. "
++                "Please explicitly use the filename parameter or pass a BytesIO object."
++            )
+             if filename is None and content_transfer_encoding is None:
++                warnings.warn(msg, DeprecationWarning)
+                 filename = name
+ 
+         type_options: MultiDict[str] = MultiDict({"name": name})
+@@ -81,7 +87,11 @@ class FormData:
+                     "content_transfer_encoding must be an instance"
+                     " of str. Got: %s" % content_transfer_encoding
+                 )
+-            headers[hdrs.CONTENT_TRANSFER_ENCODING] = content_transfer_encoding
++            msg = (
++                "content_transfer_encoding is deprecated. "
++                "To maintain compatibility with v4 please pass a BytesPayload."
++            )
++            warnings.warn(msg, DeprecationWarning)
+             self._is_multipart = True
+ 
+         self._fields.append((type_options, headers, value))
+diff --git a/aiohttp/multipart.py b/aiohttp/multipart.py
+index 73801f45..0e2e6f85 100644
+--- a/aiohttp/multipart.py
++++ b/aiohttp/multipart.py
+@@ -255,13 +255,22 @@ class BodyPartReader:
+     chunk_size = 8192
+ 
+     def __init__(
+-        self, boundary: bytes, headers: "CIMultiDictProxy[str]", content: StreamReader
++        self,
++        boundary: bytes,
++        headers: "CIMultiDictProxy[str]",
++        content: StreamReader,
++        *,
++        subtype: str = "mixed",
++        default_charset: Optional[str] = None,
+     ) -> None:
+         self.headers = headers
+         self._boundary = boundary
+         self._content = content
++        self._default_charset = default_charset
+         self._at_eof = False
+-        length = self.headers.get(CONTENT_LENGTH, None)
++        self._is_form_data = subtype == "form-data"
++        # https://datatracker.ietf.org/doc/html/rfc7578#section-4.8
++        length = None if self._is_form_data else self.headers.get(CONTENT_LENGTH, None)
+         self._length = int(length) if length is not None else None
+         self._read_bytes = 0
+         # TODO: typeing.Deque is not supported by Python 3.5
+@@ -329,6 +338,8 @@ class BodyPartReader:
+         assert self._length is not None, "Content-Length required for chunked read"
+         chunk_size = min(size, self._length - self._read_bytes)
+         chunk = await self._content.read(chunk_size)
++        if self._content.at_eof():
++            self._at_eof = True
+         return chunk
+ 
+     async def _read_chunk_from_stream(self, size: int) -> bytes:
+@@ -444,7 +455,8 @@ class BodyPartReader:
+         """
+         if CONTENT_TRANSFER_ENCODING in self.headers:
+             data = self._decode_content_transfer(data)
+-        if CONTENT_ENCODING in self.headers:
++        # https://datatracker.ietf.org/doc/html/rfc7578#section-4.8
++        if not self._is_form_data and CONTENT_ENCODING in self.headers:
+             return self._decode_content(data)
+         return data
+ 
+@@ -478,7 +490,7 @@ class BodyPartReader:
+         """Returns charset parameter from Content-Type header or default."""
+         ctype = self.headers.get(CONTENT_TYPE, "")
+         mimetype = parse_mimetype(ctype)
+-        return mimetype.parameters.get("charset", default)
++        return mimetype.parameters.get("charset", self._default_charset or default)
+ 
+     @reify
+     def name(self) -> Optional[str]:
+@@ -533,9 +545,17 @@ class MultipartReader:
+     part_reader_cls = BodyPartReader
+ 
+     def __init__(self, headers: Mapping[str, str], content: StreamReader) -> None:
++        self._mimetype = parse_mimetype(headers[CONTENT_TYPE])
++        assert self._mimetype.type == "multipart", "multipart/* content type expected"
++        if "boundary" not in self._mimetype.parameters:
++            raise ValueError(
++                "boundary missed for Content-Type: %s" % headers[CONTENT_TYPE]
++            )
++
+         self.headers = headers
+         self._boundary = ("--" + self._get_boundary()).encode()
+         self._content = content
++        self._default_charset: Optional[str] = None
+         self._last_part: Optional[Union["MultipartReader", BodyPartReader]] = None
+         self._at_eof = False
+         self._at_bof = True
+@@ -587,7 +607,24 @@ class MultipartReader:
+             await self._read_boundary()
+         if self._at_eof:  # we just read the last boundary, nothing to do there
+             return None
+-        self._last_part = await self.fetch_next_part()
++
++        part = await self.fetch_next_part()
++        # https://datatracker.ietf.org/doc/html/rfc7578#section-4.6
++        if (
++            self._last_part is None
++            and self._mimetype.subtype == "form-data"
++            and isinstance(part, BodyPartReader)
++        ):
++            _, params = parse_content_disposition(part.headers.get(CONTENT_DISPOSITION))
++            if params.get("name") == "_charset_":
++                # Longest encoding in https://encoding.spec.whatwg.org/encodings.json
++                # is 19 characters, so 32 should be more than enough for any valid encoding.
++                charset = await part.read_chunk(32)
++                if len(charset) > 31:
++                    raise RuntimeError("Invalid default charset")
++                self._default_charset = charset.strip().decode()
++                part = await self.fetch_next_part()
++        self._last_part = part
+         return self._last_part
+ 
+     async def release(self) -> None:
+@@ -623,19 +660,16 @@ class MultipartReader:
+                 return type(self)(headers, self._content)
+             return self.multipart_reader_cls(headers, self._content)
+         else:
+-            return self.part_reader_cls(self._boundary, headers, self._content)
+-
+-    def _get_boundary(self) -> str:
+-        mimetype = parse_mimetype(self.headers[CONTENT_TYPE])
+-
+-        assert mimetype.type == "multipart", "multipart/* content type expected"
+-
+-        if "boundary" not in mimetype.parameters:
+-            raise ValueError(
+-                "boundary missed for Content-Type: %s" % self.headers[CONTENT_TYPE]
++            return self.part_reader_cls(
++                self._boundary,
++                headers,
++                self._content,
++                subtype=self._mimetype.subtype,
++                default_charset=self._default_charset,
+             )
+ 
+-        boundary = mimetype.parameters["boundary"]
++    def _get_boundary(self) -> str:
++        boundary = self._mimetype.parameters["boundary"]
+         if len(boundary) > 70:
+             raise ValueError("boundary %r is too long (70 chars max)" % boundary)
+ 
+@@ -726,6 +760,7 @@ class MultipartWriter(Payload):
+         super().__init__(None, content_type=ctype)
+ 
+         self._parts: List[_Part] = []
++        self._is_form_data = subtype == "form-data"
+ 
+     def __enter__(self) -> "MultipartWriter":
+         return self
+@@ -803,32 +838,36 @@ class MultipartWriter(Payload):
+ 
+     def append_payload(self, payload: Payload) -> Payload:
+         """Adds a new body part to multipart writer."""
+-        # compression
+-        encoding: Optional[str] = payload.headers.get(
+-            CONTENT_ENCODING,
+-            "",
+-        ).lower()
+-        if encoding and encoding not in ("deflate", "gzip", "identity"):
+-            raise RuntimeError(f"unknown content encoding: {encoding}")
+-        if encoding == "identity":
+-            encoding = None
+-
+-        # te encoding
+-        te_encoding: Optional[str] = payload.headers.get(
+-            CONTENT_TRANSFER_ENCODING,
+-            "",
+-        ).lower()
+-        if te_encoding not in ("", "base64", "quoted-printable", "binary"):
+-            raise RuntimeError(
+-                "unknown content transfer encoding: {}" "".format(te_encoding)
++        encoding: Optional[str] = None
++        te_encoding: Optional[str] = None
++        if self._is_form_data:
++            # https://datatracker.ietf.org/doc/html/rfc7578#section-4.7
++            # https://datatracker.ietf.org/doc/html/rfc7578#section-4.8
++            assert CONTENT_DISPOSITION in payload.headers
++            assert "name=" in payload.headers[CONTENT_DISPOSITION]
++            assert (
++                not {CONTENT_ENCODING, CONTENT_LENGTH, CONTENT_TRANSFER_ENCODING}
++                & payload.headers.keys()
+             )
+-        if te_encoding == "binary":
+-            te_encoding = None
+-
+-        # size
+-        size = payload.size
+-        if size is not None and not (encoding or te_encoding):
+-            payload.headers[CONTENT_LENGTH] = str(size)
++        else:
++            # compression
++            encoding = payload.headers.get(CONTENT_ENCODING, "").lower()
++            if encoding and encoding not in ("deflate", "gzip", "identity"):
++                raise RuntimeError(f"unknown content encoding: {encoding}")
++            if encoding == "identity":
++                encoding = None
++
++            # te encoding
++            te_encoding = payload.headers.get(CONTENT_TRANSFER_ENCODING, "").lower()
++            if te_encoding not in ("", "base64", "quoted-printable", "binary"):
++                raise RuntimeError(f"unknown content transfer encoding: {te_encoding}")
++            if te_encoding == "binary":
++                te_encoding = None
++
++            # size
++            size = payload.size
++            if size is not None and not (encoding or te_encoding):
++                payload.headers[CONTENT_LENGTH] = str(size)
+ 
+         self._parts.append((payload, encoding, te_encoding))  # type: ignore[arg-type]
+         return payload
+diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py
+index 4f62b479..8801423b 100644
+--- a/tests/test_client_functional.py
++++ b/tests/test_client_functional.py
+@@ -1158,48 +1158,6 @@ async def test_POST_DATA_with_charset_post(aiohttp_client) -> None:
+     resp.close()
+ 
+ 
+-async def test_POST_DATA_with_context_transfer_encoding(aiohttp_client) -> None:
+-    async def handler(request):
+-        data = await request.post()
+-        assert data["name"] == "text"
+-        return web.Response(text=data["name"])
+-
+-    app = web.Application()
+-    app.router.add_post("/", handler)
+-    client = await aiohttp_client(app)
+-
+-    form = aiohttp.FormData()
+-    form.add_field("name", "text", content_transfer_encoding="base64")
+-
+-    resp = await client.post("/", data=form)
+-    assert 200 == resp.status
+-    content = await resp.text()
+-    assert content == "text"
+-    resp.close()
+-
+-
+-async def test_POST_DATA_with_content_type_context_transfer_encoding(aiohttp_client):
+-    async def handler(request):
+-        data = await request.post()
+-        assert data["name"] == "text"
+-        return web.Response(body=data["name"])
+-
+-    app = web.Application()
+-    app.router.add_post("/", handler)
+-    client = await aiohttp_client(app)
+-
+-    form = aiohttp.FormData()
+-    form.add_field(
+-        "name", "text", content_type="text/plain", content_transfer_encoding="base64"
+-    )
+-
+-    resp = await client.post("/", data=form)
+-    assert 200 == resp.status
+-    content = await resp.text()
+-    assert content == "text"
+-    resp.close()
+-
+-
+ async def test_POST_MultiDict(aiohttp_client) -> None:
+     async def handler(request):
+         data = await request.post()
+@@ -1249,7 +1207,7 @@ async def test_POST_FILES(aiohttp_client, fname) -> None:
+     client = await aiohttp_client(app)
+ 
+     with fname.open("rb") as f:
+-        resp = await client.post("/", data={"some": f, "test": b"data"}, chunked=True)
++        resp = await client.post("/", data={"some": f, "test": io.BytesIO(b"data")}, chunked=True)
+         assert 200 == resp.status
+         resp.close()
+ 
+diff --git a/tests/test_multipart.py b/tests/test_multipart.py
+index cc3f5ff7..68f5ab9e 100644
+--- a/tests/test_multipart.py
++++ b/tests/test_multipart.py
+@@ -942,6 +942,58 @@ class TestMultipartReader:
+             assert first.at_eof()
+             assert not second.at_eof()
+ 
++    async def test_read_form_default_encoding(self) -> None:
++        with Stream(
++            b"--:\r\n"
++            b'Content-Disposition: form-data; name="_charset_"\r\n\r\n'
++            b"ascii"
++            b"\r\n"
++            b"--:\r\n"
++            b'Content-Disposition: form-data; name="field1"\r\n\r\n'
++            b"foo"
++            b"\r\n"
++            b"--:\r\n"
++            b"Content-Type: text/plain;charset=UTF-8\r\n"
++            b'Content-Disposition: form-data; name="field2"\r\n\r\n'
++            b"foo"
++            b"\r\n"
++            b"--:\r\n"
++            b'Content-Disposition: form-data; name="field3"\r\n\r\n'
++            b"foo"
++            b"\r\n"
++        ) as stream:
++            reader = aiohttp.MultipartReader(
++                {CONTENT_TYPE: 'multipart/form-data;boundary=":"'},
++                stream,
++            )
++            field1 = await reader.next()
++            assert field1.name == "field1"
++            assert field1.get_charset("default") == "ascii"
++            field2 = await reader.next()
++            assert field2.name == "field2"
++            assert field2.get_charset("default") == "UTF-8"
++            field3 = await reader.next()
++            assert field3.name == "field3"
++            assert field3.get_charset("default") == "ascii"
++
++    async def test_read_form_invalid_default_encoding(self) -> None:
++        with Stream(
++            b"--:\r\n"
++            b'Content-Disposition: form-data; name="_charset_"\r\n\r\n'
++            b"this-value-is-too-long-to-be-a-charset"
++            b"\r\n"
++            b"--:\r\n"
++            b'Content-Disposition: form-data; name="field1"\r\n\r\n'
++            b"foo"
++            b"\r\n"
++        ) as stream:
++            reader = aiohttp.MultipartReader(
++                {CONTENT_TYPE: 'multipart/form-data;boundary=":"'},
++                stream,
++            )
++            with pytest.raises(RuntimeError, match="Invalid default charset"):
++                await reader.next()
++
+ 
+ async def test_writer(writer) -> None:
+     assert writer.size == 7
+@@ -1278,7 +1330,6 @@ class TestMultipartWriter:
+                         CONTENT_TYPE: "text/python",
+                     },
+                 )
+-            content_length = part.size
+             await writer.write(stream)
+ 
+         assert part.headers[CONTENT_TYPE] == "text/python"
+@@ -1289,9 +1340,7 @@ class TestMultipartWriter:
+         assert headers == (
+             b"--:\r\n"
+             b"Content-Type: text/python\r\n"
+-            b'Content-Disposition: attachments; filename="bug.py"\r\n'
+-            b"Content-Length: %s"
+-            b"" % (str(content_length).encode(),)
++            b'Content-Disposition: attachments; filename="bug.py"'
+         )
+ 
+     async def test_set_content_disposition_override(self, buf, stream):
+@@ -1305,7 +1354,6 @@ class TestMultipartWriter:
+                         CONTENT_TYPE: "text/python",
+                     },
+                 )
+-            content_length = part.size
+             await writer.write(stream)
+ 
+         assert part.headers[CONTENT_TYPE] == "text/python"
+@@ -1316,9 +1364,7 @@ class TestMultipartWriter:
+         assert headers == (
+             b"--:\r\n"
+             b"Content-Type: text/python\r\n"
+-            b'Content-Disposition: attachments; filename="bug.py"\r\n'
+-            b"Content-Length: %s"
+-            b"" % (str(content_length).encode(),)
++            b'Content-Disposition: attachments; filename="bug.py"'
+         )
+ 
+     async def test_reset_content_disposition_header(self, buf, stream):
+@@ -1330,8 +1376,6 @@ class TestMultipartWriter:
+                     headers={CONTENT_TYPE: "text/plain"},
+                 )
+ 
+-            content_length = part.size
+-
+             assert CONTENT_DISPOSITION in part.headers
+ 
+             part.set_content_disposition("attachments", filename="bug.py")
+@@ -1344,9 +1388,7 @@ class TestMultipartWriter:
+             b"--:\r\n"
+             b"Content-Type: text/plain\r\n"
+             b"Content-Disposition:"
+-            b' attachments; filename="bug.py"\r\n'
+-            b"Content-Length: %s"
+-            b"" % (str(content_length).encode(),)
++            b' attachments; filename="bug.py"'
+         )
+ 
+ 
+diff --git a/tests/test_web_functional.py b/tests/test_web_functional.py
+index 5fdfb234..61739e95 100644
+--- a/tests/test_web_functional.py
++++ b/tests/test_web_functional.py
+@@ -34,7 +34,8 @@ def fname(here):
+ 
+ def new_dummy_form():
+     form = FormData()
+-    form.add_field("name", b"123", content_transfer_encoding="base64")
++    with pytest.warns(DeprecationWarning, match="BytesPayload"):
++        form.add_field("name", b"123", content_transfer_encoding="base64")
+     return form
+ 
+ 
+@@ -429,25 +430,6 @@ async def test_release_post_data(aiohttp_client) -> None:
+     await resp.release()
+ 
+ 
+-async def test_POST_DATA_with_content_transfer_encoding(aiohttp_client) -> None:
+-    async def handler(request):
+-        data = await request.post()
+-        assert b"123" == data["name"]
+-        return web.Response()
+-
+-    app = web.Application()
+-    app.router.add_post("/", handler)
+-    client = await aiohttp_client(app)
+-
+-    form = FormData()
+-    form.add_field("name", b"123", content_transfer_encoding="base64")
+-
+-    resp = await client.post("/", data=form)
+-    assert 200 == resp.status
+-
+-    await resp.release()
+-
+-
+ async def test_post_form_with_duplicate_keys(aiohttp_client) -> None:
+     async def handler(request):
+         data = await request.post()
+@@ -505,7 +487,8 @@ async def test_100_continue(aiohttp_client) -> None:
+         return web.Response()
+ 
+     form = FormData()
+-    form.add_field("name", b"123", content_transfer_encoding="base64")
++    with pytest.warns(DeprecationWarning, match="BytesPayload"):
++        form.add_field("name", b"123", content_transfer_encoding="base64")
+ 
+     app = web.Application()
+     app.router.add_post("/", handler)
+@@ -683,7 +666,7 @@ async def test_upload_file(aiohttp_client) -> None:
+     app.router.add_post("/", handler)
+     client = await aiohttp_client(app)
+ 
+-    resp = await client.post("/", data={"file": data})
++    resp = await client.post("/", data={"file": io.BytesIO(data)})
+     assert 200 == resp.status
+ 
+     await resp.release()
+-- 
+2.45.0
+
+
+From 0d0a305762a9071933d95281a36a0c0dfdfff930 Mon Sep 17 00:00:00 2001
+From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com>
+Date: Mon, 15 Apr 2024 20:47:19 +0100
+Subject: [PATCH 2/3] [PR #8332/482e6cdf backport][3.9] Add
+ set_content_disposition test (#8333)
+
+**This is a backport of PR #8332 as merged into master
+(482e6cdf6516607360666a48c5828d3dbe959fbd).**
+
+Co-authored-by: Oleg A <t0rr@mail.ru>
+(cherry picked from commit 7eecdff163ccf029fbb1ddc9de4169d4aaeb6597)
+---
+ CHANGES/8332.bugfix.rst | 1 +
+ aiohttp/multipart.py    | 7 +++++--
+ tests/test_multipart.py | 7 +++++++
+ 3 files changed, 13 insertions(+), 2 deletions(-)
+ create mode 100644 CHANGES/8332.bugfix.rst
+
+diff --git a/CHANGES/8332.bugfix.rst b/CHANGES/8332.bugfix.rst
+new file mode 100644
+index 00000000..70cad26b
+--- /dev/null
++++ b/CHANGES/8332.bugfix.rst
+@@ -0,0 +1 @@
++Fixed regression with adding Content-Disposition to form-data part after appending to writer -- by :user:`Dreamsorcerer`/:user:`Olegt0rr`.
+diff --git a/aiohttp/multipart.py b/aiohttp/multipart.py
+index 0e2e6f85..e59e0a68 100644
+--- a/aiohttp/multipart.py
++++ b/aiohttp/multipart.py
+@@ -843,8 +843,6 @@ class MultipartWriter(Payload):
+         if self._is_form_data:
+             # https://datatracker.ietf.org/doc/html/rfc7578#section-4.7
+             # https://datatracker.ietf.org/doc/html/rfc7578#section-4.8
+-            assert CONTENT_DISPOSITION in payload.headers
+-            assert "name=" in payload.headers[CONTENT_DISPOSITION]
+             assert (
+                 not {CONTENT_ENCODING, CONTENT_LENGTH, CONTENT_TRANSFER_ENCODING}
+                 & payload.headers.keys()
+@@ -925,6 +923,11 @@ class MultipartWriter(Payload):
+     async def write(self, writer: Any, close_boundary: bool = True) -> None:
+         """Write body."""
+         for part, encoding, te_encoding in self._parts:
++            if self._is_form_data:
++                # https://datatracker.ietf.org/doc/html/rfc7578#section-4.2
++                assert CONTENT_DISPOSITION in part.headers
++                assert "name=" in part.headers[CONTENT_DISPOSITION]
++
+             await writer.write(b"--" + self._boundary + b"\r\n")
+             await writer.write(part._binary_headers)
+ 
+diff --git a/tests/test_multipart.py b/tests/test_multipart.py
+index 68f5ab9e..08279e49 100644
+--- a/tests/test_multipart.py
++++ b/tests/test_multipart.py
+@@ -1280,6 +1280,13 @@ class TestMultipartWriter:
+         part = writer._parts[0][0]
+         assert part.headers[CONTENT_TYPE] == "test/passed"
+ 
++    async def test_set_content_disposition_after_append(self):
++        writer = aiohttp.MultipartWriter("form-data")
++        payload = writer.append("some-data")
++        payload.set_content_disposition("form-data", name="method")
++        assert CONTENT_DISPOSITION in payload.headers
++        assert "name=" in payload.headers[CONTENT_DISPOSITION]
++
+     def test_with(self) -> None:
+         with aiohttp.MultipartWriter(boundary=":") as writer:
+             writer.append("foo")
+-- 
+2.45.0
+
+
+From b5f94118ff3f0d3711d85b8089fd46f1d5e87e4d Mon Sep 17 00:00:00 2001
+From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com>
+Date: Mon, 15 Apr 2024 21:54:12 +0100
+Subject: [PATCH 3/3] [PR #8335/5a6949da backport][3.9] Add Content-Disposition
+ automatically (#8336)
+
+**This is a backport of PR #8335 as merged into master
+(5a6949da642d1db6cf414fd0d1f70e54c7b7be14).**
+
+Co-authored-by: Sam Bull <git@sambull.org>
+(cherry picked from commit f21c6f2ca512a026ce7f0f6c6311f62d6a638866)
+---
+ CHANGES/8335.bugfix.rst |  1 +
+ aiohttp/multipart.py    |  4 ++++
+ tests/test_multipart.py | 22 +++++++++++++++++-----
+ 3 files changed, 22 insertions(+), 5 deletions(-)
+ create mode 100644 CHANGES/8335.bugfix.rst
+
+diff --git a/CHANGES/8335.bugfix.rst b/CHANGES/8335.bugfix.rst
+new file mode 100644
+index 00000000..cd93b864
+--- /dev/null
++++ b/CHANGES/8335.bugfix.rst
+@@ -0,0 +1 @@
++Added default Content-Disposition in multipart/form-data responses -- by :user:`Dreamsorcerer`.
+diff --git a/aiohttp/multipart.py b/aiohttp/multipart.py
+index e59e0a68..9cd49bb5 100644
+--- a/aiohttp/multipart.py
++++ b/aiohttp/multipart.py
+@@ -847,6 +847,10 @@ class MultipartWriter(Payload):
+                 not {CONTENT_ENCODING, CONTENT_LENGTH, CONTENT_TRANSFER_ENCODING}
+                 & payload.headers.keys()
+             )
++            # Set default Content-Disposition in case user doesn't create one
++            if CONTENT_DISPOSITION not in payload.headers:
++                name = f"section-{len(self._parts)}"
++                payload.set_content_disposition("form-data", name=name)
+         else:
+             # compression
+             encoding = payload.headers.get(CONTENT_ENCODING, "").lower()
+diff --git a/tests/test_multipart.py b/tests/test_multipart.py
+index 08279e49..1d036fbe 100644
+--- a/tests/test_multipart.py
++++ b/tests/test_multipart.py
+@@ -1280,12 +1280,24 @@ class TestMultipartWriter:
+         part = writer._parts[0][0]
+         assert part.headers[CONTENT_TYPE] == "test/passed"
+ 
+-    async def test_set_content_disposition_after_append(self):
++    def test_set_content_disposition_after_append(self):
+         writer = aiohttp.MultipartWriter("form-data")
+-        payload = writer.append("some-data")
+-        payload.set_content_disposition("form-data", name="method")
+-        assert CONTENT_DISPOSITION in payload.headers
+-        assert "name=" in payload.headers[CONTENT_DISPOSITION]
++        part = writer.append("some-data")
++        part.set_content_disposition("form-data", name="method")
++        assert 'name="method"' in part.headers[CONTENT_DISPOSITION]
++
++    def test_automatic_content_disposition(self):
++        writer = aiohttp.MultipartWriter("form-data")
++        writer.append_json(())
++        part = payload.StringPayload("foo")
++        part.set_content_disposition("form-data", name="second")
++        writer.append_payload(part)
++        writer.append("foo")
++
++        disps = tuple(p[0].headers[CONTENT_DISPOSITION] for p in writer._parts)
++        assert 'name="section-0"' in disps[0]
++        assert 'name="second"' in disps[1]
++        assert 'name="section-2"' in disps[2]
+ 
+     def test_with(self) -> None:
+         with aiohttp.MultipartWriter(boundary=":") as writer:
+-- 
+2.45.0
+
diff --git a/pkgs/development/python-modules/aiohttp/default.nix b/pkgs/development/python-modules/aiohttp/default.nix
index 75d2421c56b0b..c5cd90264082f 100644
--- a/pkgs/development/python-modules/aiohttp/default.nix
+++ b/pkgs/development/python-modules/aiohttp/default.nix
@@ -49,6 +49,7 @@ buildPythonPackage rec {
       hash = "sha256-ZzhlE50bmA+e2XX2RH1FuWQHZIAa6Dk/hZjxPoX5t4g=";
     })
     ./3.8.6-CVE-2024-23334.patch
+    ./3.8.6-CVE-2024-30251.patch
   ];
 
   postPatch = ''
diff --git a/pkgs/development/python-modules/django/4.nix b/pkgs/development/python-modules/django/4.nix
index 65ebba3aa857f..0c69a72370db3 100644
--- a/pkgs/development/python-modules/django/4.nix
+++ b/pkgs/development/python-modules/django/4.nix
@@ -1,7 +1,8 @@
 { lib
 , stdenv
 , buildPythonPackage
-, fetchPypi
+, fetchFromGitHub
+, pythonAtLeast
 , pythonOlder
 , substituteAll
 
@@ -41,15 +42,17 @@
 }:
 
 buildPythonPackage rec {
-  pname = "Django";
-  version = "4.2.11";
+  pname = "django";
+  version = "4.2.12";
   format = "pyproject";
 
   disabled = pythonOlder "3.10";
 
-  src = fetchPypi {
-    inherit pname version;
-    hash = "sha256-bm/z2y2N0MmGtO7IVUyOT5GbXB/2KltDkMF6/y7W5cQ=";
+  src = fetchFromGitHub {
+    owner = "django";
+    repo = "django";
+    rev = "refs/tags/${version}";
+    hash = "sha256-n6esWUpZpCP4J4bNckNKJ9E61qFjTPS7XF+WgxNS2JE=";
   };
 
   patches = [
@@ -60,6 +63,7 @@ buildPythonPackage rec {
     # make sure the tests don't remove packages from our pythonpath
     # and disable failing tests
     ./django_4_tests.patch
+
   ] ++ lib.optionals withGdal [
     (substituteAll {
       src = ./django_4_set_geos_gdal_lib.patch;
diff --git a/pkgs/development/python-modules/python-jose/default.nix b/pkgs/development/python-modules/python-jose/default.nix
index 6e3f406fe5a30..edd545b3511c5 100644
--- a/pkgs/development/python-modules/python-jose/default.nix
+++ b/pkgs/development/python-modules/python-jose/default.nix
@@ -1,6 +1,7 @@
 { lib
 , buildPythonPackage
 , fetchFromGitHub
+, fetchpatch
 
 # build-system
 , setuptools
@@ -31,6 +32,19 @@ buildPythonPackage rec {
     hash = "sha256-6VGC6M5oyGCOiXcYp6mpyhL+JlcYZKIqOQU9Sm/TkKM=";
   };
 
+  patches = [
+    (fetchpatch {
+      name = "CVE-2024-33663.patch";
+      url  = "https://build.opensuse.org/public/source/openSUSE:Factory/python-python-jose/CVE-2024-33663.patch?rev=36cd8815411620042f56a3b81599b341";
+      hash = "sha256-uxOCa7Lg82zY2nuHzw6CbcymCKUodITrFU3lLY1XMFU=";
+    })
+    (fetchpatch {
+      name = "CVE-2024-33664.patch";
+      url  = "https://build.opensuse.org/public/source/openSUSE:Factory/python-python-jose/CVE-2024-33664.patch?rev=36cd8815411620042f56a3b81599b341";
+      hash = "sha256-wx/U1T7t7TloP+dMXxGxEVB3bMC7e6epmN8RE8FKksM=";
+    })
+  ];
+
   postPatch = ''
     substituteInPlace setup.py \
       --replace '"pytest-runner",' ""
diff --git a/pkgs/os-specific/linux/util-linux/default.nix b/pkgs/os-specific/linux/util-linux/default.nix
index d710fabb7ace0..58213e1947456 100644
--- a/pkgs/os-specific/linux/util-linux/default.nix
+++ b/pkgs/os-specific/linux/util-linux/default.nix
@@ -1,4 +1,4 @@
-{ lib, stdenv, fetchurl, pkg-config, zlib, shadow
+{ lib, stdenv, fetchurl, fetchpatch, pkg-config, zlib, shadow
 , capabilitiesSupport ? stdenv.isLinux
 , libcap_ng
 , libxcrypt
@@ -30,6 +30,12 @@ stdenv.mkDerivation rec {
   patches = [
     ./rtcwake-search-PATH-for-shutdown.patch
     ./bcachefs-patch-set.patch
+
+    (fetchpatch {
+      name = "CVE-2024-28085.patch";
+      url = "https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/patch/?id=f4f0782f66692112311659086fd552d40d7a6f59";
+      hash = "sha256-1OQ/FG/gCeGKF+FpeNABMuv+dLhMhFclTfk/vB3Y1N0=";
+    })
   ];
 
   # We separate some of the utilities into their own outputs. This
diff --git a/pkgs/servers/sql/postgresql/default.nix b/pkgs/servers/sql/postgresql/default.nix
index d3066474bbd69..e0469b0a2b845 100644
--- a/pkgs/servers/sql/postgresql/default.nix
+++ b/pkgs/servers/sql/postgresql/default.nix
@@ -346,45 +346,45 @@ let
 
   mkPackages = self: {
     postgresql_12 = self.callPackage generic {
-      version = "12.18";
+      version = "12.19";
       psqlSchema = "12";
-      hash = "sha256-T5kZcl2UHOmGjgf+HtHTqGdIWZtIM4ZUdYOSi3TDkYo=";
+      hash = "sha256-YX495Swi6CL09X0B1bIkBQPhmKnsyvWYqFEQm9GOb7s=";
       this = self.postgresql_12;
       thisAttr = "postgresql_12";
       inherit self;
     };
 
     postgresql_13 = self.callPackage generic {
-      version = "13.14";
+      version = "13.15";
       psqlSchema = "13";
-      hash = "sha256-uN8HhVGJiWC9UA3F04oXfpkFN234H+fytmChQH+mpe0=";
+      hash = "sha256-Qu3UFURtM7jCQr520a0FdTGyJksuhpOTObcHXG5OySU=";
       this = self.postgresql_13;
       thisAttr = "postgresql_13";
       inherit self;
     };
 
     postgresql_14 = self.callPackage generic {
-      version = "14.11";
+      version = "14.12";
       psqlSchema = "14";
-      hash = "sha256-pnC9fc4i3K1Cl7JhE2s7HUoJpvVBcZViqhTKY78paKg=";
+      hash = "sha256-YRjQj53cwb2Dzyt8x007WDvc7C835iRaisADuPqoCSM=";
       this = self.postgresql_14;
       thisAttr = "postgresql_14";
       inherit self;
     };
 
     postgresql_15 = self.callPackage generic {
-      version = "15.6";
+      version = "15.7";
       psqlSchema = "15";
-      hash = "sha256-hFUUbtnGnJOlfelUrq0DAsr60DXCskIXXWqh4X68svs=";
+      hash = "sha256-pG/klIWrY4Xjnau7tlT10wSSBvds1pXiJCaHKVIJmPc=";
       this = self.postgresql_15;
       thisAttr = "postgresql_15";
       inherit self;
     };
 
     postgresql_16 = self.callPackage generic {
-      version = "16.2";
+      version = "16.3";
       psqlSchema = "16";
-      hash = "sha256-RG6IKU28LJCFq0twYaZG+mBLS+wDUh1epnHC5a2bKVI=";
+      hash = "sha256-Mxlj1dPcTK9CFqBJ+kC2bWvLjHMGFYWUEblRh2TmBYU=";
       this = self.postgresql_16;
       thisAttr = "postgresql_16";
       inherit self;