Skip to content

Commit

Permalink
lib/repo: Ensure min-free-space* config value doesn't overflow
Browse files Browse the repository at this point in the history
when converted to bytes

In a subsequent commit, we add a public API to read the value of
min-free-space-* value in bytes. The value for free space check
is enforced in terms of block size instead of bytes. Therefore,
for consistency we check while preparing the transaction that the
value doesn't overflow when converted to bytes.

https://phabricator.endlessm.com/T23694

Closes: ostreedev#1715
Approved by: cgwalters
  • Loading branch information
Umang Jain authored and rh-atomic-bot committed Sep 4, 2018
1 parent 74bdf7e commit 3814d07
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 9 deletions.
28 changes: 19 additions & 9 deletions src/libostree/ostree-repo-commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1536,23 +1536,28 @@ devino_cache_lookup (OstreeRepo *self,
return dev_ino_val->checksum;
}

static guint64
min_free_space_calculate_reserved_blocks (OstreeRepo *self, struct statvfs *stvfsbuf)
static gboolean
min_free_space_calculate_reserved_blocks (OstreeRepo *self, struct statvfs *stvfsbuf, GError **error)
{
guint64 reserved_blocks = 0;
self->reserved_blocks = 0;

if (self->min_free_space_mb > 0)
{
reserved_blocks = (self->min_free_space_mb << 20) / stvfsbuf->f_bsize;
if (self->min_free_space_mb > (G_MAXUINT64 >> 20) ||
self->txn.blocksize > (1 << 20))
return glnx_throw (error, "min-free-space value is greater than the maximum allowed value of %" G_GUINT64_FORMAT " bytes",
G_MAXUINT64 / stvfsbuf->f_bsize);

self->reserved_blocks = (self->min_free_space_mb << 20) / self->txn.blocksize;
}
else if (self->min_free_space_percent > 0)
{
/* Convert fragment to blocks to compute the total */
guint64 total_blocks = (stvfsbuf->f_frsize * stvfsbuf->f_blocks) / stvfsbuf->f_bsize;
reserved_blocks = ((double)total_blocks) * (self->min_free_space_percent/100.0);
self->reserved_blocks = ((double)total_blocks) * (self->min_free_space_percent/100.0);
}

return reserved_blocks;
return TRUE;
}

/**
Expand Down Expand Up @@ -1650,11 +1655,16 @@ ostree_repo_prepare_transaction (OstreeRepo *self,

g_mutex_lock (&self->txn_lock);
self->txn.blocksize = stvfsbuf.f_bsize;
guint64 reserved_blocks = min_free_space_calculate_reserved_blocks (self, &stvfsbuf);
if (!min_free_space_calculate_reserved_blocks (self, &stvfsbuf, error))
{
g_mutex_unlock (&self->txn_lock);
return FALSE;
}

/* Use the appropriate free block count if we're unprivileged */
guint64 bfree = (getuid () != 0 ? stvfsbuf.f_bavail : stvfsbuf.f_bfree);
if (bfree > reserved_blocks)
self->txn.max_blocks = bfree - reserved_blocks;
if (bfree > self->reserved_blocks)
self->txn.max_blocks = bfree - self->reserved_blocks;
else
{
self->cleanup_stagedir = TRUE;
Expand Down
1 change: 1 addition & 0 deletions src/libostree/ostree-repo-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ struct OstreeRepo {
gid_t target_owner_gid;
guint min_free_space_percent; /* See the min-free-space-percent config option */
guint64 min_free_space_mb; /* See the min-free-space-size config option */
guint64 reserved_blocks;
gboolean cleanup_stagedir;

guint test_error_flags; /* OstreeRepoTestErrorFlags */
Expand Down

0 comments on commit 3814d07

Please sign in to comment.