Re: Security issue : 2021 commit to libblkid breaks existing string sanitization

Karel Zak <[email protected]> Mon, 15 Sep 2025 13:57:19 +0200
Newsgroups org.kernel.vger.util-linux
Message-ID <3ffdghfdus35xfk6r5tztxfy6f2soyjrg6j6g6d43nf55uwc6f@unu7kambgnbf>
Hi Richard,

-On Fri, Sep 12, 2025 at 06:33:36PM -0700, Richard Aplin wrote:
-> There was a 2021 commit to libblkid,
 > https://github.com/util-linux/util-linux/commit/6db368598962ea8b0329ae148ab878fd458f2533
> commit label "Optimize the blkid_safe_string() function"
> 
> This is potentially an unsafe change and may allow shell command injection.
 
I disagree. :-)

> 1. The shell command blkid has a mode "-o udev" which was designed to
> output information about block devices in a LABEL=VALUE format for
> consumption by shell scripts.

No, it's designed for use in udev rules where nothing is blindly evaluated or executed.

man blkid is pretty explicit:

udev
       print key="value" pairs for easy import into the udev environment; the keys
       are prefixed by ID_FS_ or ID_PART_ prefixes. The value may be modified to be
       safe for udev environment; allowed is plain ASCII, hex-escaping and valid
       UTF-8, everything else (including whitespaces) is replaced with '_'. The keys
       with _ENC postfix use hex-escaping for unsafe chars.

The _ENC variables keep only A-Za-z, "#+-.:=@_" from ASCII; this means
characters like "$()" are escaped.

> I have seen more than one instance (I
> am looking at one now in a commercial product) where userspace script
> has done:
> eval $(blkid -o udev ...)

Well, this is not a blkid issue; you need at least "| grep _ENC".

> 2. One of the fields returned by blkid (e.g. for a USB stick) is the
> volume label, which would be controllable by an attacker inserting a
> USB stick.
> The blkid 'udev' command code is aware of this danger and sanitizes
> the volume label and other attacker-controllable strings by calling
> the function
> blkid_safe_string(...)
> in libblkid.

It is safe for printing to a terminal, not for any random interpreter
like shell. There is also blkid_encode_string() for more restrictive
needs.

> 3. In previous versions of libblkid the blkid_safe_string function
> used to strip several dangerous ascii characters that would have
> allowed command injection (specifically; backtick, parenthesis, etc.
> It still allowed '$' which is a little dubious).

LABEL= and PARTLABEL= are used in config files, rules, etc., so the
goal is to keep them as unmodified as possible. If we introduce
changes in this area, some machines may fail to boot. It's better to
educate system admins not to blindly use "eval" when security matters.


Yes, I understand that users and admins want the installed system to
prevent all their mistakes instantly, but beyond a certain point it
affects usability.

We can add a note to the man page explicitly warning against using
eval $(blkid -o udev ...) to make it clearer for users.

    Karel