Skip to content

install: finalize ownership before mode, and skip the mode if chown fails - #13629

Open
sylvestre wants to merge 1 commit into
uutils:mainfrom
sylvestre:install-chown-before-chmod
Open

install: finalize ownership before mode, and skip the mode if chown fails#13629
sylvestre wants to merge 1 commit into
uutils:mainfrom
sylvestre:install-chown-before-chmod

Conversation

@sylvestre

Copy link
Copy Markdown
Contributor

set_ownership_and_permissions applied the mode -- including setuid/setgid -- and only then attempted the chown, with no rollback on failure. A failed ownership change therefore left the destination as a setuid file owned by the installing user. install -d had the same ordering.

@sylvestre
sylvestre force-pushed the install-chown-before-chmod branch from f799e90 to 24a02f8 Compare July 29, 2026 08:09
…ails

set_ownership_and_permissions applied the mode -- including setuid/setgid --
and only then attempted the chown, with no rollback on failure. A failed
ownership change therefore left the destination as a setuid file owned by the
installing user. install -d had the same ordering.

Reproducible unprivileged, no race needed:

  $ install -m 4755 -o root src dst
  GNU 9.10 : cannot change ownership of 'dst'  -> dst is 600, no setuid
  uutils   : chown failed                      -> dst is 4755, setuid

Swap the order, matching GNU: chown first, and skip the chmod when it fails.
This also fixes a second, quieter bug -- chown(2) clears setuid/setgid, so
chmod-then-chown silently dropped those bits from successfully installed files.

The mode is still applied in full when no ownership change is requested.
@sylvestre
sylvestre force-pushed the install-chown-before-chmod branch from 24a02f8 to e0ed8e3 Compare July 29, 2026 08:42
@github-actions

Copy link
Copy Markdown

GNU testsuite comparison:

Skip an intermittent issue tests/date/date-locale-hour (fails in this run but passes in the 'main' branch)
Skip an intermittent issue tests/misc/io-errors (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/date/resolution (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/retry (passes in this run but fails in the 'main' branch)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant