github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/efivarfs/vars.go (about) 1 // Copyright 2022 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package efivarfs allows interaction with efivarfs of the 6 // linux kernel. 7 package efivarfs 8 9 import ( 10 "bytes" 11 "errors" 12 "fmt" 13 "strings" 14 15 guid "github.com/google/uuid" 16 ) 17 18 // VariableAttributes is an uint32 identifying the variables attributes. 19 type VariableAttributes uint32 20 21 const ( 22 // AttributeNonVolatile indicates a variable is non volatile. 23 AttributeNonVolatile VariableAttributes = 0x00000001 24 // AttributeBootserviceAccess indicates a variable is accessible during boot service. 25 AttributeBootserviceAccess VariableAttributes = 0x00000002 26 // AttributeRuntimeAccess indicates a variable is accessible during runtime. 27 AttributeRuntimeAccess VariableAttributes = 0x00000004 28 // AttributeHardwareErrorRecord indicates a variable holds hardware error records. 29 AttributeHardwareErrorRecord VariableAttributes = 0x00000008 30 // AttributeAuthenticatedWriteAccess indicates a variable needs authentication before write access. 31 AttributeAuthenticatedWriteAccess VariableAttributes = 0x00000010 32 // AttributeTimeBasedAuthenticatedWriteAccess indicates a variable needs time based authentication before write access. 33 AttributeTimeBasedAuthenticatedWriteAccess VariableAttributes = 0x00000020 34 // AttributeAppendWrite indicates data written to this variable is appended. 35 AttributeAppendWrite VariableAttributes = 0x00000040 36 // AttributeEnhancedAuthenticatedAccess indicate a variable uses the new authentication format. 37 AttributeEnhancedAuthenticatedAccess VariableAttributes = 0x00000080 38 ) 39 40 // VariableDescriptor contains the name and GUID identifying a variable 41 type VariableDescriptor struct { 42 Name string 43 GUID guid.UUID 44 } 45 46 var ( 47 // ErrBadGUID is for any errors parsing GUIDs. 48 ErrBadGUID = errors.New("Bad GUID") 49 ) 50 51 func guidParse(v string) ([]string, *guid.UUID, error) { 52 vs := strings.SplitN(v, "-", 2) 53 if len(vs) < 2 { 54 return nil, nil, fmt.Errorf("GUID must have name-GUID format: %w", ErrBadGUID) 55 } 56 g, err := guid.Parse(vs[1]) 57 if err != nil { 58 return nil, nil, fmt.Errorf("%w:%v", ErrBadGUID, err) 59 } 60 return vs, &g, nil 61 } 62 63 // ReadVariable calls get() on the current efivarfs backend. 64 func ReadVariable(e EFIVar, desc VariableDescriptor) (VariableAttributes, []byte, error) { 65 return e.Get(desc) 66 } 67 68 // SimpleReadVariable is like ReadVariables but takes the combined name and guid string 69 // of the form name-guid and returns a bytes.Reader instead of a []byte. 70 func SimpleReadVariable(e EFIVar, v string) (VariableAttributes, *bytes.Reader, error) { 71 vs, g, err := guidParse(v) 72 if err != nil { 73 return 0, nil, err 74 } 75 attrs, data, err := ReadVariable(e, 76 VariableDescriptor{ 77 Name: vs[0], 78 GUID: *g, 79 }, 80 ) 81 return attrs, bytes.NewReader(data), err 82 } 83 84 // WriteVariable calls set() on the current efivarfs backend. 85 func WriteVariable(e EFIVar, desc VariableDescriptor, attrs VariableAttributes, data []byte) error { 86 return e.Set(desc, attrs, data) 87 } 88 89 // SimpleWriteVariable is like WriteVariables but takes the combined name and guid string 90 // of the form name-guid and returns a bytes.Buffer instead of a []byte. 91 func SimpleWriteVariable(e EFIVar, v string, attrs VariableAttributes, data *bytes.Buffer) error { 92 vs, g, err := guidParse(v) 93 if err != nil { 94 return err 95 } 96 return WriteVariable(e, 97 VariableDescriptor{ 98 Name: vs[0], 99 GUID: *g, 100 }, attrs, data.Bytes(), 101 ) 102 } 103 104 // RemoveVariable calls remove() on the current efivarfs backend. 105 func RemoveVariable(e EFIVar, desc VariableDescriptor) error { 106 return e.Remove(desc) 107 } 108 109 // SimpleRemoveVariable is like RemoveVariable but takes the combined name and guid string 110 // of the form name-guid. 111 func SimpleRemoveVariable(e EFIVar, v string) error { 112 vs, g, err := guidParse(v) 113 if err != nil { 114 return err 115 } 116 return RemoveVariable(e, 117 VariableDescriptor{ 118 Name: vs[0], 119 GUID: *g, 120 }, 121 ) 122 } 123 124 // ListVariables calls list() on the current efivarfs backend. 125 func ListVariables(e EFIVar) ([]VariableDescriptor, error) { 126 return e.List() 127 } 128 129 // SimpleListVariables is like ListVariables but returns a []string instead of a []VariableDescriptor. 130 func SimpleListVariables(e EFIVar) ([]string, error) { 131 list, err := ListVariables(e) 132 if err != nil { 133 return nil, err 134 } 135 var out []string 136 for _, v := range list { 137 out = append(out, v.Name+"-"+v.GUID.String()) 138 } 139 return out, nil 140 }