diff options
| author | J. Bruce Fields <bfields@redhat.com> | 2016-03-18 11:31:17 -0400 |
|---|---|---|
| committer | J. Bruce Fields <bfields@redhat.com> | 2016-03-22 14:39:35 -0400 |
| commit | 4b15da44e742871206582f6aa2997b009648f02f (patch) | |
| tree | e69e230a2db6740a6bc44fd479df3f692429a0c0 | |
| parent | 10c4de10b2624ab9d83bd8e708d39a1867302a6a (diff) | |
nfsd: better layoutupdate bounds-checking
You could add any multiple of 2^32/PNFS_SCSI_RANGE_SIZE to nr_iomaps and
still pass this check. You'd probably still fail the following kcalloc,
but best to be paranoid since this is from-the-wire data.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
| -rw-r--r-- | fs/nfsd/blocklayoutxdr.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/nfsd/blocklayoutxdr.c b/fs/nfsd/blocklayoutxdr.c index ca1883668810..6c3b316f932e 100644 --- a/fs/nfsd/blocklayoutxdr.c +++ b/fs/nfsd/blocklayoutxdr.c | |||
| @@ -105,18 +105,22 @@ nfsd4_block_decode_layoutupdate(__be32 *p, u32 len, struct iomap **iomapp, | |||
| 105 | u32 block_size) | 105 | u32 block_size) |
| 106 | { | 106 | { |
| 107 | struct iomap *iomaps; | 107 | struct iomap *iomaps; |
| 108 | u32 nr_iomaps, expected, i; | 108 | u32 nr_iomaps, i; |
| 109 | 109 | ||
| 110 | if (len < sizeof(u32)) { | 110 | if (len < sizeof(u32)) { |
| 111 | dprintk("%s: extent array too small: %u\n", __func__, len); | 111 | dprintk("%s: extent array too small: %u\n", __func__, len); |
| 112 | return -EINVAL; | 112 | return -EINVAL; |
| 113 | } | 113 | } |
| 114 | len -= sizeof(u32); | ||
| 115 | if (len % PNFS_BLOCK_EXTENT_SIZE) { | ||
| 116 | dprintk("%s: extent array invalid: %u\n", __func__, len); | ||
| 117 | return -EINVAL; | ||
| 118 | } | ||
| 114 | 119 | ||
| 115 | nr_iomaps = be32_to_cpup(p++); | 120 | nr_iomaps = be32_to_cpup(p++); |
| 116 | expected = sizeof(__be32) + nr_iomaps * PNFS_BLOCK_EXTENT_SIZE; | 121 | if (nr_iomaps != len / PNFS_BLOCK_EXTENT_SIZE) { |
| 117 | if (len != expected) { | ||
| 118 | dprintk("%s: extent array size mismatch: %u/%u\n", | 122 | dprintk("%s: extent array size mismatch: %u/%u\n", |
| 119 | __func__, len, expected); | 123 | __func__, len, nr_iomaps); |
| 120 | return -EINVAL; | 124 | return -EINVAL; |
| 121 | } | 125 | } |
| 122 | 126 | ||
