Skip to content

Commit de343db

Browse files
author
Manish Ranjan Mahanta
committed
Moving to VMUtils and static analysis fix
Signed-off-by: Manish Ranjan Mahanta <mmahanta@microsoft.com>
1 parent 8f00207 commit de343db

4 files changed

Lines changed: 77 additions & 46 deletions

File tree

internal/uvm/log_wcow.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,12 @@ func (uvm *UtilityVM) SetLogSources(ctx context.Context) error {
6464
if wcaps != nil && wcaps.IsLogForwardingSupported() {
6565
// Make a call to the GCS to set the ETW providers
6666

67-
var settings string
6867
// Determines the log sources to be set based on the configuration. If default log sources are enabled,
6968
// we only include them along with user specified log sources.
7069
// For confidential WCOw, we skip the adding guids to the log sources as the sidecar-GCS will verify the
7170
// allowed log sources against policy and append the necessary GUIDs to the ones allowed. Rest are dropped.
7271
// For non-confidential WCOW, we include the GUIDs in the log sources as the hcsshim communicates directly with the inboxGCS.
73-
settings = etw.UpdateEncodedLogSources(uvm.logSources, !uvm.disableDefaultLogSources, !uvm.HasConfidentialPolicy())
72+
settings := etw.UpdateEncodedLogSources(ctx, uvm.logSources, !uvm.disableDefaultLogSources, !uvm.HasConfidentialPolicy())
7473

7574
req := guestrequest.LogForwardServiceRPCRequest{
7675
RPCType: guestrequest.RPCModifyServiceSettings,
File renamed without changes.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
},
3535
{
3636
"providerName": "Microsoft.Windows.LogForwardService.Provider",
37-
"providerGuid": "396A26FF-FB73-5465-0D17-DD493089623"
37+
"providerGuid": "396a26ff-fb73-5465-0d17-dd4930896239"
3838
},
3939
{
4040
"providerName": "Microsoft.Windows.Security.KeyGuard",
Lines changed: 75 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
package etw
22

33
import (
4+
"context"
45
"embed"
56
"encoding/base64"
67
"encoding/json"
78
"fmt"
89
"strings"
910
"sync"
10-
)
1111

12-
//go:embed etw-map.json
13-
//go:embed default-logsources.json
12+
"github.com/Microsoft/hcsshim/internal/log"
13+
)
1414

15-
var etwFS embed.FS
16-
var listFS embed.FS
15+
//go:embed etw-map.json default-logsources.json
16+
var embeddedFiles embed.FS
1717

1818
const (
1919
EtwMapFileName = "etw-map.json"
@@ -49,7 +49,7 @@ type Source struct {
4949

5050
type EtwProvider struct {
5151
ProviderName string `json:"providerName,omitempty"`
52-
ProviderGuid string `json:"providerGuid,omitempty"`
52+
ProviderGUID string `json:"providerGuid,omitempty"`
5353
Level string `json:"level,omitempty"`
5454
Keywords string `json:"keywords,omitempty"`
5555
}
@@ -61,11 +61,11 @@ type EtwInfo struct {
6161

6262
type EtwProviderMap struct {
6363
ProviderName string `json:"providerName"`
64-
ProviderGuid string `json:"providerGuid"`
64+
ProviderGUID string `json:"providerGuid"`
6565
}
6666

67-
// NormalizeGuid takes a GUID string in various formats and normalizes it to the standard 8-4-4-4-12 format with uppercase letters. It returns an error if the input string is not a valid GUID.
68-
func NormalizeGuid(in string) (string, error) {
67+
// NormalizeGUID takes a GUID string in various formats and normalizes it to the standard 8-4-4-4-12 format with uppercase letters. It returns an error if the input string is not a valid GUID.
68+
func NormalizeGUID(in string) (string, error) {
6969
s := strings.TrimSpace(in)
7070
s = strings.TrimPrefix(s, "{")
7171
s = strings.TrimSuffix(s, "}")
@@ -95,15 +95,17 @@ func NormalizeGuid(in string) (string, error) {
9595
}
9696

9797
// LoadEtwMap loads the ETW provider name to GUID mapping from the embedded JSON file. It returns two maps, one for name to GUID and another for GUID to name. If there is an error in loading or parsing the file, it returns empty maps and the error.
98-
func LoadEtwMap() (map[string]string, map[string]string, error) {
98+
func LoadEtwMap(ctx context.Context) (map[string]string, map[string]string, error) {
9999
onceProvider.Do(func() {
100-
b, err := etwFS.ReadFile(EtwMapFileName)
100+
b, err := embeddedFiles.ReadFile(EtwMapFileName)
101101
if err != nil {
102+
log.G(ctx).Errorf("Error reading ETW map file: %v", err)
102103
return
103104
}
104105

105106
var cfg EtwInfo
106107
if err := json.Unmarshal(b, &cfg); err != nil {
108+
log.G(ctx).Errorf("Error unmarshalling ETW map file: %v", err)
107109
return
108110
}
109111

@@ -112,19 +114,22 @@ func LoadEtwMap() (map[string]string, map[string]string, error) {
112114

113115
for _, p := range cfg.EtwMap {
114116
name := strings.TrimSpace(p.ProviderName)
115-
guid, err := NormalizeGuid(p.ProviderGuid)
117+
guid, err := NormalizeGUID(p.ProviderGUID)
116118
if name == "" || err != nil {
117119
// skip invalid entries
120+
log.G(ctx).Warningf("Skipping invalid ETW map entry with name %q and GUID %q: %v", p.ProviderName, p.ProviderGUID, err)
118121
continue
119122
}
120123

121124
// Duplicate check
122125
if _, ok := n2g[name]; ok {
123126
// skip if already exists
127+
log.G(ctx).Warningf("Skipping duplicate ETW provider name %q in ETW map", name)
124128
continue
125129
}
126130
if _, ok := g2n[guid]; ok {
127131
// skip if already exists
132+
log.G(ctx).Warningf("Skipping duplicate ETW provider GUID %q in ETW map", guid)
128133
continue
129134
}
130135

@@ -140,27 +145,48 @@ func LoadEtwMap() (map[string]string, map[string]string, error) {
140145
return nameToGUID, guidToName, nil
141146
}
142147

143-
// GetDefaultLogSources returns the default log sources from the embedded json file. If there is an error in loading or parsing the file, it returns an empty LogSourcesInfo struct and the error.
144-
func GetDefaultLogSources() (LogSourcesInfo, error) {
148+
// GetDefaultLogSources returns the default log sources from the embedded JSON file. If there is an error in loading or parsing the file, it returns an empty LogSourcesInfo struct and the error.
149+
// The default log sources are defined in the "default-logsources.json" file and are loaded only once using sync.Once to ensure thread safety and performance.
150+
// The providers in the default-logsources.json file should only have Provider Names and must not contain GUIDs as the handling of GUIDs is based on the configuration and is done in the UpdateEncodedLogSources function where we
151+
// check if we need to include GUIDs for the log sources based on the configuration and if needed, we map the provider names to their corresponding GUIDs using the ETW map loaded from the "etw-map.json" file.
152+
// The only exception to this is if the provider does not have any name and only has a GUID.
153+
func GetDefaultLogSources(ctx context.Context) (LogSourcesInfo, error) {
145154
onceLists.Do(func() {
146155

147-
allList, err := listFS.ReadFile(DefaultLogSourcesFile)
156+
allList, err := embeddedFiles.ReadFile(DefaultLogSourcesFile)
148157
if err != nil {
158+
log.G(ctx).Errorf("Error reading default log sources file: %v", err)
149159
return
150160
}
151161

152162
if err := json.Unmarshal(allList, &defaultLogSources); err != nil {
163+
log.G(ctx).Errorf("Error unmarshalling default log sources file: %v", err)
153164
return
154165
}
166+
167+
// Check if the default log sources have provider names. If they do, do not include GUIDs in the
168+
// default log sources, because GUID handling is based on configuration and is done in the
169+
// UpdateEncodedLogSources function. There we check if GUIDs are needed for the log sources and,
170+
// if so, map provider names to their corresponding GUIDs using the ETW map from "etw-map.json".
171+
// The only exception is when a provider has no name and only a GUID.
172+
for i := range defaultLogSources.LogConfig.Sources {
173+
for j := range defaultLogSources.LogConfig.Sources[i].Providers {
174+
if defaultLogSources.LogConfig.Sources[i].Providers[j].ProviderName != "" &&
175+
defaultLogSources.LogConfig.Sources[i].Providers[j].ProviderGUID != "" {
176+
defaultLogSources.LogConfig.Sources[i].Providers[j].ProviderGUID = ""
177+
}
178+
}
179+
}
155180
})
156181
return defaultLogSources, nil
157182
}
158183

159-
// GetDefaultLogSourcesWithMappedGuid returns the default log sources with provider GUIDs included in the providers. If there is an error in loading the default log sources or the ETW map, it returns the default log sources without GUIDs.
160-
func GetDefaultLogSourcesWithMappedGuid() (LogSourcesInfo, error) {
184+
// GetDefaultLogSourcesWithMappedGUID returns the default log sources with provider GUIDs included in the providers. If there is an error in loading the default log sources or the ETW map, it returns the default log sources without GUIDs.
185+
func GetDefaultLogSourcesWithMappedGUID(ctx context.Context) (LogSourcesInfo, error) {
161186
onceListMap.Do(func() {
162-
_, err := GetDefaultLogSources()
187+
_, err := GetDefaultLogSources(ctx)
163188
if err != nil {
189+
log.G(ctx).Errorf("Error getting default log sources: %v", err)
164190
return
165191
}
166192

@@ -173,8 +199,8 @@ func GetDefaultLogSourcesWithMappedGuid() (LogSourcesInfo, error) {
173199
etwProvider.Keywords = provider.Keywords
174200
etwProvider.Level = provider.Level
175201
etwProvider.ProviderName = provider.ProviderName
176-
etwProvider.ProviderGuid = GetProviderGuidFromName(provider.ProviderName)
177-
source.Providers = append(src.Providers, etwProvider)
202+
etwProvider.ProviderGUID = GetProviderGUIDFromName(ctx, provider.ProviderName)
203+
source.Providers = append(source.Providers, etwProvider)
178204
}
179205

180206
logConfig.Sources = append(logConfig.Sources, source)
@@ -185,32 +211,38 @@ func GetDefaultLogSourcesWithMappedGuid() (LogSourcesInfo, error) {
185211
return defaultLogSourcesWithMap, nil
186212
}
187213

188-
// GetProviderGuidFromName returns the provider guid for a given provider name. If the provider name is not found in the map, it returns an empty string.
189-
func GetProviderGuidFromName(providerName string) string {
190-
LoadEtwMap()
214+
// GetProviderGUIDFromName returns the provider GUID for a given provider name. If the provider name is not found in the map, it returns an empty string.
215+
func GetProviderGUIDFromName(ctx context.Context, providerName string) string {
216+
if _, _, err := LoadEtwMap(ctx); err != nil {
217+
log.G(ctx).Errorf("Error loading ETW map: %v", err)
218+
return ""
219+
}
191220
return nameToGUID[providerName]
192221
}
193222

194-
// GetProviderNameFromGuid returns the provider name for a given provider guid. If the provider guid is not found in the map, it returns an empty string.
195-
func GetProviderNameFromGuid(providerGuid string) string {
196-
LoadEtwMap()
197-
return guidToName[providerGuid]
223+
// GetProviderNameFromGUID returns the provider name for a given provider GUID. If the provider GUID is not found in the map, it returns an empty string.
224+
func GetProviderNameFromGUID(ctx context.Context, providerGUID string) string {
225+
if _, _, err := LoadEtwMap(ctx); err != nil {
226+
log.G(ctx).Errorf("Error loading ETW map: %v", err)
227+
return ""
228+
}
229+
return guidToName[providerGUID]
198230
}
199231

200-
// Updates the user provided log sources with the default log sources based on the configuration and returns the updated log sources as a base64 encoded json string. If there is an error in the process, it returns the original user provided log sources string.
201-
func UpdateEncodedLogSources(base64EncodedJsonLogConfig string, useDefaultLogSources bool, includeGuids bool) string {
232+
// Updates the user provided log sources with the default log sources based on the configuration and returns the updated log sources as a base64 encoded JSON string. If there is an error in the process, it returns the original user provided log sources string.
233+
func UpdateEncodedLogSources(ctx context.Context, base64EncodedJSONLogConfig string, useDefaultLogSources bool, includeGUIDs bool) string {
202234

203235
var resultLogCfg LogSourcesInfo
204236
if useDefaultLogSources {
205-
if includeGuids {
206-
resultLogCfg, _ = GetDefaultLogSourcesWithMappedGuid()
237+
if includeGUIDs {
238+
resultLogCfg, _ = GetDefaultLogSourcesWithMappedGUID(ctx)
207239
} else {
208-
resultLogCfg, _ = GetDefaultLogSources()
240+
resultLogCfg, _ = GetDefaultLogSources(ctx)
209241
}
210242
}
211243

212-
if base64EncodedJsonLogConfig != "" {
213-
jsonBytes, err := base64.StdEncoding.DecodeString(base64EncodedJsonLogConfig)
244+
if base64EncodedJSONLogConfig != "" {
245+
jsonBytes, err := base64.StdEncoding.DecodeString(base64EncodedJSONLogConfig)
214246
if err == nil {
215247
var userLogConfig LogSourcesInfo
216248
if err := json.Unmarshal(jsonBytes, &userLogConfig); err == nil {
@@ -226,21 +258,21 @@ func UpdateEncodedLogSources(base64EncodedJsonLogConfig string, useDefaultLogSou
226258
if destSrc, ok := resultSrcMap[source.Type]; ok {
227259
// then update the source's providers
228260
for _, srcProvider := range source.Providers {
229-
if includeGuids {
230-
if srcProvider.ProviderGuid == "" {
231-
srcProvider.ProviderGuid = GetProviderGuidFromName(srcProvider.ProviderName)
261+
if includeGUIDs {
262+
if srcProvider.ProviderGUID == "" {
263+
srcProvider.ProviderGUID = GetProviderGUIDFromName(ctx, srcProvider.ProviderName)
232264
}
233265
} else {
234266
// If Include GUIDs is false, then
235267
// We still include GUIDs if that is the only identity present. Only when both Name and GUID is provided for a ETW provider, we
236268
// check if the provided GUID is valid and remove it if we can fetch the same from our well known list of guids by using the name
237269
// This is because the sidecar-GCS prefers verification of log providers by name against the policy.
238-
if srcProvider.ProviderName != "" && srcProvider.ProviderGuid != "" {
239-
guid, _ := NormalizeGuid(srcProvider.ProviderGuid)
240-
if strings.EqualFold(guid, GetProviderGuidFromName(srcProvider.ProviderName)) {
241-
srcProvider.ProviderGuid = ""
270+
if srcProvider.ProviderName != "" && srcProvider.ProviderGUID != "" {
271+
guid, _ := NormalizeGUID(srcProvider.ProviderGUID)
272+
if strings.EqualFold(guid, GetProviderGUIDFromName(ctx, srcProvider.ProviderName)) {
273+
srcProvider.ProviderGUID = ""
242274
} else {
243-
srcProvider.ProviderGuid = guid
275+
srcProvider.ProviderGUID = guid
244276
}
245277
}
246278
}
@@ -271,7 +303,7 @@ func UpdateEncodedLogSources(base64EncodedJsonLogConfig string, useDefaultLogSou
271303

272304
jsonBytes, err := json.Marshal(resultLogCfg)
273305
if err != nil {
274-
return base64EncodedJsonLogConfig
306+
return base64EncodedJSONLogConfig
275307
}
276308

277309
encodedCfg := base64.StdEncoding.EncodeToString(jsonBytes)

0 commit comments

Comments
 (0)