all: fix chlog, imp api

This commit is contained in:
Eugene Burkov 2024-10-25 17:05:08 +03:00
parent 42c3f8e91c
commit a2309f812a
7 changed files with 53 additions and 7 deletions

View file

@ -25,13 +25,16 @@ See also the [v0.107.54 GitHub milestone][ms-v0.107.54].
NOTE: Add new changes BELOW THIS COMMENT. NOTE: Add new changes BELOW THIS COMMENT.
--> -->
### Security
- Incorrect handling of sensitive files permissions on Windows ([#7314]).
### Changed ### Changed
- Improved filtering performance ([#6818]). - Improved filtering performance ([#6818]).
### Fixed ### Fixed
- Incorrect handling of sensitive files permissions on Windows ([#7314]).
- Repetitive statistics log messages ([#7338]). - Repetitive statistics log messages ([#7338]).
- Custom client cache ([#7250]). - Custom client cache ([#7250]).
- Missing runtime clients with information from the system hosts file on first - Missing runtime clients with information from the system hosts file on first

View file

@ -1,6 +1,9 @@
package aghos package aghos
import "io/fs" import (
"io/fs"
"os"
)
// TODO(e.burkov): Add platform-independent tests. // TODO(e.burkov): Add platform-independent tests.
@ -28,6 +31,12 @@ func WriteFile(filename string, data []byte, perm fs.FileMode) (err error) {
return writeFile(filename, data, perm) return writeFile(filename, data, perm)
} }
// OpenFile is an extension for [os.OpenFile] that properly handles Windows
// access rights.
func OpenFile(name string, flag int, perm fs.FileMode) (file *os.File, err error) {
return openFile(name, flag, perm)
}
// Stat is an extension for [os.Stat] that properly handles Windows access // Stat is an extension for [os.Stat] that properly handles Windows access
// rights. // rights.
func Stat(name string) (fi fs.FileInfo, err error) { func Stat(name string) (fi fs.FileInfo, err error) {

View file

@ -27,6 +27,13 @@ func writeFile(filename string, data []byte, perm fs.FileMode) (err error) {
return os.WriteFile(filename, data, perm) return os.WriteFile(filename, data, perm)
} }
// openFile is a Unix implementation of [OpenFile].
func openFile(name string, flag int, perm fs.FileMode) (file *os.File, err error) {
// #nosec G304 -- This function simply wraps the [os.OpenFile] function, so
// the security concerns should be addressed to the [OpenFile] calls.
return os.OpenFile(name, flag, perm)
}
// stat is a Unix implementation of [Stat]. // stat is a Unix implementation of [Stat].
func stat(name string) (fi os.FileInfo, err error) { func stat(name string) (fi os.FileInfo, err error) {
return os.Stat(name) return os.Stat(name)

View file

@ -180,7 +180,7 @@ func mkdirAll(path string, perm os.FileMode) (err error) {
parent, _ := filepath.Split(path) parent, _ := filepath.Split(path)
err = os.MkdirAll(parent, perm) err = os.MkdirAll(parent, perm)
if err != nil { if err != nil && !errors.Is(err, os.ErrExist) {
return fmt.Errorf("creating parent directories: %w", err) return fmt.Errorf("creating parent directories: %w", err)
} }
@ -197,6 +197,26 @@ func writeFile(filename string, data []byte, perm os.FileMode) (err error) {
return chmod(filename, perm) return chmod(filename, perm)
} }
// openFile is a Windows implementation of [OpenFile].
func openFile(name string, flag int, perm os.FileMode) (file *os.File, err error) {
// Only change permissions if the file not yet exists, but should be
// created.
if flag&os.O_CREATE != 0 {
return os.OpenFile(name, flag, perm)
}
_, err = stat(name)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
defer func() { err = errors.WithDeferred(err, chmod(name, perm)) }()
} else {
return nil, fmt.Errorf("getting file info: %w", err)
}
}
return os.OpenFile(name, flag, perm)
}
// newWellKnownTrustee returns a trustee for a well-known SID. // newWellKnownTrustee returns a trustee for a well-known SID.
func newWellKnownTrustee(stype windows.WELL_KNOWN_SID_TYPE) (t *windows.TRUSTEE, err error) { func newWellKnownTrustee(stype windows.WELL_KNOWN_SID_TYPE) (t *windows.TRUSTEE, err error) {
sid, err := windows.CreateWellKnownSid(stype) sid, err := windows.CreateWellKnownSid(stype)
@ -213,8 +233,8 @@ func newWellKnownTrustee(stype windows.WELL_KNOWN_SID_TYPE) (t *windows.TRUSTEE,
// Constants reflecting the UNIX permission bits. // Constants reflecting the UNIX permission bits.
const ( const (
ownerWrite = 0b010_000_000 ownerWrite = 0b010_000_000
groupWrite = 0b000_100_000 groupWrite = 0b000_010_000
worldWrite = 0b000_000_100 worldWrite = 0b000_000_010
ownerAll = 0b111_000_000 ownerAll = 0b111_000_000
groupAll = 0b000_111_000 groupAll = 0b000_111_000

View file

@ -57,6 +57,7 @@ type qLogFile struct {
// newQLogFile initializes a new instance of the qLogFile. // newQLogFile initializes a new instance of the qLogFile.
func newQLogFile(path string) (qf *qLogFile, err error) { func newQLogFile(path string) (qf *qLogFile, err error) {
// Don't use [aghos.OpenFile] here, because the file is expected to exist.
f, err := os.OpenFile(path, os.O_RDONLY, aghos.DefaultPermFile) f, err := os.OpenFile(path, os.O_RDONLY, aghos.DefaultPermFile)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -71,7 +71,7 @@ func (l *queryLog) flushToFile(b *bytes.Buffer) (err error) {
filename := l.logFile filename := l.logFile
f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, aghos.DefaultPermFile) f, err := aghos.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, aghos.DefaultPermFile)
if err != nil { if err != nil {
return fmt.Errorf("creating file %q: %w", filename, err) return fmt.Errorf("creating file %q: %w", filename, err)
} }

View file

@ -384,7 +384,13 @@ func (s *StatsCtx) openDB() (err error) {
s.logger.Debug("opening database") s.logger.Debug("opening database")
var db *bbolt.DB var db *bbolt.DB
db, err = bbolt.Open(s.filename, aghos.DefaultPermFile, nil)
opts := *bbolt.DefaultOptions
// Use the custom OpenFile function to properly handle access rights on
// Windows.
opts.OpenFile = aghos.OpenFile
db, err = bbolt.Open(s.filename, aghos.DefaultPermFile, &opts)
if err != nil { if err != nil {
if err.Error() == "invalid argument" { if err.Error() == "invalid argument" {
const lines = `AdGuard Home cannot be initialized due to an incompatible file system. const lines = `AdGuard Home cannot be initialized due to an incompatible file system.