1 |
Move ipc files to a .ipc subdirectory, with a setgid bit to |
2 |
prevent a lockfile group permission race. The lockfile function |
3 |
uses an appropriate open call with mode argument so that the |
4 |
lockfile is created atomically with both group ownership and |
5 |
group write bit. |
6 |
|
7 |
Bug: https://bugs.gentoo.org/468990 |
8 |
Signed-off-by: Zac Medico <zmedico@g.o> |
9 |
--- |
10 |
bin/ebuild-ipc.py | 6 +++--- |
11 |
bin/phase-functions.sh | 4 ++-- |
12 |
lib/_emerge/AbstractEbuildProcess.py | 4 ++-- |
13 |
lib/_emerge/EbuildIpcDaemon.py | 2 +- |
14 |
lib/portage/package/ebuild/prepare_build_dirs.py | 6 ++++++ |
15 |
lib/portage/tests/ebuild/test_doebuild_spawn.py | 1 + |
16 |
lib/portage/tests/ebuild/test_ipc_daemon.py | 6 +++--- |
17 |
7 files changed, 18 insertions(+), 11 deletions(-) |
18 |
|
19 |
diff --git a/bin/ebuild-ipc.py b/bin/ebuild-ipc.py |
20 |
index 4999c043a..c24ba6f58 100755 |
21 |
--- a/bin/ebuild-ipc.py |
22 |
+++ b/bin/ebuild-ipc.py |
23 |
@@ -138,9 +138,9 @@ class EbuildIpc: |
24 |
|
25 |
def __init__(self): |
26 |
self.fifo_dir = os.environ["PORTAGE_BUILDDIR"] |
27 |
- self.ipc_in_fifo = os.path.join(self.fifo_dir, ".ipc_in") |
28 |
- self.ipc_out_fifo = os.path.join(self.fifo_dir, ".ipc_out") |
29 |
- self.ipc_lock_file = os.path.join(self.fifo_dir, ".ipc_lock") |
30 |
+ self.ipc_in_fifo = os.path.join(self.fifo_dir, ".ipc", "in") |
31 |
+ self.ipc_out_fifo = os.path.join(self.fifo_dir, ".ipc", "out") |
32 |
+ self.ipc_lock_file = os.path.join(self.fifo_dir, ".ipc", "lock") |
33 |
|
34 |
def _daemon_is_alive(self): |
35 |
try: |
36 |
diff --git a/bin/phase-functions.sh b/bin/phase-functions.sh |
37 |
index d3221993d..5eb031805 100644 |
38 |
--- a/bin/phase-functions.sh |
39 |
+++ b/bin/phase-functions.sh |
40 |
@@ -291,10 +291,10 @@ __dyn_clean() { |
41 |
rm -f "$PORTAGE_BUILDDIR"/.{ebuild_changed,logid,pretended,setuped,unpacked,prepared} \ |
42 |
"$PORTAGE_BUILDDIR"/.{configured,compiled,tested,packaged,instprepped} \ |
43 |
"$PORTAGE_BUILDDIR"/.die_hooks \ |
44 |
- "$PORTAGE_BUILDDIR"/.ipc_{in,out,lock} \ |
45 |
"$PORTAGE_BUILDDIR"/.exit_status |
46 |
|
47 |
- rm -rf "${PORTAGE_BUILDDIR}/build-info" |
48 |
+ rm -rf "${PORTAGE_BUILDDIR}/build-info" \ |
49 |
+ "${PORTAGE_BUILDDIR}/.ipc" |
50 |
rm -rf "${WORKDIR}" |
51 |
rm -f "${PORTAGE_BUILDDIR}/files" |
52 |
fi |
53 |
diff --git a/lib/_emerge/AbstractEbuildProcess.py b/lib/_emerge/AbstractEbuildProcess.py |
54 |
index 1b4e7759f..6d89d40f0 100644 |
55 |
--- a/lib/_emerge/AbstractEbuildProcess.py |
56 |
+++ b/lib/_emerge/AbstractEbuildProcess.py |
57 |
@@ -249,8 +249,8 @@ class AbstractEbuildProcess(SpawnProcess): |
58 |
|
59 |
def _init_ipc_fifos(self): |
60 |
|
61 |
- input_fifo = os.path.join(self.settings["PORTAGE_BUILDDIR"], ".ipc_in") |
62 |
- output_fifo = os.path.join(self.settings["PORTAGE_BUILDDIR"], ".ipc_out") |
63 |
+ input_fifo = os.path.join(self.settings["PORTAGE_BUILDDIR"], ".ipc", "in") |
64 |
+ output_fifo = os.path.join(self.settings["PORTAGE_BUILDDIR"], ".ipc", "out") |
65 |
|
66 |
for p in (input_fifo, output_fifo): |
67 |
|
68 |
diff --git a/lib/_emerge/EbuildIpcDaemon.py b/lib/_emerge/EbuildIpcDaemon.py |
69 |
index ee6fd7658..78594ff0a 100644 |
70 |
--- a/lib/_emerge/EbuildIpcDaemon.py |
71 |
+++ b/lib/_emerge/EbuildIpcDaemon.py |
72 |
@@ -81,7 +81,7 @@ class EbuildIpcDaemon(FifoIpcDaemon): |
73 |
# write something to the pipe just before we close it, and in that |
74 |
# case the write will be lost. Therefore, try for a non-blocking |
75 |
# lock, and only re-open the pipe if the lock is acquired. |
76 |
- lock_filename = os.path.join(os.path.dirname(self.input_fifo), ".ipc_lock") |
77 |
+ lock_filename = os.path.join(os.path.dirname(self.input_fifo), "lock") |
78 |
try: |
79 |
lock_obj = lockfile(lock_filename, unlinkfile=True, flags=os.O_NONBLOCK) |
80 |
except TryAgain: |
81 |
diff --git a/lib/portage/package/ebuild/prepare_build_dirs.py b/lib/portage/package/ebuild/prepare_build_dirs.py |
82 |
index 659198905..9d2474fd8 100644 |
83 |
--- a/lib/portage/package/ebuild/prepare_build_dirs.py |
84 |
+++ b/lib/portage/package/ebuild/prepare_build_dirs.py |
85 |
@@ -102,6 +102,12 @@ def prepare_build_dirs(myroot=None, settings=None, cleanup=False): |
86 |
apply_secpass_permissions( |
87 |
mysettings[dir_key], uid=portage_uid, gid=portage_gid |
88 |
) |
89 |
+ # The setgid bit prevents a lockfile group permission race for bug #468990. |
90 |
+ ensure_dirs( |
91 |
+ os.path.join(mysettings["PORTAGE_BUILDDIR"], ".ipc"), |
92 |
+ gid=portage_gid, |
93 |
+ mode=0o2770, |
94 |
+ ) |
95 |
except PermissionDenied as e: |
96 |
writemsg(_("Permission Denied: %s\n") % str(e), noiselevel=-1) |
97 |
return 1 |
98 |
diff --git a/lib/portage/tests/ebuild/test_doebuild_spawn.py b/lib/portage/tests/ebuild/test_doebuild_spawn.py |
99 |
index ef0ae5847..d142ec41e 100644 |
100 |
--- a/lib/portage/tests/ebuild/test_doebuild_spawn.py |
101 |
+++ b/lib/portage/tests/ebuild/test_doebuild_spawn.py |
102 |
@@ -81,6 +81,7 @@ class DoebuildSpawnTestCase(TestCase): |
103 |
settings["T"] = os.path.join(settings["PORTAGE_BUILDDIR"], "temp") |
104 |
for x in ("PORTAGE_BUILDDIR", "HOME", "T"): |
105 |
os.makedirs(settings[x]) |
106 |
+ os.makedirs(os.path.join(settings["PORTAGE_BUILDDIR"], ".ipc")) |
107 |
# Create a fake environment, to pretend as if the ebuild |
108 |
# has been sourced already. |
109 |
open(os.path.join(settings["T"], "environment"), "wb").close() |
110 |
diff --git a/lib/portage/tests/ebuild/test_ipc_daemon.py b/lib/portage/tests/ebuild/test_ipc_daemon.py |
111 |
index e20b6fff1..0ac3d3c32 100644 |
112 |
--- a/lib/portage/tests/ebuild/test_ipc_daemon.py |
113 |
+++ b/lib/portage/tests/ebuild/test_ipc_daemon.py |
114 |
@@ -66,10 +66,10 @@ class IpcDaemonTestCase(TestCase): |
115 |
|
116 |
build_dir = EbuildBuildDir(scheduler=event_loop, settings=env) |
117 |
event_loop.run_until_complete(build_dir.async_lock()) |
118 |
- ensure_dirs(env["PORTAGE_BUILDDIR"]) |
119 |
+ ensure_dirs(os.path.join(env["PORTAGE_BUILDDIR"], ".ipc")) |
120 |
|
121 |
- input_fifo = os.path.join(env["PORTAGE_BUILDDIR"], ".ipc_in") |
122 |
- output_fifo = os.path.join(env["PORTAGE_BUILDDIR"], ".ipc_out") |
123 |
+ input_fifo = os.path.join(env["PORTAGE_BUILDDIR"], ".ipc", "in") |
124 |
+ output_fifo = os.path.join(env["PORTAGE_BUILDDIR"], ".ipc", "out") |
125 |
os.mkfifo(input_fifo) |
126 |
os.mkfifo(output_fifo) |
127 |
|
128 |
-- |
129 |
2.32.0 |