{
  "schema_version": "1.6.1",
  "id": "RPI-CVE-2025-68183",
  "modified": "2026-10-09T11:39:44Z",
  "upstream": [
    "CVE-2025-68183"
  ],
  "published": "2025-12-16T13:43:51Z",
  "summary": "ima: don't clear IMA_DIGSIG flag when setting or removing non-IMA xattr",
  "details": "In the Linux kernel, the following vulnerability has been resolved:\n\nima: don't clear IMA_DIGSIG flag when setting or removing non-IMA xattr\n\nCurrently when both IMA and EVM are in fix mode, the IMA signature will\nbe reset to IMA hash if a program first stores IMA signature in\nsecurity.ima and then writes/removes some other security xattr for the\nfile.\n\nFor example, on Fedora, after booting the kernel with \"ima_appraise=fix\nevm=fix ima_policy=appraise_tcb\" and installing rpm-plugin-ima,\ninstalling/reinstalling a package will not make good reference IMA\nsignature generated. Instead IMA hash is generated,\n\n    # getfattr -m - -d -e hex /usr/bin/bash\n    # file: usr/bin/bash\n    security.ima=0x0404...\n\nThis happens because when setting security.selinux, the IMA_DIGSIG flag\nthat had been set early was cleared. As a result, IMA hash is generated\nwhen the file is closed.\n\nSimilarly, IMA signature can be cleared on file close after removing\nsecurity xattr like security.evm or setting/removing ACL.\n\nPrevent replacing the IMA file signature with a file hash, by preventing\nthe IMA_DIGSIG flag from being reset.\n\nHere's a minimal C reproducer which sets security.selinux as the last\nstep which can also replaced by removing security.evm or setting ACL,\n\n    #include <stdio.h>\n    #include <sys/xattr.h>\n    #include <fcntl.h>\n    #include <unistd.h>\n    #include <string.h>\n    #include <stdlib.h>\n\n    int main() {\n        const char* file_path = \"/usr/sbin/test_binary\";\n        const char* hex_string = \"030204d33204490066306402304\";\n        int length = strlen(hex_string);\n        char* ima_attr_value;\n        int fd;\n\n        fd = open(file_path, O_WRONLY|O_CREAT|O_EXCL, 0644);\n        if (fd == -1) {\n            perror(\"Error opening file\");\n            return 1;\n        }\n\n        ima_attr_value = (char*)malloc(length / 2 );\n        for (int i = 0, j = 0; i < length; i += 2, j++) {\n            sscanf(hex_string + i, \"%2hhx\", &ima_attr_value[j]);\n        }\n\n        if (fsetxattr(fd, \"security.ima\", ima_attr_value, length/2, 0) == -1) {\n            perror(\"Error setting extended attribute\");\n            close(fd);\n            return 1;\n        }\n\n        const char* selinux_value= \"system_u:object_r:bin_t:s0\";\n        if (fsetxattr(fd, \"security.selinux\", selinux_value, strlen(selinux_value), 0) == -1) {\n            perror(\"Error setting extended attribute\");\n            close(fd);\n            return 1;\n        }\n\n        close(fd);\n\n        return 0;\n    }",
  "severity": [
    {
      "type": "CVSS_V3",
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
    }
  ],
  "affected": [
    {
      "package": {
        "ecosystem": "Raspberry Pi OS:12",
        "name": "linux"
      },
      "versions": [
        "1:6.1.47-1+rpt4"
      ],
      "ecosystem_specific": {
        "binaries": [
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-2712",
            "binary_version": "1:6.1.47-1+rpt4"
          },
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-v6",
            "binary_version": "1:6.1.47-1+rpt4"
          },
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-v7",
            "binary_version": "1:6.1.47-1+rpt4"
          },
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-v7l",
            "binary_version": "1:6.1.47-1+rpt4"
          },
          {
            "binary_name": "linux-image-6.1.0-rpi3-rpi-v8",
            "binary_version": "1:6.1.47-1+rpt4"
          }
        ]
      },
      "database_specific": {
        "per_version": {
          "1:6.1.47-1+rpt4": {
            "linux_commit": "655fc658a15ae7a6f37103754adb39ba52a9a14e",
            "upstream_version": "6.1.47",
            "assessment": "commit ancestry (strak rule)",
            "upstream_fixed": null,
            "compiled_filter": false
          }
        }
      }
    }
  ],
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://www.cve.org/CVERecord?id=CVE-2025-68183"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/d2993a7e98eb70c737c6f5365a190e79c72b8407"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/edd824eb45e4f7e05ad3ab090dab6dbdb79cd292"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/02aa671c08a4834bef5166743a7b88686fbfa023"
    },
    {
      "type": "FIX",
      "url": "https://git.kernel.org/stable/c/88b4cbcf6b041ae0f2fc8a34554a5b6a83a2b7cd"
    }
  ],
  "database_specific": {
    "source": "https://git.kernel.org/pub/scm/linux/security/vulns.git",
    "upstream_modified": "2026-08-05T12:19:11Z",
    "severity": {
      "source": "kernel CNA",
      "cvss_v3_score": 7.8,
      "cvss_v3_severity": "High",
      "scenario": "AV:L - Triggering requires local syscalls against a file on the system \u2014 `setxattr`/`fsetxattr` on an EVM-protected xattr, `setfacl`, or `fremovexattr` \u2014 followed by an open/close of the target file. No network, adjacent-network, or physical path reaches the IMA appraisal hooks.\nAC:L - The commit ships a deterministic reproducer: setting any EVM-protected xattr or a POSIX ACL unconditionally clears IMA_DIGSIG every time, with no memory-layout or timing luck involved. The enforce-mode variant needs a race against `process_measurement()`'s `MAY_WRITE` check, but `ima_reset_appraise_flags()` takes no `iint->mutex`, and the attacker drives both sides (one thread spinning on `setxattr(\"system.posix_acl_access\")`, another on `open(O_WRONLY)`); the required IMA-appraise + EVM configuration is a shipped, supported Fedora/RHEL setup, not a rare build option.\nPR:L - `vfs_set_acl()` invokes `security_inode_set_acl()` \u2192 `ima_inode_set_acl()` \u2192 `ima_reset_appraise_flags(inode, 0)` before `set_posix_acl()` ever reaches its `inode_owner_or_capable()` check, so an unprivileged user with no capabilities and no ownership of the file clears the cached IMA_DIGSIG bit on any signed appraised binary \u2014 the syscall fails with -EPERM only after the flag is already gone. No CAP_SYS_ADMIN is needed for this path, unlike the `security.ima` path guarded by `ima_protect_xattr()`.\nUI:N - The attacker performs the xattr/ACL operation and the file open/close entirely from their own process; no victim must mount a filesystem, open a file, or take any other action for the IMA_DIGSIG flag to be cleared and the signature to be replaced.\nS:U - The defeated control (IMA appraisal) and the affected resources (files and their security xattrs) live in the same kernel security authority; no VM, hypervisor, IOMMU, or sandbox boundary is crossed.\nC:H - Clearing IMA_DIGSIG both drops the \"signed files cannot be opened for write\" enforcement at `ima_main.c:472` and lets `ima_update_xattr()` re-bless the modified content with a fresh hash plus EVM HMAC, so attacker-substituted content in an appraised executable passes appraisal and subsequently runs \u2014 typically in a privileged/service context \u2014 yielding full disclosure of data reachable by that code. This is the standard treatment of a code-integrity/signature-verification bypass; the bug itself contains no direct memory-read primitive.\nI:H - The file's IMA digital signature \u2014 the one integrity artifact a local attacker cannot forge, since it is verified against the trusted IMA keyring \u2014 is silently destroyed and replaced by a locally computed hash written through `__vfs_setxattr_noperm()`, which bypasses the `CAP_SYS_ADMIN` gate in `ima_protect_xattr()`. Combined with the lost write-block, this converts \"signed and immutable\" into \"mutable and re-blessed on close\", a complete integrity bypass of IMA appraisal for the affected file.\nA:H - Once a signature is replaced by a plain hash, any policy carrying IMA_DIGSIG_REQUIRED (`appraise_type=imasig`) rejects that file in enforce mode, so appraised binaries become permanently unexecutable \u2014 applied to system-critical files such as init, sshd, or libc consumers this denies service and can leave the system unbootable, and the corrupted xattr persists on disk until the file is re-signed out of band."
    }
  }
}
