secretmem: Prevent secretmem_users from wrapping to zero
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Mon, 25 Oct 2021 18:16:34 +0000 (19:16 +0100)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 25 Oct 2021 18:27:31 +0000 (11:27 -0700)
Commit 110860541f44 ("mm/secretmem: use refcount_t instead of atomic_t")
attempted to fix the problem of secretmem_users wrapping to zero and
allowing suspend once again.

But it was reverted in commit 87066fdd2e30 ("Revert 'mm/secretmem: use
refcount_t instead of atomic_t'") because of the problems it caused - a
refcount_t was not semantically the right type to use.

Instead prevent secretmem_users from wrapping to zero by forbidding new
users if the number of users has wrapped from positive to negative.
This stops a long way short of reaching the necessary 4 billion users
where it wraps to zero again, so there's no need to be clever with
special anti-wrap types or checking the return value from atomic_inc().

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Jordy Zomer <jordy@pwning.systems>
Cc: Kees Cook <keescook@chromium.org>,
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/secretmem.c

index 030f02ddc7c1dc823bc284be22976df820e62404..c2dda408bb3620e651754fd45232e9b4be63944f 100644 (file)
@@ -203,6 +203,8 @@ SYSCALL_DEFINE1(memfd_secret, unsigned int, flags)
 
        if (flags & ~(SECRETMEM_FLAGS_MASK | O_CLOEXEC))
                return -EINVAL;
+       if (atomic_read(&secretmem_users) < 0)
+               return -ENFILE;
 
        fd = get_unused_fd_flags(flags & O_CLOEXEC);
        if (fd < 0)