From 09bba4198af021b0cf92fa3f6dfb29bdd884674d Mon Sep 17 00:00:00 2001 From: Patrick Pacher Date: Tue, 17 Aug 2021 12:39:05 +0200 Subject: [PATCH 1/3] Fix incorrect read-lock for filterlist bloom filter --- intel/filterlists/bloom.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/intel/filterlists/bloom.go b/intel/filterlists/bloom.go index 67915d3e..35fa1b7b 100644 --- a/intel/filterlists/bloom.go +++ b/intel/filterlists/bloom.go @@ -6,9 +6,9 @@ import ( "strings" "sync" - "github.com/tannerryan/ring" "github.com/safing/portbase/database/record" "github.com/safing/portbase/log" + "github.com/tannerryan/ring" ) var defaultFilter = newScopedBloom() @@ -66,8 +66,8 @@ func (bf *scopedBloom) getBloomForType(entityType string) (*ring.Ring, error) { } func (bf *scopedBloom) add(scope, value string) { - bf.rw.RLock() - defer bf.rw.RUnlock() + bf.rw.Lock() + defer bf.rw.Unlock() r, err := bf.getBloomForType(scope) if err != nil { From 3627384fc5666b8d154864f8f5c52958089c4003 Mon Sep 17 00:00:00 2001 From: Patrick Pacher Date: Tue, 17 Aug 2021 13:47:17 +0200 Subject: [PATCH 2/3] Improve locking in intel/geoip --- intel/geoip/database.go | 3 ++- intel/geoip/lookup.go | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/intel/geoip/database.go b/intel/geoip/database.go index 2706f49f..57c07489 100644 --- a/intel/geoip/database.go +++ b/intel/geoip/database.go @@ -20,7 +20,7 @@ var ( geoDBv4Reader *maxminddb.Reader geoDBv6Reader *maxminddb.Reader - dbLock sync.Mutex + dbLock sync.RWMutex dbInUse = abool.NewBool(false) // only activate if used for first time dbDoReload = abool.NewBool(true) // if database should be reloaded @@ -35,6 +35,7 @@ func ReloadDatabases() error { dbFileLock.Lock() defer dbFileLock.Unlock() + dbLock.Lock() defer dbLock.Unlock() diff --git a/intel/geoip/lookup.go b/intel/geoip/lookup.go index b4c7f320..16a8f59f 100644 --- a/intel/geoip/lookup.go +++ b/intel/geoip/lookup.go @@ -15,8 +15,8 @@ func getReader(ip net.IP) *maxminddb.Reader { // GetLocation returns Location data of an IP address func GetLocation(ip net.IP) (record *Location, err error) { - dbLock.Lock() - defer dbLock.Unlock() + dbLock.RLock() + defer dbLock.RUnlock() err = prepDatabaseForUse() if err != nil { From 026dc274f475a619ddb453d8658da5869a84cc36 Mon Sep 17 00:00:00 2001 From: Patrick Pacher Date: Tue, 17 Aug 2021 14:25:55 +0200 Subject: [PATCH 3/3] Fix bypass prevention not working as expected due to filterlists not matched for the entity --- firewall/bypassing.go | 7 ++++++- firewall/master.go | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/firewall/bypassing.go b/firewall/bypassing.go index bfe76adf..6554643a 100644 --- a/firewall/bypassing.go +++ b/firewall/bypassing.go @@ -1,6 +1,7 @@ package firewall import ( + "context" "strings" "github.com/safing/portmaster/nameserver/nsutil" @@ -14,7 +15,7 @@ var ( // PreventBypassing checks if the connection should be denied or permitted // based on some bypass protection checks. -func PreventBypassing(conn *network.Connection) (endpoints.EPResult, string, nsutil.Responder) { +func PreventBypassing(ctx context.Context, conn *network.Connection) (endpoints.EPResult, string, nsutil.Responder) { // Block firefox canary domain to disable DoH if strings.ToLower(conn.Entity.Domain) == "use-application-dns.net." { return endpoints.Denied, @@ -22,6 +23,10 @@ func PreventBypassing(conn *network.Connection) (endpoints.EPResult, string, nsu nsutil.NxDomain() } + if !conn.Entity.LoadLists(ctx) { + return endpoints.Undeterminable, "", nil + } + if conn.Entity.MatchLists(resolverFilterLists) { return endpoints.Denied, "blocked rogue connection to DNS resolver", diff --git a/firewall/master.go b/firewall/master.go index 96292ff0..95ce467d 100644 --- a/firewall/master.go +++ b/firewall/master.go @@ -335,10 +335,10 @@ func checkConnectionScope(_ context.Context, conn *network.Connection, p *profil return false } -func checkBypassPrevention(_ context.Context, conn *network.Connection, p *profile.LayeredProfile, _ packet.Packet) bool { +func checkBypassPrevention(ctx context.Context, conn *network.Connection, p *profile.LayeredProfile, _ packet.Packet) bool { if p.PreventBypassing() { // check for bypass protection - result, reason, reasonCtx := PreventBypassing(conn) + result, reason, reasonCtx := PreventBypassing(ctx, conn) switch result { case endpoints.Denied: conn.BlockWithContext("bypass prevention: "+reason, profile.CfgOptionPreventBypassingKey, reasonCtx)