All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: kernelfans@gmail.com
Cc: linux-pm@vger.kernel.org
Subject: [bug report] PM / reboot: Eliminate race between reboot and suspend
Date: Tue, 19 Nov 2019 09:18:54 +0300	[thread overview]
Message-ID: <20191119052701.fcbfdpdhylqpdyye@kili.mountain> (raw)

Hello Pingfan Liu,

The patch 55f2503c3b69: "PM / reboot: Eliminate race between reboot
and suspend" from Jul 31, 2018, leads to the following static checker
warning:

	kernel/reboot.c:395 __do_sys_reboot()
	error: double unlocked 'system_transition_mutex' (orig line 387)

kernel/reboot.c
   310  SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
   311                  void __user *, arg)
   312  {
   313          struct pid_namespace *pid_ns = task_active_pid_ns(current);
   314          char buffer[256];
   315          int ret = 0;
   316  
   317          /* We only trust the superuser with rebooting the system. */
   318          if (!ns_capable(pid_ns->user_ns, CAP_SYS_BOOT))
   319                  return -EPERM;
   320  
   321          /* For safety, we require "magic" arguments. */
   322          if (magic1 != LINUX_REBOOT_MAGIC1 ||
   323                          (magic2 != LINUX_REBOOT_MAGIC2 &&
   324                          magic2 != LINUX_REBOOT_MAGIC2A &&
   325                          magic2 != LINUX_REBOOT_MAGIC2B &&
   326                          magic2 != LINUX_REBOOT_MAGIC2C))
   327                  return -EINVAL;
   328  
   329          /*
   330           * If pid namespaces are enabled and the current task is in a child
   331           * pid_namespace, the command is handled by reboot_pid_ns() which will
   332           * call do_exit().
   333           */
   334          ret = reboot_pid_ns(pid_ns, cmd);
   335          if (ret)
   336                  return ret;
   337  
   338          /* Instead of trying to make the power_off code look like
   339           * halt when pm_power_off is not set do it the easy way.
   340           */
   341          if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
   342                  cmd = LINUX_REBOOT_CMD_HALT;
   343  
   344          mutex_lock(&system_transition_mutex);
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This used to be reboot_mutex.

   345          switch (cmd) {
   346          case LINUX_REBOOT_CMD_RESTART:
   347                  kernel_restart(NULL);
   348                  break;
   349  
   350          case LINUX_REBOOT_CMD_CAD_ON:
   351                  C_A_D = 1;
   352                  break;
   353  
   354          case LINUX_REBOOT_CMD_CAD_OFF:
   355                  C_A_D = 0;
   356                  break;
   357  
   358          case LINUX_REBOOT_CMD_HALT:
   359                  kernel_halt();
   360                  do_exit(0);
   361                  panic("cannot halt");
   362  
   363          case LINUX_REBOOT_CMD_POWER_OFF:
   364                  kernel_power_off();
   365                  do_exit(0);
   366                  break;
   367  
   368          case LINUX_REBOOT_CMD_RESTART2:
   369                  ret = strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1);
   370                  if (ret < 0) {
   371                          ret = -EFAULT;
   372                          break;
   373                  }
   374                  buffer[sizeof(buffer) - 1] = '\0';
   375  
   376                  kernel_restart(buffer);
   377                  break;
   378  
   379  #ifdef CONFIG_KEXEC_CORE
   380          case LINUX_REBOOT_CMD_KEXEC:
   381                  ret = kernel_kexec();
   382                  break;
   383  #endif
   384  
   385  #ifdef CONFIG_HIBERNATION
   386          case LINUX_REBOOT_CMD_SW_SUSPEND:
   387                  ret = hibernate();
                        ^^^^^^^^^^^^^^^^^
The first thing that hibernate() does is call lock_system_sleep() which
use to take the pm_mutex, but now it takes system_transition_mutex so
it will just hang forever.

   388                  break;
   389  #endif
   390  
   391          default:
   392                  ret = -EINVAL;
   393                  break;
   394          }
   395          mutex_unlock(&system_transition_mutex);
   396          return ret;
   397  }

regards,
dan carpenter

             reply	other threads:[~2019-11-19  6:19 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-19  6:18 Dan Carpenter [this message]
2020-11-18 18:59 [bug report] PM / reboot: Eliminate race between reboot and suspend Dan Carpenter
2020-11-18 18:59 ` Dan Carpenter
2021-01-20  9:30 ` Baoquan He
2021-01-20  9:30   ` Baoquan He
2021-01-21  9:10   ` Pingfan Liu
2021-01-21  9:10     ` Pingfan Liu
2021-01-21 14:42     ` Rafael J. Wysocki
2021-01-21 14:42       ` Rafael J. Wysocki
2021-01-22  7:38       ` Baoquan He
2021-01-22  7:38         ` Baoquan He

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191119052701.fcbfdpdhylqpdyye@kili.mountain \
    --to=dan.carpenter@oracle.com \
    --cc=kernelfans@gmail.com \
    --cc=linux-pm@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.