Skip to content

Commit

Permalink
Ensure %rmbuild doesn't fail due to permissions in the built content
Browse files Browse the repository at this point in the history
Packages may contain files without write permissions, read-only sources
and whatnot. Run %_fixperms on the whole builddir before trying to
remove it to ensure we don't fail doing our household duties, both
on post-cleanup but also before trying to remove an old run, as
eg 'rpmbuild -bi' will not run cleanup.

It's worth noting that prior to b5f6c64
the build could similarly fail while running it's default %clean.
If we hadn't removeed the default %clean, we'd have to do this
permission fixup first redundantly for the build root and then for the
rest of the %builddir.

Also worth noting is that the added test doesn't actually reproduce the
issue in the test-suite because it runs as root and root is not bothered
by such petty issues as missing read/write permissions to remove. But
at least we have a reproducer for the case once #3005 is done.

Fixes: #2519
  • Loading branch information
pmatilai committed Apr 4, 2024
1 parent 1153ccd commit c751b54
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 0 deletions.
8 changes: 8 additions & 0 deletions build/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,11 @@ rpmRC doScript(rpmSpec spec, rpmBuildFlags what, const char *name,
fprintf(fp, "cd '%s'\n", buildSubdir);

if (what == RPMBUILD_RMBUILD) {
char *fix = rpmExpand("%{_fixperms}", NULL);
fprintf(fp, "test -d '%s' && %s '%s'\n",
spec->buildDir, fix, spec->buildDir);
fprintf(fp, "rm -rf '%s'\n", spec->buildDir);
free(fix);
} else if (sb != NULL)
fprintf(fp, "%s", sb);

Expand Down Expand Up @@ -307,7 +311,10 @@ static int doCheckBuildRequires(rpmts ts, rpmSpec spec, int test)

static rpmRC doBuildDir(rpmSpec spec, int test, StringBuf *sbp)
{
char *fix = rpmExpand("%{_fixperms}", NULL);
char *doDir = rstrscat(NULL,
"test -d '", spec->buildDir, "' && ",
fix, " '", spec->buildDir, "'\n",
"rm -rf '", spec->buildDir, "'\n",
"mkdir -p '", spec->buildDir, "'\n",
NULL);
Expand All @@ -320,6 +327,7 @@ static rpmRC doBuildDir(rpmSpec spec, int test, StringBuf *sbp)
spec->buildDir, strerror(errno));
}
free(doDir);
free(fix);
return rc;
}

Expand Down
22 changes: 22 additions & 0 deletions tests/data/SPECS/noperms.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Name: noperms
Version: 1.0
Release: 1
License: Public Domain
Summary: Test read-only files in build

%description
%{summary}

%prep
%setup -c -T

%build
mkdir bad
touch bad/foo
chmod a-w bad

%install
cp -avp . ${RPM_BUILD_ROOT}

%files
/bad
16 changes: 16 additions & 0 deletions tests/rpmbuild.at
Original file line number Diff line number Diff line change
Expand Up @@ -2957,3 +2957,19 @@ runroot rpmbuild --quiet -bb /data/SPECS/bpf.spec
[],
[])
RPMTEST_CLEANUP

# XXX this always succeeds when rpmbuild is run as root so the test is
# kinda meaningless until #3005 is done, but works as a manual reproducer.
AT_SETUP([rpmbuild non-removable file in builddir])
AT_KEYWORDS([build])
RPMDB_INIT

# -bi doesn't run cleanup, test that we manage that situation too
RPMTEST_CHECK([
runroot rpmbuild --quiet -bi /data/SPECS/noperms.spec
runroot rpmbuild --quiet -bb /data/SPECS/noperms.spec
],
[0],
[],
[])
RPMTEST_CLEANUP

0 comments on commit c751b54

Please sign in to comment.