github.com/newrelic/go-agent@v3.26.0+incompatible/internal/sysinfo/bootid.go (about) 1 // Copyright 2020 New Relic Corporation. All rights reserved. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package sysinfo 5 6 import ( 7 "bytes" 8 "fmt" 9 "io/ioutil" 10 "runtime" 11 ) 12 13 // BootID returns the boot ID of the executing kernel. 14 func BootID() (string, error) { 15 if "linux" != runtime.GOOS { 16 return "", ErrFeatureUnsupported 17 } 18 data, err := ioutil.ReadFile("/proc/sys/kernel/random/boot_id") 19 if err != nil { 20 return "", err 21 } 22 23 return validateBootID(data) 24 } 25 26 type invalidBootID string 27 28 func (e invalidBootID) Error() string { 29 return fmt.Sprintf("Boot id has unrecognized format, id=%q", string(e)) 30 } 31 32 func isASCIIByte(b byte) bool { 33 return (b >= 0x20 && b <= 0x7f) 34 } 35 36 func validateBootID(data []byte) (string, error) { 37 // We're going to go for the permissive reading of 38 // https://source.datanerd.us/agents/agent-specs/blob/master/Utilization.md: 39 // any ASCII (excluding control characters, because I'm pretty sure that's not 40 // in the spirit of the spec) string will be sent up to and including 128 41 // bytes in length. 42 trunc := bytes.TrimSpace(data) 43 if len(trunc) > 128 { 44 trunc = trunc[:128] 45 } 46 for _, b := range trunc { 47 if !isASCIIByte(b) { 48 return "", invalidBootID(data) 49 } 50 } 51 52 return string(trunc), nil 53 }