Bug 238016 - Possible divide by zero in function aac_cam_action (sys/dev/aac/aac_cam.c and sys/dev/aacraid/aacraid_cam.c) and aic_calc_geometry (sys/dev/aic7xxx/aic_osm_lib.c)
Summary: Possible divide by zero in function aac_cam_action (sys/dev/aac/aac_cam.c and...
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Many People
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-05-21 08:25 UTC by Young
Modified: 2019-05-21 08:25 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Young 2019-05-21 08:25:33 UTC
There are three possible divide-by-zero vulnerabilities in function aac_cam_action (sys/dev/aac/aac_cam.c and sys/dev/aacraid/aacraid_cam.c) and aic_calc_geometry (sys/dev/aic7xxx/aic_osm_lib.c).

        case XPT_CALC_GEOMETRY:
        {
                struct ccb_calc_geometry *ccg;
                u_int32_t size_mb;
                u_int32_t secs_per_cylinder;

                ccg = &ccb->ccg;
                size_mb = ccg->volume_size /
                    ((1024L * 1024L) / ccg->block_size);
                if (size_mb >= (2 * 1024)) {            /* 2GB */
                        ccg->heads = 255;
                        ccg->secs_per_track = 63;
                } else if (size_mb >= (1 * 1024)) {     /* 1GB */
                        ccg->heads = 128;
                        ccg->secs_per_track = 32;
                } else {
                        ccg->heads = 64;
                        ccg->secs_per_track = 32;
                }
                secs_per_cylinder = ccg->heads * ccg->secs_per_track;
                ccg->cylinders = ccg->volume_size / secs_per_cylinder;

                ccb->ccb_h.status = CAM_REQ_CMP;
                xpt_done(ccb);
                return;
        }
(aac_cam_action in sys/dev/aac/aac_cam.c and sys/dev/aacraid/aacraid_cam.c)

void
aic_calc_geometry(struct ccb_calc_geometry *ccg, int extended)
{
#if __FreeBSD_version >= 500000
        cam_calc_geometry(ccg, extended);
#else
        uint32_t size_mb;
        uint32_t secs_per_cylinder;

        size_mb = ccg->volume_size / ((1024L * 1024L) / ccg->block_size);
        if (size_mb > 1024 && extended) {
                ccg->heads = 255;
                ccg->secs_per_track = 63;
        } else {
                ccg->heads = 64;
                ccg->secs_per_track = 32;
        }
        secs_per_cylinder = ccg->heads * ccg->secs_per_track;
        ccg->cylinders = ccg->volume_size / secs_per_cylinder;
        ccg->ccb_h.status = CAM_REQ_CMP;
#endif
}
(aic_calc_geometry in sys/dev/aic7xxx/aic_osm_lib.c))

There is the chance that "ccg->block_size = 0".

This issue is similar to https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=12041 which was fixed in https://github.com/freebsd/freebsd/commit/b5184a290e8a553843618c8beb113d67df465f98.

However, we should check wheter ccg->block_size equals zero or not like https://github.com/freebsd/freebsd/blob/master/sys/cam/cam.c#L570.