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. |