Skip to content

Commit 4adbf1d

Browse files
committed
Fix: blocking O_NONBLOCK process bug in sleep.c
There is a subtle bug that if the atomic flag changes between the time it was checked and the second time it was checked, sleep.c would potentially block a process that had specified O_NONBLOCK. This fixes the bug by using atomic_cmpxchg instead of atomic_read.
1 parent 84cc7fe commit 4adbf1d

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

examples/sleep.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,18 @@ static DECLARE_WAIT_QUEUE_HEAD(waitq);
9292
/* Called when the /proc file is opened */
9393
static int module_open(struct inode *inode, struct file *file)
9494
{
95+
/* Try to get without blocking */
96+
if (!atomic_cmpxchg(&already_open, 0, 1)) {
97+
/* Success without blocking, allow the access */
98+
try_module_get(THIS_MODULE);
99+
return 0;
100+
}
95101
/* If the file's flags include O_NONBLOCK, it means the process does not
96-
* want to wait for the file. In this case, if the file is already open,
102+
* want to wait for the file. In this case, because the file is already open,
97103
* we should fail with -EAGAIN, meaning "you will have to try again",
98104
* instead of blocking a process which would rather stay awake.
99105
*/
100-
if ((file->f_flags & O_NONBLOCK) && atomic_read(&already_open))
106+
if (file->f_flags & O_NONBLOCK)
101107
return -EAGAIN;
102108

103109
/* This is the correct place for try_module_get(THIS_MODULE) because if

0 commit comments

Comments
 (0)