Skip to content

filesystem: prevent panic on mount points with non-UTF-8 names#3687

Open
ricardbejarano wants to merge 2 commits into
prometheus:masterfrom
bejaratommy:fix-filesystem-nonutf8-panic
Open

filesystem: prevent panic on mount points with non-UTF-8 names#3687
ricardbejarano wants to merge 2 commits into
prometheus:masterfrom
bejaratommy:fix-filesystem-nonutf8-panic

Conversation

@ricardbejarano

Copy link
Copy Markdown

Summary

On Linux, mount paths are byte strings and are usually — but not always — valid UTF-8. When a filesystem is mounted on a path containing non-UTF-8 bytes, the filesystem collector passes that value straight to prometheus.MustNewConstMetric as a label value, which panics (Prometheus label values must be valid UTF-8). This crashes the whole scrape:

panic: label value "/mnt/cass\xe9" is not valid UTF-8
github.com/prometheus/client_golang/prometheus.MustNewConstMetric(...)
github.com/prometheus/node_exporter/collector.(*filesystemCollector).Update(...)

Fix

Sanitize the device, mountPoint and fsType labels with strings.ToValidUTF8(..., "�") in parseFilesystemLabels. This mirrors the approach already used elsewhere in the tree (hwmon, dmi, netclass, powersupply collectors and collector/utils), so invalid bytes are replaced with the Unicode replacement character instead of taking the exporter down.

A unit test covering non-UTF-8 device/mountPoint/fsType input is included.

Fixes #3662

Reproduce

fallocate -l 32m /root/disk.dd
mkfs -t ext2 /root/disk.dd
mount --mkdir /root/disk.dd /mnt/cass$'\xe9'
./node_exporter &
curl http://localhost:9100/metrics

On Linux, mount paths are byte strings and may contain non-UTF-8
sequences. Those values were passed straight through to
prometheus.MustNewConstMetric as label values, which panics because
Prometheus label values must be valid UTF-8, taking down the whole
scrape.

Sanitize the device, mountPoint and fsType labels with
strings.ToValidUTF8 when parsing /proc mounts, matching the approach
already used by the hwmon, dmi, netclass and powersupply collectors.

Signed-off-by: bejaratommy <tommy@bejara.net>
Signed-off-by: bejaratommy <tommy@bejara.net>

@rtreffer rtreffer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was able to reproduce on an older node_exporter for mount point and device by doing a loopback mount of a ext4 disk image. Both the image and mount point had non-utf8 names.

panic: label value "/media/cass\xe9" is not valid UTF-8

goroutine 89 [running]:
github.com/prometheus/client_golang/prometheus.MustNewConstMetric(...)
        github.com/prometheus/client_golang/prometheus/value.go:129
github.com/prometheus/node_exporter/collector.(*filesystemCollector).Update(0xc000246c40, 0xc0002956c0)
        github.com/prometheus/node_exporter/collector/filesystem_common.go:198 +0xb49
github.com/prometheus/node_exporter/collector.execute({0xcddee3, 0xa}, {0xe15280, 0xc000246c40}, 0xc0002956c0, 0xc0000491f0)
        github.com/prometheus/node_exporter/collector/collector.go:160 +0x85
github.com/prometheus/node_exporter/collector.NodeCollector.Collect.func1({0xcddee3?, 0x0?}, {0xe15280?, 0xc000246c40?})
        github.com/prometheus/node_exporter/collector/collector.go:151 +0x33
created by github.com/prometheus/node_exporter/collector.NodeCollector.Collect in goroutine 44
        github.com/prometheus/node_exporter/collector/collector.go:150 +0xce

This change aligns labels with the output of mount

/media/cass�/out.img on /media/cass� type ext2 (rw,relatime)

listmount indicates that all values can be byte strings.
I doubt that this is relevant for fsType but it does not harm to normalize all values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

filesystemCollector crash with non-utf8 mount point

3 participants