summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2022-02-14 04:42:30 +0100
committerAl Viro <viro@zeniv.linux.org.uk>2022-02-14 04:42:30 +0100
commit124f75f864f38327e3e7e182e6b6da5105e2bade (patch)
treef861c6dfec15a97b5c6200d89cd9fb18132aac80 /fs
parentseq_file: fix NULL pointer arithmetic warning (diff)
downloadlinux-124f75f864f38327e3e7e182e6b6da5105e2bade.tar.xz
linux-124f75f864f38327e3e7e182e6b6da5105e2bade.zip
clean overflow checks in count_mounts() a bit
Wraparound checks in there are redundant (x + y < x and x + y < y are equivalent when x and y are both unsigned int). IMO more straightforward code would be better here... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/namespace.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 13d025a9ecf5..42d4fc21263b 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2069,22 +2069,23 @@ static int invent_group_ids(struct mount *mnt, bool recurse)
int count_mounts(struct mnt_namespace *ns, struct mount *mnt)
{
unsigned int max = READ_ONCE(sysctl_mount_max);
- unsigned int mounts = 0, old, pending, sum;
+ unsigned int mounts = 0;
struct mount *p;
+ if (ns->mounts >= max)
+ return -ENOSPC;
+ max -= ns->mounts;
+ if (ns->pending_mounts >= max)
+ return -ENOSPC;
+ max -= ns->pending_mounts;
+
for (p = mnt; p; p = next_mnt(p, mnt))
mounts++;
- old = ns->mounts;
- pending = ns->pending_mounts;
- sum = old + pending;
- if ((old > sum) ||
- (pending > sum) ||
- (max < sum) ||
- (mounts > (max - sum)))
+ if (mounts > max)
return -ENOSPC;
- ns->pending_mounts = pending + mounts;
+ ns->pending_mounts += mounts;
return 0;
}