Limit the number of entries allocated for a REPORT_ZONES command.

The DIOCGETZONE ioctl can be used to fetch the zone list of an SMR
drive, and the caller specifies the number of entries it wants to fetch.
Clamp the caller's request to a sane limit so that a user cannot attempt
large allocations. Callers already need to invoke the ioctl multiple
times to fetch the full list in general, so there's no harm in limiting
the number of entries returned.

Fix style while here.

admbug:		807
Reported by:	Ilja Van Sprundel <ivansprundel@ioactive.com>
Reviewed by:	asomers, ken
Tested by:	ken
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D19249
This commit is contained in:
Mark Johnston 2019-02-19 21:33:02 +00:00
parent 94b793c497
commit d4fbe32c65

View File

@ -677,8 +677,10 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread
alloc_size = 0;
if (zone_args->zone_cmd == DISK_ZONE_REPORT_ZONES) {
rep = &zone_args->zone_params.report;
#define MAXENTRIES (MAXPHYS / sizeof(struct disk_zone_rep_entry))
if (rep->entries_allocated > MAXENTRIES)
rep->entries_allocated = MAXENTRIES;
alloc_size = rep->entries_allocated *
sizeof(struct disk_zone_rep_entry);
if (alloc_size != 0)
@ -688,15 +690,11 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread
rep->entries = new_entries;
}
error = g_io_zonecmd(zone_args, cp);
if ((zone_args->zone_cmd == DISK_ZONE_REPORT_ZONES)
&& (alloc_size != 0)
&& (error == 0)) {
if (zone_args->zone_cmd == DISK_ZONE_REPORT_ZONES &&
alloc_size != 0 && error == 0)
error = copyout(new_entries, old_entries, alloc_size);
}
if ((old_entries != NULL)
&& (rep != NULL))
if (old_entries != NULL && rep != NULL)
rep->entries = old_entries;
if (new_entries != NULL)
g_free(new_entries);
break;