diff options
author | Stephen M. Cameron <scameron@beardog.cce.hp.com> | 2010-07-19 14:46:28 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-08-07 12:52:30 -0400 |
commit | adfbc1ff342ece2e482254bcc5381fadfffbbb89 (patch) | |
tree | aefa1482a22f0378a1397546595e7980fb4acf75 /drivers/block | |
parent | a6528d017234b483283274fbdd360f3541befe19 (diff) |
cciss: sanitize max commands
cciss: sanitize max commands
Some controllers might try to tell us they support 0 commands
in performant mode. This is a lie told by buggy firmware.
We have to be wary of this lest we try to allocate a negative
number of command blocks, which will be treated as unsigned,
and get an out of memory condition.
Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/cciss.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index b3060eced553..6d4c4f227d55 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -4112,13 +4112,25 @@ static int __devinit cciss_find_cfgtables(ctlr_info_t *h) | |||
4112 | return 0; | 4112 | return 0; |
4113 | } | 4113 | } |
4114 | 4114 | ||
4115 | static void __devinit cciss_get_max_perf_mode_cmds(struct ctlr_info *h) | ||
4116 | { | ||
4117 | h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); | ||
4118 | if (h->max_commands < 16) { | ||
4119 | dev_warn(&h->pdev->dev, "Controller reports " | ||
4120 | "max supported commands of %d, an obvious lie. " | ||
4121 | "Using 16. Ensure that firmware is up to date.\n", | ||
4122 | h->max_commands); | ||
4123 | h->max_commands = 16; | ||
4124 | } | ||
4125 | } | ||
4126 | |||
4115 | /* Interrogate the hardware for some limits: | 4127 | /* Interrogate the hardware for some limits: |
4116 | * max commands, max SG elements without chaining, and with chaining, | 4128 | * max commands, max SG elements without chaining, and with chaining, |
4117 | * SG chain block size, etc. | 4129 | * SG chain block size, etc. |
4118 | */ | 4130 | */ |
4119 | static void __devinit cciss_find_board_params(ctlr_info_t *h) | 4131 | static void __devinit cciss_find_board_params(ctlr_info_t *h) |
4120 | { | 4132 | { |
4121 | h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); | 4133 | cciss_get_max_perf_mode_cmds(h); |
4122 | h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */ | 4134 | h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */ |
4123 | h->maxsgentries = readl(&(h->cfgtable->MaxSGElements)); | 4135 | h->maxsgentries = readl(&(h->cfgtable->MaxSGElements)); |
4124 | /* | 4136 | /* |