Skip to content

Commit

Permalink
classes/package_rpm: write file permissions and ownership explicitly …
Browse files Browse the repository at this point in the history
…into .spec

Per rpm-software-management/rpm@77d3529
rpm 4.19.1+ will not consider actual filesystem permissions and ownership, and will quietly default
to root if not expictly set otherwise in .spec file.

There's also additional diagnostics (printing what is in passwd/group)
when user/group name lookup against the sysroot fails.
That is never supposed to happen, and yet there was one report that it did:
https://autobuilder.yoctoproject.org/typhoon/#/builders/44/builds/8493/steps/23/logs/stdio

Investigating that issue led to the first three commits in this patchset:

sysroot user management postinsts: run with /bin/sh -e to report errors when they happen
classes/multilib: expand PACKAGE_WRITE_DEPS in addition to DEPENDS
classes/staging: capture output of sysroot postinsts into logs

(From OE-Core rev: a9db9a56617459e8f6f6dd466f2e18a7eed5c1e3)

Signed-off-by: Alexander Kanavin <alex@linutronix.de>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
  • Loading branch information
kanavin authored and rpurdie committed Jan 27, 2024
1 parent d00682a commit 347abb8
Showing 1 changed file with 28 additions and 6 deletions.
34 changes: 28 additions & 6 deletions meta/classes-global/package_rpm.bbclass
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ def write_rpm_perfiledata(srcname, d):

python write_specfile () {
import oe.packagedata
import os,pwd,grp,stat

# append information for logs and patches to %prep
def add_prep(d, spec_files_bottom):
Expand Down Expand Up @@ -198,6 +199,23 @@ python write_specfile () {
# of the walk, the isdir() test would then fail and the walk code would assume its a file
# hence we check for the names in files too.
for rootpath, dirs, files in os.walk(walkpath):
def get_attr(path):
stat_f = os.stat(rootpath + "/" + path, follow_symlinks=False)
mode = stat.S_IMODE(stat_f.st_mode)
try:
owner = pwd.getpwuid(stat_f.st_uid).pw_name
except Exception as e:
bb.error("Content of /etc/passwd in sysroot:\n{}".format(
open(d.getVar("RECIPE_SYSROOT") +"/etc/passwd").read()))
raise e
try:
group = grp.getgrgid(stat_f.st_gid).gr_name
except Exception as e:
bb.error("Content of /etc/group in sysroot:\n{}".format(
open(d.getVar("RECIPE_SYSROOT") +"/etc/group").read()))
raise e
return "%attr({:o},{},{}) ".format(mode, owner, group)

path = rootpath.replace(walkpath, "")
if path.endswith("DEBIAN") or path.endswith("CONTROL"):
continue
Expand All @@ -221,24 +239,28 @@ python write_specfile () {
if dir == "CONTROL" or dir == "DEBIAN":
continue
dir = dir.replace("%", "%%%%%%%%")
p = path + '/' + dir
# All packages own the directories their files are in...
target.append('%dir "' + path + '/' + dir + '"')
target.append(get_attr(dir) + '%dir "' + p + '"')
else:
# packages own only empty directories or explict directory.
# This will prevent the overlapping of security permission.
attr = get_attr(path)
if path and not files and not dirs:
target.append('%dir "' + path + '"')
target.append(attr + '%dir "' + path + '"')
elif path and path in dirfiles:
target.append('%dir "' + path + '"')
target.append(attr + '%dir "' + path + '"')

for file in files:
if file == "CONTROL" or file == "DEBIAN":
continue
file = file.replace("%", "%%%%%%%%")
if conffiles.count(path + '/' + file):
target.append('%config "' + path + '/' + file + '"')
attr = get_attr(file)
p = path + '/' + file
if conffiles.count(p):
target.append(attr + '%config "' + p + '"')
else:
target.append('"' + path + '/' + file + '"')
target.append(attr + '"' + p + '"')

# Prevent the prerm/postrm scripts from being run during an upgrade
def wrap_uninstall(scriptvar):
Expand Down

0 comments on commit 347abb8

Please sign in to comment.