Commit 5b6f1eb9 authored by Alain Knaff's avatar Alain Knaff Committed by Al Viro
Browse files

vfs: lseek(fd, 0, SEEK_CUR) race condition

This patch fixes a race condition in lseek. While it is expected that
unpredictable behaviour may result while repositioning the offset of a
file descriptor concurrently with reading/writing to the same file
descriptor, this should not happen when merely *reading* the file
descriptor's offset.

Unfortunately, the only portable way in Unix to read a file
descriptor's offset is lseek(fd, 0, SEEK_CUR); however executing this
concurrently with read/write may mess up the position.

[with fixes from akpm]
Signed-off-by: default avatarAlain Knaff <>
Signed-off-by: default avatarAndrew Morton <>
Signed-off-by: default avatarAl Viro <>
parent 7d3b56ba
......@@ -50,6 +50,14 @@ generic_file_llseek_unlocked(struct file *file, loff_t offset, int origin)
offset += inode->i_size;
case SEEK_CUR:
* Here we special-case the lseek(fd, 0, SEEK_CUR)
* position-querying operation. Avoid rewriting the "same"
* f_pos value back to the file because a concurrent read(),
* write() or lseek() might have altered it
if (offset == 0)
return file->f_pos;
offset += file->f_pos;
......@@ -105,6 +113,10 @@ loff_t default_llseek(struct file *file, loff_t offset, int origin)
offset += i_size_read(file->f_path.dentry->d_inode);
case SEEK_CUR:
if (offset == 0) {
retval = file->f_pos;
goto out;
offset += file->f_pos;
retval = -EINVAL;
......@@ -115,6 +127,7 @@ loff_t default_llseek(struct file *file, loff_t offset, int origin)
retval = offset;
return retval;
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment