Skip to content

Commit

Permalink
tmpfs: fix the issue that the mount and remount results are inconsist…
Browse files Browse the repository at this point in the history
…ent.

An undefined-behavior issue has not been completely fixed since commit
d14f5ef ("tmpfs: fix undefined-behaviour in shmem_reconfigure()"). 
In the commit, check in the shmem_reconfigure() is added in remount
process to avoid the Ubsan problem.  However, the check is not added to
the mount process.  It causes inconsistent results between mount and
remount.  The operations to reproduce the problem in user mode as follows:

If nr_blocks is set to 0x8000000000000000, the mounting is successful.

  # mount tmpfs /dev/shm/ -t tmpfs -o nr_blocks=0x8000000000000000

However, when -o remount is used, the mount fails because of the
check in the shmem_reconfigure()

  # mount tmpfs /dev/shm/ -t tmpfs -o remount,nr_blocks=0x8000000000000000
  mount: /dev/shm: mount point not mounted or bad option.

Therefore, add checks in the shmem_parse_one() function and remove the
check in shmem_reconfigure() to avoid this problem.

Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: ZhaoLong Wang <[email protected]>
Cc: Luo Meng <[email protected]>
Cc: Hugh Dickins <[email protected]>
Cc: Yu Kuai <[email protected]>
Cc: Zhihao Cheng <[email protected]>
Cc: Zhang Yi <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
  • Loading branch information
ZhaoLong Wang authored and akpm00 committed Jul 18, 2022
1 parent 07313a2 commit 0c98c8e
Showing 1 changed file with 2 additions and 5 deletions.
7 changes: 2 additions & 5 deletions mm/shmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -3392,7 +3392,7 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
break;
case Opt_nr_blocks:
ctx->blocks = memparse(param->string, &rest);
if (*rest)
if (*rest || ctx->blocks > S64_MAX)
goto bad_value;
ctx->seen |= SHMEM_SEEN_BLOCKS;
break;
Expand Down Expand Up @@ -3514,10 +3514,7 @@ static int shmem_reconfigure(struct fs_context *fc)

raw_spin_lock(&sbinfo->stat_lock);
inodes = sbinfo->max_inodes - sbinfo->free_inodes;
if (ctx->blocks > S64_MAX) {
err = "Number of blocks too large";
goto out;
}

if ((ctx->seen & SHMEM_SEEN_BLOCKS) && ctx->blocks) {
if (!sbinfo->max_blocks) {
err = "Cannot retroactively limit size";
Expand Down

0 comments on commit 0c98c8e

Please sign in to comment.