diff options
Diffstat (limited to 'fs/locks.c')
| -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. |
