{"record":{"id":"28a26dc9902071fb","repo":"crowdsecurity/crowdsec","slug":"while-getting-dacl-w","errorCode":null,"errorMessage":"while getting DACL: %w","messagePattern":"while getting DACL: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/csplugin/utils_windows.go","lineNumber":103,"sourceCode":"\t}\n\tif !sd.IsValid() {\n\t\treturn errors.New(\"security descriptor is invalid\")\n\t}\n\towner, _, err := sd.Owner()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"while getting owner: %w\", err)\n\t}\n\tif !owner.IsValid() {\n\t\treturn errors.New(\"owner is invalid\")\n\t}\n\n\tif !owner.Equals(systemSid) && !owner.Equals(currentUserSid) && !owner.Equals(adminSid) {\n\t\treturn fmt.Errorf(\"plugin at %s is not owned by SYSTEM, Administrators or by current user, but by %s\", path, owner.String())\n\t}\n\n\tdacl, _, err := sd.DACL()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"while getting DACL: %w\", err)\n\t}\n\n\tif dacl == nil {\n\t\treturn fmt.Errorf(\"no DACL found on plugin, meaning fully permissive access on plugin %s\", path)\n\t}\n\n\trs := reflect.ValueOf(dacl).Elem()\n\n\t/*\n\t\t\tFor reference, the structure of the ACL type is:\n\t\t\ttype ACL struct {\n\t\t\taclRevision byte\n\t\t\tsbz1        byte\n\t\t\taclSize     uint16\n\t\t\taceCount    uint16\n\t\t\tsbz2        uint16\n\t\t}\n\t\tAs the field are not exported, we have to use reflection to access them, this should not be an issue as the structure won't (probably) change any time soon.","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/csplugin/utils_windows.go#L85-L121","documentation":"CheckPerms retrieves the plugin's DACL via (*SECURITY_DESCRIPTOR).DACL() (wrapping GetSecurityDescriptorDacl) and fails if that accessor errors. This means Windows could not read the discretionary ACL from an otherwise-valid security descriptor — a low-level, rarely-seen condition.","triggerScenarios":"Calling CheckPerms when sd.DACL() returns a non-nil error: the security descriptor's ACL pointer/size fields are inconsistent, usually due to a corrupted or non-standard descriptor on the plugin file.","commonSituations":"Descriptors mangled by third-party ACL tools or incomplete backup restores; filesystem corruption; exotic filter drivers interfering with security-info queries.","solutions":["Reset the file's security descriptor: `icacls <plugin> /reset`","Reinstall or re-copy the plugin binary to regenerate a clean descriptor","Read the wrapped %w error for the underlying Win32 code","Check the volume for filesystem corruption (chkdsk) if multiple files show the issue"],"exampleFix":"// before\ndacl, _, err := sd.DACL()\nif err != nil {\n\treturn fmt.Errorf(\"while getting DACL: %w\", err)\n}\n// after\ndacl, _, err := sd.DACL()\nif err != nil {\n\treturn fmt.Errorf(\"while getting DACL of %s: %w\", path, err)\n}","handlingStrategy":"try-catch","validationCode":"sd, err := windows.GetNamedSecurityInfo(path, windows.SE_FILE_OBJECT, windows.DACL_SECURITY_INFORMATION)\nif err != nil {\n\treturn fmt.Errorf(\"DACL unreadable before plugin check: %w\", err)\n}\nif !sd.IsValid() {\n\treturn errors.New(\"security descriptor corrupt\")\n}","typeGuard":null,"tryCatchPattern":"err := CheckPerms(pluginPath)\nif err != nil && strings.Contains(err.Error(), \"getting DACL\") {\n\tlog.Warnf(\"unreadable DACL on %s — reset with: icacls %s /reset\", pluginPath, pluginPath)\n}","preventionTips":["Reset ACLs after restoring plugins from backups","Avoid tools that emit non-standard security descriptors","Keep plugin files on healthy NTFS volumes"],"tags":["windows","acl","security"],"backgroundTag":"internal-invariant-violation","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}