Example #1
0
static int verify_command(struct file *file, unsigned char *cmd)
{
	static unsigned char cmd_type[256] = {

		/* Basic read-only commands */
		safe_for_read(TEST_UNIT_READY),
		safe_for_read(REQUEST_SENSE),
		safe_for_read(READ_6),
		safe_for_read(READ_10),
		safe_for_read(READ_12),
		safe_for_read(READ_16),
		safe_for_read(READ_BUFFER),
		safe_for_read(READ_DEFECT_DATA),
		safe_for_read(READ_LONG),
		safe_for_read(INQUIRY),
		safe_for_read(MODE_SENSE),
		safe_for_read(MODE_SENSE_10),
		safe_for_read(LOG_SENSE),
		safe_for_read(START_STOP),
		safe_for_read(GPCMD_VERIFY_10),
		safe_for_read(VERIFY_16),

		/* Audio CD commands */
		safe_for_read(GPCMD_PLAY_CD),
		safe_for_read(GPCMD_PLAY_AUDIO_10),
		safe_for_read(GPCMD_PLAY_AUDIO_MSF),
		safe_for_read(GPCMD_PLAY_AUDIO_TI),
		safe_for_read(GPCMD_PAUSE_RESUME),

		/* CD/DVD data reading */
		safe_for_read(GPCMD_READ_BUFFER_CAPACITY),
		safe_for_read(GPCMD_READ_CD),
		safe_for_read(GPCMD_READ_CD_MSF),
		safe_for_read(GPCMD_READ_DISC_INFO),
		safe_for_read(GPCMD_READ_CDVD_CAPACITY),
		safe_for_read(GPCMD_READ_DVD_STRUCTURE),
		safe_for_read(GPCMD_READ_HEADER),
		safe_for_read(GPCMD_READ_TRACK_RZONE_INFO),
		safe_for_read(GPCMD_READ_SUBCHANNEL),
		safe_for_read(GPCMD_READ_TOC_PMA_ATIP),
		safe_for_read(GPCMD_REPORT_KEY),
		safe_for_read(GPCMD_SCAN),
		safe_for_read(GPCMD_GET_CONFIGURATION),
		safe_for_read(GPCMD_READ_FORMAT_CAPACITIES),
		safe_for_read(GPCMD_GET_EVENT_STATUS_NOTIFICATION),
		safe_for_read(GPCMD_GET_PERFORMANCE),
		safe_for_read(GPCMD_SEEK),
		safe_for_read(GPCMD_STOP_PLAY_SCAN),

		/* Basic writing commands */
		safe_for_write(WRITE_6),
		safe_for_write(WRITE_10),
		safe_for_write(WRITE_VERIFY),
		safe_for_write(WRITE_12),
		safe_for_write(WRITE_VERIFY_12),
		safe_for_write(WRITE_16),
		safe_for_write(WRITE_LONG),
		safe_for_write(WRITE_LONG_2),
		safe_for_write(ERASE),
		safe_for_write(GPCMD_MODE_SELECT_10),
		safe_for_write(MODE_SELECT),
		safe_for_write(LOG_SELECT),
		safe_for_write(GPCMD_BLANK),
		safe_for_write(GPCMD_CLOSE_TRACK),
		safe_for_write(GPCMD_FLUSH_CACHE),
		safe_for_write(GPCMD_FORMAT_UNIT),
		safe_for_write(GPCMD_REPAIR_RZONE_TRACK),
		safe_for_write(GPCMD_RESERVE_RZONE_TRACK),
		safe_for_write(GPCMD_SEND_DVD_STRUCTURE),
		safe_for_write(GPCMD_SEND_EVENT),
		safe_for_write(GPCMD_SEND_KEY),
		safe_for_write(GPCMD_SEND_OPC),
		safe_for_write(GPCMD_SEND_CUE_SHEET),
		safe_for_write(GPCMD_SET_SPEED),
		safe_for_write(GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL),
		safe_for_write(GPCMD_LOAD_UNLOAD),
		safe_for_write(GPCMD_SET_STREAMING),
	};
	unsigned char type = cmd_type[cmd[0]];
	int has_write_perm = 0;

	/* Anybody who can open the device can do a read-safe command */
	if (type & CMD_READ_SAFE)
		return 0;

	/*
	 * file can be NULL from ioctl_by_bdev()...
	 */
	if (file)
		has_write_perm = tx_cache_get_file_ro(file)->f_mode & FMODE_WRITE;

	/* Write-safe commands just require a writable open.. */
	if ((type & CMD_WRITE_SAFE) && has_write_perm)
		return 0;

	/* And root can do any command.. */
	if (capable(CAP_SYS_RAWIO))
		return 0;

	if (!type) {
		cmd_type[cmd[0]] = CMD_WARNED;
		printk(KERN_WARNING "scsi: unknown opcode 0x%02x\n", cmd[0]);
	}

	/* Otherwise fail it with an "Operation not permitted" */
	return -EPERM;
}
Example #2
0
static int verify_command(struct file *file, unsigned char *cmd)
{
    static const unsigned char cmd_type[256] = {

        /* Basic read-only commands */
        safe_for_read(TEST_UNIT_READY),
        safe_for_read(REQUEST_SENSE),
        safe_for_read(READ_6),
        safe_for_read(READ_10),
        safe_for_read(READ_12),
        safe_for_read(READ_16),
        safe_for_read(READ_BUFFER),
        safe_for_read(READ_LONG),
        safe_for_read(INQUIRY),
        safe_for_read(MODE_SENSE),
        safe_for_read(MODE_SENSE_10),
        safe_for_read(START_STOP),

        /* Audio CD commands */
        safe_for_read(GPCMD_PLAY_CD),
        safe_for_read(GPCMD_PLAY_AUDIO_10),
        safe_for_read(GPCMD_PLAY_AUDIO_MSF),
        safe_for_read(GPCMD_PLAY_AUDIO_TI),

        /* CD/DVD data reading */
        safe_for_read(GPCMD_READ_CD),
        safe_for_read(GPCMD_READ_CD_MSF),
        safe_for_read(GPCMD_READ_DISC_INFO),
        safe_for_read(GPCMD_READ_CDVD_CAPACITY),
        safe_for_read(GPCMD_READ_DVD_STRUCTURE),
        safe_for_read(GPCMD_READ_HEADER),
        safe_for_read(GPCMD_READ_TRACK_RZONE_INFO),
        safe_for_read(GPCMD_READ_SUBCHANNEL),
        safe_for_read(GPCMD_READ_TOC_PMA_ATIP),
        safe_for_read(GPCMD_REPORT_KEY),
        safe_for_read(GPCMD_SCAN),

        /* Basic writing commands */
        safe_for_write(WRITE_6),
        safe_for_write(WRITE_10),
        safe_for_write(WRITE_VERIFY),
        safe_for_write(WRITE_12),
        safe_for_write(WRITE_VERIFY_12),
        safe_for_write(WRITE_16),
        safe_for_write(WRITE_BUFFER),
        safe_for_write(WRITE_LONG),
    };
    unsigned char type = cmd_type[cmd[0]];

    /* Anybody who can open the device can do a read-safe command */
    if (type & CMD_READ_SAFE)
        return 0;

    /* Write-safe commands just require a writable open.. */
    if (type & CMD_WRITE_SAFE) {
        if (file->f_mode & FMODE_WRITE)
            return 0;
    }

    /* And root can do any command.. */
    if (capable(CAP_SYS_RAWIO))
        return 0;

    /* Otherwise fail it with an "Operation not permitted" */
    return -EPERM;
}