aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common.nim72
-rw-r--r--src/feature/syncinstall.nim72
-rw-r--r--src/pacman.nim6
-rw-r--r--src/utils.nim16
4 files changed, 100 insertions, 66 deletions
diff --git a/src/common.nim b/src/common.nim
index c42cb82..2b9651a 100644
--- a/src/common.nim
+++ b/src/common.nim
@@ -236,22 +236,29 @@ proc bisectVersion(repoPath: string, debug: bool, firstCommit: Option[string],
discard close(1)
discard close(2)
- dropPrivileges()
- execResult(args)))
+ if dropPrivileges():
+ execResult(args)
+ else:
+ quit(1)))
let (workFirstCommit, checkFirst) = if firstCommit.isSome:
(firstCommit, false)
else:
(forkWaitRedirect(() => (block:
- dropPrivileges()
- execResult(gitCmd, "-C", repoPath,
- "rev-list", "--max-parents=0", "@")))
+ if dropPrivileges():
+ execResult(gitCmd, "-C", repoPath,
+ "rev-list", "--max-parents=0", "@")
+ else:
+ quit(1)))
.output.optLast, true)
let (realLastThreeCommits, _) = forkWaitRedirect(() => (block:
- dropPrivileges()
- execResult(gitCmd, "-C", repoPath,
- "rev-list", "--max-count=3", "@")))
+ if dropPrivileges():
+ execResult(gitCmd, "-C", repoPath,
+ "rev-list", "--max-count=3", "@")
+ else:
+ quit(1)))
+
let index = workFirstCommit.map(c => realLastThreeCommits.find(c)).get(-1)
let lastThreeCommits = if index >= 0:
realLastThreeCommits[0 .. index]
@@ -266,9 +273,11 @@ proc bisectVersion(repoPath: string, debug: bool, firstCommit: Option[string],
none(string)
else:
let foundVersion = forkWaitRedirect(() => (block:
- dropPrivileges()
- execResult(pkgLibDir & "/bisect",
- compareMethod, repoPath & "/" & gitSubdir, version)))
+ if dropPrivileges():
+ execResult(pkgLibDir & "/bisect",
+ compareMethod, repoPath & "/" & gitSubdir, version)
+ else:
+ quit(1)))
.output.optFirst
let checkout2Code = forkExecWithoutOutput(gitCmd, "-C", repoPath,
@@ -308,9 +317,11 @@ proc bisectVersion(repoPath: string, debug: bool, firstCommit: Option[string],
"bisect", "run", pkgLibDir & "/bisect", compareMethod, gitSubdir, version)
let commit = forkWaitRedirect(() => (block:
- dropPrivileges()
- execResult(gitCmd, "-C", repoPath,
- "rev-list", "--max-count=1", "refs/bisect/bad")))
+ if dropPrivileges():
+ execResult(gitCmd, "-C", repoPath,
+ "rev-list", "--max-count=1", "refs/bisect/bad")
+ else:
+ quit(1)))
.output.optFirst
discard forkExecWithoutOutput(gitCmd, "-C", repoPath,
@@ -330,9 +341,10 @@ proc bisectVersion(repoPath: string, debug: bool, firstCommit: Option[string],
proc obtainSrcInfo*(path: string): string =
let (output, code) = forkWaitRedirect(() => (block:
- discard chdir(path)
- dropPrivileges()
- execResult(makePkgCmd, "--printsrcinfo")))
+ if dropPrivileges() and chdir(path) == 0:
+ execResult(makePkgCmd, "--printsrcinfo")
+ else:
+ quit(1)))
if code == 0:
output.foldl(a & b & "\n", "")
@@ -368,10 +380,12 @@ proc obtainBuildPkgInfosInternal(config: Config, bases: seq[LookupBaseGroup],
removeDirQuiet(repoPath)
if forkWait(() => (block:
- dropPrivileges()
- execResult(gitCmd, "-C", config.tmpRoot,
- "clone", "-q", git.url, "-b", git.branch,
- "--single-branch", base))) == 0:
+ if dropPrivileges():
+ execResult(gitCmd, "-C", config.tmpRoot,
+ "clone", "-q", git.url, "-b", git.branch,
+ "--single-branch", base)
+ else:
+ quit(1))) == 0:
let commit = bisectVersion(repoPath, config.debug, none(string),
"source", git.path, version)
@@ -380,9 +394,11 @@ proc obtainBuildPkgInfosInternal(config: Config, bases: seq[LookupBaseGroup],
(newSeq[PackageInfo](), none(string))
else:
discard forkWait(() => (block:
- dropPrivileges()
- execResult(gitCmd, "-C", repoPath,
- "checkout", "-q", commit.unsafeGet)))
+ if dropPrivileges():
+ execResult(gitCmd, "-C", repoPath,
+ "checkout", "-q", commit.unsafeGet)
+ else:
+ quit(1)))
let srcInfo = obtainSrcInfo(repoPath & "/" & git.path)
let pkgInfos = parseSrcInfo(repo, srcInfo, config.arch,
@@ -439,8 +455,10 @@ proc cloneAurRepo*(config: Config, basePackages: seq[PackageInfo]): (int, Option
raise newException(SystemError, "invalid clone call")
else:
let cloneCode = forkWait(() => (block:
- dropPrivileges()
- execResult(gitCmd, "-C", config.tmpRoot,
- "clone", "-q", basePackages[0].gitUrl, "--single-branch", base)))
+ if dropPrivileges():
+ execResult(gitCmd, "-C", config.tmpRoot,
+ "clone", "-q", basePackages[0].gitUrl, "--single-branch", base)
+ else:
+ quit(1)))
(cloneCode, none(string))
diff --git a/src/feature/syncinstall.nim b/src/feature/syncinstall.nim
index 94bb886..4fa5eaa 100644
--- a/src/feature/syncinstall.nim
+++ b/src/feature/syncinstall.nim
@@ -240,6 +240,17 @@ proc printUnsatisfied(config: Config,
trp("unable to satisfy dependency '%s' required by %s\n") %
[$reference, pkgInfo.name])
+template dropPrivilegesAndChdir(path: Option[string], body: untyped): int =
+ if dropPrivileges():
+ if path.isNone or chdir(path.unsafeGet) == 0:
+ body
+ else:
+ printError(config.color, tr"chdir failed: $#" % [path.unsafeGet])
+ quit(1)
+ else:
+ printError(config.color, tr"failed to drop privileges")
+ quit(1)
+
proc editLoop(config: Config, base: string, repoPath: string, gitSubdir: Option[string],
defaultYes: bool, noconfirm: bool): char =
proc editFileLoop(file: string): char =
@@ -266,25 +277,25 @@ proc editLoop(config: Config, base: string, repoPath: string, gitSubdir: Option[
if editor.strip.len == 0:
'n'
else:
- discard forkWait(proc: int =
- discard chdir(buildPath(repoPath, gitSubdir))
- dropPrivileges()
- execResult(bashCmd, "-c", """$1 "$2"""", "bash", editor, file))
+ discard forkWait(() => (block:
+ let buildPath = buildPath(repoPath, gitSubdir)
+ dropPrivilegesAndChdir(some(buildPath)):
+ execResult(bashCmd, "-c", """$1 "$2"""", "bash", editor, file)))
editFileLoop(file)
else:
res
let rawFiles = if gitSubdir.isSome:
forkWaitRedirect(() => (block:
- dropPrivileges()
- execResult(gitCmd, "-C", repoPath, "ls-tree", "-r", "--name-only", "@",
- gitSubdir.unsafeGet & "/")))
+ dropPrivilegesAndChdir(none(string)):
+ execResult(gitCmd, "-C", repoPath, "ls-tree", "-r", "--name-only", "@",
+ gitSubdir.unsafeGet & "/")))
.output
.map(s => s[gitSubdir.unsafeGet.len + 1 .. ^1])
else:
forkWaitRedirect(() => (block:
- dropPrivileges()
- execResult(gitCmd, "-C", repoPath, "ls-tree", "-r", "--name-only", "@")))
+ dropPrivilegesAndChdir(none(string)):
+ execResult(gitCmd, "-C", repoPath, "ls-tree", "-r", "--name-only", "@")))
.output
let files = ("PKGBUILD" & rawFiles.filter(x => x != ".SRCINFO")).deduplicate
@@ -338,20 +349,18 @@ proc buildLoop(config: Config, pkgInfos: seq[PackageInfo], noconfirm: bool,
let envExt = getEnv("PKGEXT")
let confExt = if envExt.len == 0:
forkWaitRedirect(() => (block:
- dropPrivileges()
- execResult(bashCmd, "-c",
- "source \"$@\" && echo \"$PKGEXT\"",
- "bash", workConfFile)))
+ dropPrivilegesAndChdir(none(string)):
+ execResult(bashCmd, "-c",
+ "source \"$@\" && echo \"$PKGEXT\"",
+ "bash", workConfFile)))
.output.optFirst.get("")
else:
envExt
let (buildCode, interrupted) = catchInterrupt():
forkWait(proc: int =
- if chdir(buildPath) == 0:
- discard cunsetenv("MAKEPKG_CONF")
- dropPrivileges()
-
+ discard cunsetenv("MAKEPKG_CONF")
+ dropPrivilegesAndChdir(some(buildPath)):
if not noextract:
removeDirQuiet(buildPath & "src")
@@ -361,9 +370,7 @@ proc buildLoop(config: Config, pkgInfos: seq[PackageInfo], noconfirm: bool,
]
execResult(@[makepkgCmd, "--config", workConfFile, "-f"] &
- optional.filter(o => o.cond).map(o => o.arg))
- else:
- quit(1))
+ optional.filter(o => o.cond).map(o => o.arg)))
discard unlink(workConfFile)
@@ -450,9 +457,8 @@ proc buildFromSources(config: Config, commonArgs: seq[Argument],
printColon(config.color, tr"Running pre-build command...")
let code = forkWait(() => (block:
- discard chdir(buildPath(repoPath, gitSubdir))
- dropPrivileges()
- execResult(bashCmd, "-c", config.preBuildCommand.unsafeGet)))
+ dropPrivilegesAndChdir(some(buildPath(repoPath, gitSubdir))):
+ execResult(bashCmd, "-c", config.preBuildCommand.unsafeGet)))
if code != 0 and printColonUserChoice(config.color,
tr"Command failed, continue?", ['y', 'n'], 'n', 'n',
@@ -665,8 +671,8 @@ proc handleInstall(args: seq[Argument], config: Config, upgradeCount: int,
discard open("/dev/null")
discard close(2)
discard open("/dev/null")
- dropPrivileges()
- execResult(gpgCmd, "--list-keys", pgpKeys[index]))) == 0:
+ dropPrivilegesAndChdir(none(string)):
+ execResult(gpgCmd, "--list-keys", pgpKeys[index]))) == 0:
keysLoop(index + 1, skipKeys)
else:
let res = if skipKeys:
@@ -684,14 +690,14 @@ proc handleInstall(args: seq[Argument], config: Config, upgradeCount: int,
keysLoop(index, newSkipKeys)
elif res == 'y' or newSkipKeys:
let importCode = forkWait(() => (block:
- dropPrivileges()
- if config.pgpKeyserver.isSome:
- forkWait(() => execResult(gpgCmd,
- "--keyserver", config.pgpKeyserver.unsafeGet,
- "--recv-keys", pgpKeys[index]))
- else:
- forkWait(() => execResult(gpgCmd,
- "--recv-keys", pgpKeys[index]))))
+ dropPrivilegesAndChdir(none(string)):
+ if config.pgpKeyserver.isSome:
+ forkWait(() => execResult(gpgCmd,
+ "--keyserver", config.pgpKeyserver.unsafeGet,
+ "--recv-keys", pgpKeys[index]))
+ else:
+ forkWait(() => execResult(gpgCmd,
+ "--recv-keys", pgpKeys[index]))))
if importCode == 0 or newSkipKeys or noconfirm:
keysLoop(index + 1, newSkipKeys)
diff --git a/src/pacman.nim b/src/pacman.nim
index 05abf51..58bf42b 100644
--- a/src/pacman.nim
+++ b/src/pacman.nim
@@ -356,8 +356,10 @@ proc obtainPacmanConfig*(args: seq[Argument]): PacmanConfig =
x <- y.split(',')), string].toSet
let hasKeyserver = forkWaitRedirect(() => (block:
- dropPrivileges()
- execResult(gpgConfCmd, "--list-options", "gpg")))
+ if dropPrivileges():
+ execResult(gpgConfCmd, "--list-options", "gpg")
+ else:
+ quit(1)))
.output
.filter(s => s.len > 10 and s[0 .. 9] == "keyserver:" and not (s[^2] == ':'))
.len > 0
diff --git a/src/utils.nim b/src/utils.nim
index 7cbf184..b480ce9 100644
--- a/src/utils.nim
+++ b/src/utils.nim
@@ -253,13 +253,17 @@ except:
proc canDropPrivileges*(): bool =
initialUser.isSome
-proc dropPrivileges*() =
+proc dropPrivileges*(): bool =
if initialUser.isSome:
let user = initialUser.unsafeGet
var groups = user.groups.map(x => x.cint)
- discard setgroups(user.groups.len, addr(groups[0]));
- discard setgid((Gid) user.gid)
- discard setuid((Uid) user.uid)
+
+ if setgroups(user.groups.len, addr(groups[0])) < 0:
+ return false
+ if setgid((Gid) user.gid) != 0:
+ return false
+ if setuid((Uid) user.uid) != 0:
+ return false
template replaceExisting(name: string, value: string) =
if cgetenv(name) != nil:
@@ -277,6 +281,10 @@ proc dropPrivileges*() =
discard cunsetenv("SUDO_GID")
discard cunsetenv("PKEXEC_UID")
+ return true
+ else:
+ return true
+
var intSigact: SigAction
intSigact.sa_handler = SIG_DFL
discard sigaction(SIGINT, intSigact)