Skip to content

Commit e1b26a9

Browse files
committed
collector/zfs: Prevent procfs integer underflow
Prevent integer underflow when parsing the `procfs` file as it used a `ParseUint` to parse signed values. Fixes: #2766 Signed-off-by: Pranshu Srivastava <[email protected]>
1 parent 32ac7f4 commit e1b26a9

File tree

4 files changed

+137
-100
lines changed

4 files changed

+137
-100
lines changed
Lines changed: 72 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,94 @@
11
6 1 0x01 91 4368 5266997922 97951858082072
22
name type data
3-
hits 4 8772612
4-
misses 4 604635
3+
anon_evictable_data 4 0
4+
anon_evictable_metadata 4 0
5+
anon_size 4 1917440
6+
arc_loaned_bytes 4 0
7+
arc_meta_limit 4 6275982336
8+
arc_meta_max 4 449286096
9+
arc_meta_min 4 16777216
10+
arc_meta_used 4 308103632
11+
arc_need_free 4 0
12+
arc_no_grow 4 0
13+
arc_prune 4 0
14+
arc_sys_free 4 261496832
15+
arc_tempreserve 4 0
16+
c 4 1643208777
17+
c_max 4 8367976448
18+
c_min 4 33554432
19+
data_size 4 1295836160
20+
deleted 4 60403
521
demand_data_hits 4 7221032
622
demand_data_misses 4 73300
723
demand_metadata_hits 4 1464353
824
demand_metadata_misses 4 498170
9-
prefetch_data_hits 4 3615
10-
prefetch_data_misses 4 17094
11-
prefetch_metadata_hits 4 83612
12-
prefetch_metadata_misses 4 16071
13-
mru_hits 4 855535
14-
mru_ghost_hits 4 21100
15-
mfu_hits 4 7829854
16-
mfu_ghost_hits 4 821
17-
deleted 4 60403
18-
mutex_miss 4 2
19-
evict_skip 4 2265729
20-
evict_not_enough 4 680
25+
duplicate_buffers 4 0
26+
duplicate_buffers_size 4 0
27+
duplicate_reads 4 0
2128
evict_l2_cached 4 0
2229
evict_l2_eligible 4 8992514560
2330
evict_l2_ineligible 4 992552448
2431
evict_l2_skip 4 0
32+
evict_not_enough 4 680
33+
evict_skip 4 2265729
34+
hash_chain_max 4 3
35+
hash_chains 4 412
36+
hash_collisions 4 50564
2537
hash_elements 4 42359
2638
hash_elements_max 4 88245
27-
hash_collisions 4 50564
28-
hash_chains 4 412
29-
hash_chain_max 4 3
30-
p 4 516395305
31-
c 4 1643208777
32-
c_min 4 33554432
33-
c_max 4 8367976448
34-
size 4 1603939792
3539
hdr_size 4 16361080
36-
data_size 4 1295836160
37-
metadata_size 4 175298560
38-
other_size 4 116443992
39-
anon_size 4 1917440
40-
anon_evictable_data 4 0
41-
anon_evictable_metadata 4 0
42-
mru_size 4 402593792
43-
mru_evictable_data 4 278091264
44-
mru_evictable_metadata 4 18606592
45-
mru_ghost_size 4 999728128
46-
mru_ghost_evictable_data 4 883765248
47-
mru_ghost_evictable_metadata 4 115962880
48-
mfu_size 4 1066623488
49-
mfu_evictable_data 4 1017613824
50-
mfu_evictable_metadata 4 9163776
51-
mfu_ghost_size 4 104936448
52-
mfu_ghost_evictable_data 4 96731136
53-
mfu_ghost_evictable_metadata 4 8205312
40+
hits 4 8772612
41+
l2_abort_lowmem 4 0
42+
l2_asize 4 0
43+
l2_cdata_free_on_write 4 0
44+
l2_cksum_bad 4 0
45+
l2_compress_failures 4 0
46+
l2_compress_successes 4 0
47+
l2_compress_zeros 4 0
48+
l2_evict_l1cached 4 0
49+
l2_evict_lock_retry 4 0
50+
l2_evict_reading 4 0
51+
l2_feeds 4 0
52+
l2_free_on_write 4 0
53+
l2_hdr_size 4 0
5454
l2_hits 4 0
55+
l2_io_error 4 0
5556
l2_misses 4 0
56-
l2_feeds 4 0
57-
l2_rw_clash 4 0
5857
l2_read_bytes 4 0
58+
l2_rw_clash 4 0
59+
l2_size 4 0
5960
l2_write_bytes 4 0
60-
l2_writes_sent 4 0
6161
l2_writes_done 4 0
6262
l2_writes_error 4 0
6363
l2_writes_lock_retry 4 0
64-
l2_evict_lock_retry 4 0
65-
l2_evict_reading 4 0
66-
l2_evict_l1cached 4 0
67-
l2_free_on_write 4 0
68-
l2_cdata_free_on_write 4 0
69-
l2_abort_lowmem 4 0
70-
l2_cksum_bad 4 0
71-
l2_io_error 4 0
72-
l2_size 4 0
73-
l2_asize 4 0
74-
l2_hdr_size 4 0
75-
l2_compress_successes 4 0
76-
l2_compress_zeros 4 0
77-
l2_compress_failures 4 0
78-
memory_throttle_count 4 0
79-
duplicate_buffers 4 0
80-
duplicate_buffers_size 4 0
81-
duplicate_reads 4 0
64+
l2_writes_sent 4 0
65+
memory_available_bytes 4 -922337203685477580
8266
memory_direct_count 4 542
8367
memory_indirect_count 4 3006
84-
arc_no_grow 4 0
85-
arc_tempreserve 4 0
86-
arc_loaned_bytes 4 0
87-
arc_prune 4 0
88-
arc_meta_used 4 308103632
89-
arc_meta_limit 4 6275982336
90-
arc_meta_max 4 449286096
91-
arc_meta_min 4 16777216
92-
arc_need_free 4 0
93-
arc_sys_free 4 261496832
68+
memory_throttle_count 4 0
69+
metadata_size 4 175298560
70+
mfu_evictable_data 4 1017613824
71+
mfu_evictable_metadata 4 9163776
72+
mfu_ghost_evictable_data 4 96731136
73+
mfu_ghost_evictable_metadata 4 8205312
74+
mfu_ghost_hits 4 821
75+
mfu_ghost_size 4 104936448
76+
mfu_hits 4 7829854
77+
mfu_size 4 1066623488
78+
misses 4 604635
79+
mru_evictable_data 4 278091264
80+
mru_evictable_metadata 4 18606592
81+
mru_ghost_evictable_data 4 883765248
82+
mru_ghost_evictable_metadata 4 115962880
83+
mru_ghost_hits 4 21100
84+
mru_ghost_size 4 999728128
85+
mru_hits 4 855535
86+
mru_size 4 402593792
87+
mutex_miss 4 2
88+
other_size 4 116443992
89+
p 4 516395305
90+
prefetch_data_hits 4 3615
91+
prefetch_data_misses 4 17094
92+
prefetch_metadata_hits 4 83612
93+
prefetch_metadata_misses 4 16071
94+
size 4 1603939792

collector/zfs.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,16 @@ func (s zfsSysctl) metricName() string {
9595
return strings.Replace(parts[len(parts)-1], "-", "_", -1)
9696
}
9797

98-
func (c *zfsCollector) constSysctlMetric(subsystem string, sysctl zfsSysctl, value uint64) prometheus.Metric {
98+
func (c *zfsCollector) constSysctlMetric(subsystem string, sysctl zfsSysctl, value interface{}) prometheus.Metric {
9999
metricName := sysctl.metricName()
100100

101+
var valueAsFloat64 float64
102+
switch v := value.(type) {
103+
case int64:
104+
valueAsFloat64 = float64(v)
105+
case uint64:
106+
valueAsFloat64 = float64(v)
107+
}
101108
return prometheus.MustNewConstMetric(
102109
prometheus.NewDesc(
103110
prometheus.BuildFQName(namespace, subsystem, metricName),
@@ -106,7 +113,7 @@ func (c *zfsCollector) constSysctlMetric(subsystem string, sysctl zfsSysctl, val
106113
nil,
107114
),
108115
prometheus.UntypedValue,
109-
float64(value),
116+
valueAsFloat64,
110117
)
111118
}
112119

collector/zfs_linux.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,15 @@ func (c *zfsCollector) updateZfsStats(subsystem string, ch chan<- prometheus.Met
6363
}
6464
defer file.Close()
6565

66-
return c.parseProcfsFile(file, c.linuxPathMap[subsystem], func(s zfsSysctl, v uint64) {
67-
ch <- c.constSysctlMetric(subsystem, s, v)
66+
return c.parseProcfsFile(file, c.linuxPathMap[subsystem], func(s zfsSysctl, v interface{}) {
67+
switch v := v.(type) {
68+
case uint64:
69+
ch <- c.constSysctlMetric(subsystem, s, v)
70+
case int64:
71+
ch <- c.constSysctlMetric(subsystem, s, v)
72+
default:
73+
level.Debug(c.logger).Log("msg", "Unknown type", "type", fmt.Sprintf("%T", v))
74+
}
6875
})
6976
}
7077

@@ -144,7 +151,7 @@ func (c *zfsCollector) updatePoolStats(ch chan<- prometheus.Metric) error {
144151
return nil
145152
}
146153

147-
func (c *zfsCollector) parseProcfsFile(reader io.Reader, fmtExt string, handler func(zfsSysctl, uint64)) error {
154+
func (c *zfsCollector) parseProcfsFile(reader io.Reader, fmtExt string, handler func(zfsSysctl, interface{})) error {
148155
scanner := bufio.NewScanner(reader)
149156

150157
parseLine := false
@@ -163,13 +170,20 @@ func (c *zfsCollector) parseProcfsFile(reader io.Reader, fmtExt string, handler
163170

164171
// kstat data type (column 2) should be KSTAT_DATA_UINT64, otherwise ignore
165172
// TODO: when other KSTAT_DATA_* types arrive, much of this will need to be restructured
166-
if parts[1] == kstatDataUint64 || parts[1] == kstatDataInt64 {
167-
key := fmt.Sprintf("kstat.zfs.misc.%s.%s", fmtExt, parts[0])
173+
key := fmt.Sprintf("kstat.zfs.misc.%s.%s", fmtExt, parts[0])
174+
switch parts[1] {
175+
case kstatDataUint64:
168176
value, err := strconv.ParseUint(parts[2], 10, 64)
169177
if err != nil {
170178
return fmt.Errorf("could not parse expected integer value for %q", key)
171179
}
172180
handler(zfsSysctl(key), value)
181+
case kstatDataInt64:
182+
value, err := strconv.ParseInt(parts[2], 10, 64)
183+
if err != nil {
184+
return fmt.Errorf("could not parse expected integer value for %q", key)
185+
}
186+
handler(zfsSysctl(key), value)
173187
}
174188
}
175189
if !parseLine {

0 commit comments

Comments
 (0)