diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-05-12 22:33:09 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-05-12 22:33:09 -0400 |
| commit | 14186fea0cb06bc43181ce239efe0df6f1af260a (patch) | |
| tree | 4c58c5747529b74502352b185515af43e26c0666 | |
| parent | 77d92784b46549e00f7b99794cd566045ded62ba (diff) | |
| parent | cf01f4eef9fe367ec0d85b38dd7214e29e376cdb (diff) | |
Merge tag 'locks-v3.15-4' of git://git.samba.org/jlayton/linux
Pull file locking fix from Jeff Layton:
"Fix for regression in handling of F_GETLK commands"
* tag 'locks-v3.15-4' of git://git.samba.org/jlayton/linux:
locks: only validate the lock vs. f_mode in F_SETLK codepaths
| -rw-r--r-- | fs/locks.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/fs/locks.c b/fs/locks.c index e663aeac579e..e390bd9ae068 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
| @@ -389,18 +389,6 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, | |||
| 389 | fl->fl_ops = NULL; | 389 | fl->fl_ops = NULL; |
| 390 | fl->fl_lmops = NULL; | 390 | fl->fl_lmops = NULL; |
| 391 | 391 | ||
| 392 | /* Ensure that fl->fl_filp has compatible f_mode */ | ||
| 393 | switch (l->l_type) { | ||
| 394 | case F_RDLCK: | ||
| 395 | if (!(filp->f_mode & FMODE_READ)) | ||
| 396 | return -EBADF; | ||
| 397 | break; | ||
| 398 | case F_WRLCK: | ||
| 399 | if (!(filp->f_mode & FMODE_WRITE)) | ||
| 400 | return -EBADF; | ||
| 401 | break; | ||
| 402 | } | ||
| 403 | |||
| 404 | return assign_type(fl, l->l_type); | 392 | return assign_type(fl, l->l_type); |
| 405 | } | 393 | } |
| 406 | 394 | ||
| @@ -2034,6 +2022,22 @@ static int do_lock_file_wait(struct file *filp, unsigned int cmd, | |||
| 2034 | return error; | 2022 | return error; |
| 2035 | } | 2023 | } |
| 2036 | 2024 | ||
| 2025 | /* Ensure that fl->fl_filp has compatible f_mode for F_SETLK calls */ | ||
| 2026 | static int | ||
| 2027 | check_fmode_for_setlk(struct file_lock *fl) | ||
| 2028 | { | ||
| 2029 | switch (fl->fl_type) { | ||
| 2030 | case F_RDLCK: | ||
| 2031 | if (!(fl->fl_file->f_mode & FMODE_READ)) | ||
| 2032 | return -EBADF; | ||
| 2033 | break; | ||
| 2034 | case F_WRLCK: | ||
| 2035 | if (!(fl->fl_file->f_mode & FMODE_WRITE)) | ||
| 2036 | return -EBADF; | ||
| 2037 | } | ||
| 2038 | return 0; | ||
| 2039 | } | ||
| 2040 | |||
| 2037 | /* Apply the lock described by l to an open file descriptor. | 2041 | /* Apply the lock described by l to an open file descriptor. |
| 2038 | * This implements both the F_SETLK and F_SETLKW commands of fcntl(). | 2042 | * This implements both the F_SETLK and F_SETLKW commands of fcntl(). |
| 2039 | */ | 2043 | */ |
| @@ -2071,6 +2075,10 @@ again: | |||
| 2071 | if (error) | 2075 | if (error) |
| 2072 | goto out; | 2076 | goto out; |
| 2073 | 2077 | ||
| 2078 | error = check_fmode_for_setlk(file_lock); | ||
| 2079 | if (error) | ||
| 2080 | goto out; | ||
| 2081 | |||
| 2074 | /* | 2082 | /* |
| 2075 | * If the cmd is requesting file-private locks, then set the | 2083 | * If the cmd is requesting file-private locks, then set the |
| 2076 | * FL_OFDLCK flag and override the owner. | 2084 | * FL_OFDLCK flag and override the owner. |
| @@ -2206,6 +2214,10 @@ again: | |||
| 2206 | if (error) | 2214 | if (error) |
| 2207 | goto out; | 2215 | goto out; |
| 2208 | 2216 | ||
| 2217 | error = check_fmode_for_setlk(file_lock); | ||
| 2218 | if (error) | ||
| 2219 | goto out; | ||
| 2220 | |||
| 2209 | /* | 2221 | /* |
| 2210 | * If the cmd is requesting file-private locks, then set the | 2222 | * If the cmd is requesting file-private locks, then set the |
| 2211 | * FL_OFDLCK flag and override the owner. | 2223 | * FL_OFDLCK flag and override the owner. |
