In a Linux user namespace, as non-root, I bind mount /tmp/foo to itself.  This succeeds.
Then, I try to remount /tmp/foo to be read-only.  If /tmp is mounted with nosuid or nodev, then the remount fails.  Otherwise, the remount succeeds.
Is there some reason why nosuid and/or nodev prevent the remount from succeeding?  Is this behavior documented somewhere?  I'm puzzled, as I would expect the bind mount and remount to either both succeed, or both fail.
Here is the code to reproduce the bind mount and remount:
#define   _GNU_SOURCE      /*  unshare   */
#include  <errno.h>        /*  errno     */
#include  <sched.h>        /*  unshare   */
#include  <stdio.h>        /*  printf    */
#include  <string.h>       /*  strerror  */
#include  <sys/mount.h>    /*  mount     */
#include  <unistd.h>       /*  getuid    */
int main() {
  printf ( "getuid   %d\n", getuid() );
  int rv = unshare ( CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWUSER );
  printf ( "unshare  %2d  %s\n", rv, strerror(errno) );
  rv = mount ( "/tmp/foo", "/tmp/foo", 0, MS_BIND | MS_REC, 0 ),
  printf ( "mount    %2d  %s\n", rv, strerror(errno) );
  rv = mount ( "/tmp/foo", "/tmp/foo", 0,
               MS_BIND | MS_REMOUNT | MS_RDONLY, 0 ),
  printf ( "remount  %2d  %s\n", rv, strerror(errno) );
  return  0;
}
Sample output:
$  mkdir -p /tmp/foo
$  mount | grep /tmp
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,relatime,inode64)
$  gcc test.c && ./a.out
getuid   1000
unshare   0  No error information
mount     0  No error information
remount  -1  Operation not permitted
$  uname -a
Linux hostname 5.12.12_1 #1 SMP 1624132767 x86_64 GNU/Linux
Whereas, if /tmp is mounted with neither nosuid nor nodev, then the bind mount and the remount will both succeed, as follows:
$  mkdir -p /tmp/foo
$  mount | grep /tmp
tmpfs on /tmp type tmpfs (rw,relatime,inode64)
$  gcc test.c && ./a.out
getuid   1000
unshare   0  No error information
mount     0  No error information
remount   0  No error information