1 /* SPDX-License-Identifier: GPL-2.0-or-later */
13 static size_t get_var_hdr_size(bool auth_vars
)
16 return sizeof(AUTHENTICATED_VARIABLE_HEADER
);
17 return sizeof(VARIABLE_HEADER
);
20 struct var_store_t
vs_load(struct mem_range_t vs_data
, bool auth_vars
)
22 uint8_t *var_hdr
= vs_data
.start
;
24 struct var_store_t vs
= {
25 .auth_vars
= auth_vars
,
29 struct var_t
*last_var
= NULL
;
31 const size_t var_hdr_size
= get_var_hdr_size(auth_vars
);
32 while (var_hdr
+ var_hdr_size
< vs_data
.start
+ vs_data
.length
) {
35 struct var_t var
= {0};
36 uint8_t *var_data
= var_hdr
;
39 const AUTHENTICATED_VARIABLE_HEADER
*auth_hdr
=
42 start_id
= auth_hdr
->StartId
;
43 state
= auth_hdr
->State
;
45 var
.reserved
= auth_hdr
->Reserved
;
46 var
.attrs
= auth_hdr
->Attributes
;
47 var
.name_size
= auth_hdr
->NameSize
;
48 var
.data_size
= auth_hdr
->DataSize
;
49 var
.guid
= auth_hdr
->VendorGuid
;
51 const VARIABLE_HEADER
*no_auth_hdr
= (void *)var_data
;
53 start_id
= no_auth_hdr
->StartId
;
54 state
= no_auth_hdr
->State
;
56 var
.reserved
= no_auth_hdr
->Reserved
;
57 var
.attrs
= no_auth_hdr
->Attributes
;
58 var
.name_size
= no_auth_hdr
->NameSize
;
59 var
.data_size
= no_auth_hdr
->DataSize
;
60 var
.guid
= no_auth_hdr
->VendorGuid
;
63 var_hdr
+= HEADER_ALIGN(var_hdr_size
+
67 if (start_id
!= VARIABLE_DATA
)
70 if (state
!= VAR_ADDED
)
73 if (var
.data_size
== UINT32_MAX
||
74 var
.name_size
== UINT32_MAX
||
75 var
.attrs
== UINT32_MAX
)
78 CHAR16
*name
= (void *)(var_data
+ var_hdr_size
);
79 var
.name
= xmalloc(var
.name_size
);
80 memcpy(var
.name
, name
, var
.name_size
);
83 (void *)(var_data
+ var_hdr_size
+ var
.name_size
);
84 var
.data
= xmalloc(var
.data_size
);
85 memcpy(var
.data
, data
, var
.data_size
);
87 struct var_t
*var_node
= xmalloc(sizeof(*var_node
));
90 last_var
->next
= var_node
;
91 else if (vs
.vars
== NULL
)
99 static void store_var(const struct var_t
*var
, bool auth_vars
, uint8_t *data
)
102 AUTHENTICATED_VARIABLE_HEADER hdr
;
103 memset(&hdr
, 0xff, sizeof(hdr
));
105 hdr
.StartId
= VARIABLE_DATA
;
106 hdr
.State
= VAR_ADDED
;
107 hdr
.Reserved
= var
->reserved
;
108 hdr
.Attributes
= var
->attrs
;
109 hdr
.VendorGuid
= var
->guid
;
110 hdr
.NameSize
= var
->name_size
;
111 hdr
.DataSize
= var
->data_size
;
113 memcpy(data
, &hdr
, sizeof(hdr
));
117 memset(&hdr
, 0xff, sizeof(hdr
));
119 hdr
.StartId
= VARIABLE_DATA
;
120 hdr
.State
= VAR_ADDED
;
121 hdr
.Reserved
= var
->reserved
;
122 hdr
.Attributes
= var
->attrs
;
123 hdr
.VendorGuid
= var
->guid
;
124 hdr
.NameSize
= var
->name_size
;
125 hdr
.DataSize
= var
->data_size
;
127 memcpy(data
, &hdr
, sizeof(hdr
));
131 memcpy(data
, var
->name
, var
->name_size
);
132 memcpy(data
+ var
->name_size
, var
->data
, var
->data_size
);
135 bool vs_store(struct var_store_t
*vs
, struct mem_range_t vs_data
)
137 uint8_t *out_data
= vs_data
.start
;
139 const size_t var_hdr_size
= get_var_hdr_size(vs
->auth_vars
);
140 for (struct var_t
*var
= vs
->vars
; var
!= NULL
; var
= var
->next
) {
141 const size_t var_size
=
142 var_hdr_size
+ var
->name_size
+ var
->data_size
;
143 if (out_data
+ var_size
> vs_data
.start
+ vs_data
.length
) {
145 "Not enough space to serialize Variable Store.\n");
149 store_var(var
, vs
->auth_vars
, out_data
);
150 out_data
+= HEADER_ALIGN(var_size
);
153 // The rest is "uninitialized".
154 memset(out_data
, 0xff, vs_data
.length
- (out_data
- vs_data
.start
));
159 struct var_t
*vs_new_var(struct var_store_t
*vs
)
161 struct var_t
*new_var
= xmalloc(sizeof(*new_var
));
163 memset(new_var
, 0, sizeof(*new_var
));
164 new_var
->attrs
= EFI_VARIABLE_NON_VOLATILE
165 | EFI_VARIABLE_BOOTSERVICE_ACCESS
166 | EFI_VARIABLE_RUNTIME_ACCESS
;
168 struct var_t
*var
= vs
->vars
;
172 while (var
->next
!= NULL
)
180 struct var_t
*vs_find(struct var_store_t
*vs
,
182 const EFI_GUID
*guid
)
185 CHAR16
*uchar_name
= to_uchars(name
, &name_size
);
188 for (var
= vs
->vars
; var
!= NULL
; var
= var
->next
) {
189 if (var
->name_size
!= name_size
)
191 if (memcmp(var
->name
, uchar_name
, name_size
) != 0)
193 if (memcmp(&var
->guid
, guid
, sizeof(*guid
)) != 0)
202 static void free_var(struct var_t
*var
)
209 void vs_delete(struct var_store_t
*vs
, struct var_t
*var
)
211 if (vs
->vars
== var
) {
212 vs
->vars
= var
->next
;
217 for (struct var_t
*v
= vs
->vars
; v
!= NULL
; v
= v
->next
) {
218 if (v
->next
== var
) {
226 void vs_free(struct var_store_t
*vs
)
228 for (struct var_t
*next
, *var
= vs
->vars
; var
!= NULL
; var
= next
) {