mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2025-03-12 21:48:33 +03:00
fix: service binary overwrite privilege escalation vuln
This commit is contained in:
parent
bd99e3e09d
commit
c0a5e389d9
2 changed files with 51 additions and 0 deletions
internal/home
|
@ -748,6 +748,7 @@ func writePIDFile(fn string) bool {
|
|||
// initConfigFilename sets up context config file path. This file path can be
|
||||
// overridden by command-line arguments, or is set to default.
|
||||
func initConfigFilename(opts options) {
|
||||
// TODO: if running as service the config location should be /etc/AdGuardHome/AdGuardHome.yaml
|
||||
Context.configFilename = stringutil.Coalesce(opts.confFilename, "AdGuardHome.yaml")
|
||||
}
|
||||
|
||||
|
@ -760,6 +761,8 @@ func initWorkingDir(opts options) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
// TODO: if running as a service use /var/lib/AdGuardHome
|
||||
|
||||
if opts.workDir != "" {
|
||||
// If there is a custom config file, use it's directory as our working dir
|
||||
Context.workDir = opts.workDir
|
||||
|
|
|
@ -304,6 +304,11 @@ func handleServiceStatusCommand(s service.Service) {
|
|||
|
||||
// handleServiceStatusCommand handles service "install" command
|
||||
func handleServiceInstallCommand(s service.Service) {
|
||||
// Set the binary's permissions and move to /usr/bin (if on linux)
|
||||
if err := secureBinary(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
err := svcAction(s, "install")
|
||||
if err != nil {
|
||||
log.Fatalf("service: executing action %q: %s", "install", err)
|
||||
|
@ -681,3 +686,46 @@ rc_bg=YES
|
|||
|
||||
rc_cmd $1
|
||||
`
|
||||
|
||||
// secureBinary is used before service.Install(). This function protects AdGuardHome from
|
||||
// privilege escalation vulnerabilities caused by writable files
|
||||
func secureBinary() error {
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
// TODO: support windows service support securely
|
||||
// Set file owner to admin/system and public permissions read-only
|
||||
return errors.Error("you currently cannot install adguardhome as a service on window")
|
||||
default:
|
||||
return secureBinaryUnix()
|
||||
}
|
||||
}
|
||||
|
||||
func secureBinaryUnix() error {
|
||||
// Installalation can only be completed with root privileges, so check and handle if not
|
||||
if os.Getuid() != 0 {
|
||||
return errors.Error("permission denied. Root privileges required")
|
||||
}
|
||||
|
||||
// Get current file path
|
||||
binary := os.Args[0]
|
||||
|
||||
// Change owner to root:root
|
||||
err := os.Chown(binary, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set permissions to root(read,write,exec), group(read,exec), public(read)
|
||||
// This combined with changing the owner make the file undeletable without root privlages
|
||||
// UNLESS THE PARENT FOLDER IS WRITABLE!
|
||||
if err := os.Chmod(binary, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Move binary to the PATH in a folder which is read-only to non root users
|
||||
if err := os.Rename(binary, "/usr/bin/AdGuardHome"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue