Fix SIGSEGV in IsInterestedInRoomID (#1846)

* Avoid crash on non-compiled room regex

Roughly fixes #1845 (actual compiling still needed)

Signed-off-by: Bohdan Horbeshko <bodqhrohro@gmail.com>

* Compile regexes for all namespaces

Deadheres the regex compiling from building larger regexes for possibly
exclusive namespaces only. A complete fix for #1845, so regexes for
rooms namespaces and other non-whitelisted namespaces can be used
more safely.

Signed-off-by: Bohdan Horbeshko <bodqhrohro@gmail.com>

* Appservice config: handle regexp parsing errors

Signed-off-by: diamondburned <datutbrus@gmail.com>
Signed-off-by: Bohdan Horbeshko <bodqhrohro@gmail.com>

Co-authored-by: Kegsay <kegan@matrix.org>
main
bodqhrohro 2021-06-07 11:13:40 +03:00 committed by GitHub
parent f18001ecbb
commit c488d3db75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 22 additions and 5 deletions

View File

@ -101,7 +101,7 @@ func (a *ApplicationService) IsInterestedInRoomID(
) bool { ) bool {
if namespaceSlice, ok := a.NamespaceMap["rooms"]; ok { if namespaceSlice, ok := a.NamespaceMap["rooms"]; ok {
for _, namespace := range namespaceSlice { for _, namespace := range namespaceSlice {
if namespace.RegexpObject.MatchString(roomID) { if namespace.RegexpObject != nil && namespace.RegexpObject.MatchString(roomID) {
return true return true
} }
} }
@ -222,6 +222,10 @@ func setupRegexps(asAPI *AppServiceAPI, derived *Derived) (err error) {
case "aliases": case "aliases":
appendExclusiveNamespaceRegexs(&exclusiveAliasStrings, namespaceSlice) appendExclusiveNamespaceRegexs(&exclusiveAliasStrings, namespaceSlice)
} }
if err = compileNamespaceRegexes(namespaceSlice); err != nil {
return fmt.Errorf("invalid regex in appservice %q, namespace %q: %w", appservice.ID, key, err)
}
} }
} }
@ -258,18 +262,31 @@ func setupRegexps(asAPI *AppServiceAPI, derived *Derived) (err error) {
func appendExclusiveNamespaceRegexs( func appendExclusiveNamespaceRegexs(
exclusiveStrings *[]string, namespaces []ApplicationServiceNamespace, exclusiveStrings *[]string, namespaces []ApplicationServiceNamespace,
) { ) {
for index, namespace := range namespaces { for _, namespace := range namespaces {
if namespace.Exclusive { if namespace.Exclusive {
// We append parenthesis to later separate each regex when we compile // We append parenthesis to later separate each regex when we compile
// i.e. "app1.*", "app2.*" -> "(app1.*)|(app2.*)" // i.e. "app1.*", "app2.*" -> "(app1.*)|(app2.*)"
*exclusiveStrings = append(*exclusiveStrings, "("+namespace.Regex+")") *exclusiveStrings = append(*exclusiveStrings, "("+namespace.Regex+")")
} }
// Compile this regex into a Regexp object for later use
namespaces[index].RegexpObject, _ = regexp.Compile(namespace.Regex)
} }
} }
// compileNamespaceRegexes turns strings into regex objects and complains
// if some of there are bad
func compileNamespaceRegexes(namespaces []ApplicationServiceNamespace) (err error) {
for index, namespace := range namespaces {
// Compile this regex into a Regexp object for later use
r, err := regexp.Compile(namespace.Regex)
if err != nil {
return fmt.Errorf("regex at namespace %d: %w", index, err)
}
namespaces[index].RegexpObject = r
}
return nil
}
// checkErrors checks for any configuration errors amongst the loaded // checkErrors checks for any configuration errors amongst the loaded
// application services according to the application service spec. // application services according to the application service spec.
func checkErrors(config *AppServiceAPI, derived *Derived) (err error) { func checkErrors(config *AppServiceAPI, derived *Derived) (err error) {