lib/repo: Skip import via hardlink if repo owners don't match

Before this, if one had repos of matching mode but different owners,
which could happen if one e.g. makes a `bare` non-root repo in
`/ostree/deploy/$stateroot/var/tmp`, every time we tried to call `linkat()`
we'd get `EPERM` and fall back to a copy.

Fix this by saving the repo owner uid, and avoid trying to call `linkat()` if we
know it's going to fail. Of course most commonly in this scenario we'll
immediately fail trying to `chown` the files to `0`, but this is prep for a
future patch to improve `bare-user` → `bare-user-only` imports where we'll be a
bit more sophisticated.

Closes: #922
Approved by: alexlarsson
This commit is contained in:
Colin Walters 2017-06-12 13:20:42 -04:00 committed by Atomic Bot
parent 21eec96bfd
commit 695771667c
2 changed files with 10 additions and 2 deletions

View File

@ -116,6 +116,7 @@ struct OstreeRepo {
GHashTable *updated_uncompressed_dirs;
GHashTable *object_sizes;
uid_t owner_uid;
uid_t target_owner_uid;
gid_t target_owner_gid;

View File

@ -2092,6 +2092,7 @@ ostree_repo_open (OstreeRepo *self,
if (fstat (self->objects_dir_fd, &stbuf) != 0)
return glnx_throw_errno (error);
self->owner_uid = stbuf.st_uid;
if (stbuf.st_uid != getuid () || stbuf.st_gid != getgid ())
{
@ -3168,8 +3169,14 @@ ostree_repo_import_object_from_with_trust (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
if (trusted && /* Don't hardlink into untrusted remotes */
self->mode == source->mode)
/* We try to import via hardlink. If the remote is explicitly not trusted
* (i.e.) their checksums may be incorrect, we skip that. Also, we require the
* repository modes to match, as well as the owner uid (since we need to be
* able to make hardlinks).
*/
if (trusted &&
self->mode == source->mode &&
self->owner_uid == source->owner_uid)
{
gboolean hardlink_was_supported = FALSE;