| From 2ebc3464781ad24474abcbd2274e6254689853b5 Mon Sep 17 00:00:00 2001 |
| From: Dan Rosenberg <dan.j.rosenberg@gmail.com> |
| Date: Mon, 19 Jul 2010 16:58:20 -0400 |
| Subject: Btrfs: fix checks in BTRFS_IOC_CLONE_RANGE |
| |
| From: Dan Rosenberg <dan.j.rosenberg@gmail.com> |
| |
| commit 2ebc3464781ad24474abcbd2274e6254689853b5 upstream. |
| |
| 1. The BTRFS_IOC_CLONE and BTRFS_IOC_CLONE_RANGE ioctls should check |
| whether the donor file is append-only before writing to it. |
| |
| 2. The BTRFS_IOC_CLONE_RANGE ioctl appears to have an integer |
| overflow that allows a user to specify an out-of-bounds range to copy |
| from the source file (if off + len wraps around). I haven't been able |
| to successfully exploit this, but I'd imagine that a clever attacker |
| could use this to read things he shouldn't. Even if it's not |
| exploitable, it couldn't hurt to be safe. |
| |
| Signed-off-by: Dan Rosenberg <dan.j.rosenberg@gmail.com> |
| Signed-off-by: Chris Mason <chris.mason@oracle.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| fs/btrfs/ioctl.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/fs/btrfs/ioctl.c |
| +++ b/fs/btrfs/ioctl.c |
| @@ -952,7 +952,7 @@ static noinline long btrfs_ioctl_clone(s |
| */ |
| |
| /* the destination must be opened for writing */ |
| - if (!(file->f_mode & FMODE_WRITE)) |
| + if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) |
| return -EINVAL; |
| |
| ret = mnt_want_write(file->f_path.mnt); |
| @@ -1005,7 +1005,7 @@ static noinline long btrfs_ioctl_clone(s |
| |
| /* determine range to clone */ |
| ret = -EINVAL; |
| - if (off >= src->i_size || off + len > src->i_size) |
| + if (off + len > src->i_size || off + len < off) |
| goto out_unlock; |
| if (len == 0) |
| olen = len = src->i_size - off; |