All of lore.kernel.org
 help / color / mirror / Atom feed
From: James Bottomley <James.Bottomley@steeleye.com>
To: Matthew Dharm <mdharm-scsi@one-eyed-alien.net>
Cc: Linus Torvalds <torvalds@transmeta.com>,
	USB Developers <linux-usb-devel@lists.sourceforge.net>,
	USB Storage List <usb-storage@one-eyed-alien.net>,
	Linux SCSI list <linux-scsi@vger.kernel.org>
Subject: Re: PATCH: exclude certain commands from emulated SCSI hosts
Date: 05 Apr 2003 09:30:41 -0600	[thread overview]
Message-ID: <1049556643.1762.16.camel@mulgrave> (raw)
In-Reply-To: <20030324093028.A1066@one-eyed-alien.net>

[-- Attachment #1: Type: text/plain, Size: 1050 bytes --]

On Mon, 2003-03-24 at 11:30, Matthew Dharm wrote:
> On Mon, Mar 24, 2003 at 09:15:57AM -0600, James Bottomley wrote:
> > OK, I can do this: A simple one with either a blacklist (reject these
> > commands) or whitelist (only accept these commands) going by the first
> > command byte OK?
> 
> Well, you need to go by more than the first command byte -- ex. INQUIRY is
> okay, unless length != 36 or EVPD.
> 
> I think a blacklist is probably in order, but with a BIG COMMENT mentioning
> that if someone adds new commands into the code paths they should at least
> consider if they belong in the blacklist.

OK, try the attached.  There is no central blacklist, you must construct
it on a per driver basis, so in the queuecommand of your driver you have
a:

	static struct scsi_cmd_filter filter =
		{ SCSI_FILTER_BLACKLIST ,
		  { MODE_SENSE, SCSI_FILTER_INQUIRY_NOT36, 0 } };

	if(scsi_filter_cmd(SCp, &filter)) {
		SCp->scsi_done(SCp);
		return 0;
	}

to use the filter (I think, I've compiled but not tested it).

Let me know how it goes.

James


[-- Attachment #2: scsi_filter.diff --]
[-- Type: text/plain, Size: 3642 bytes --]

===== drivers/scsi/scsi.h 1.68 vs edited =====
--- 1.68/drivers/scsi/scsi.h	Mon Mar 24 11:23:37 2003
+++ edited/drivers/scsi/scsi.h	Sat Apr  5 09:24:38 2003
@@ -959,4 +959,39 @@
 extern int scsi_sysfs_register(void);
 extern void scsi_sysfs_unregister(void);
 
+struct scsi_cmd_filter {
+	enum {
+		SCSI_FILTER_WHITELIST,
+		SCSI_FILTER_BLACKLIST
+	} type;
+	/* normal scsi commands are bytes, exceptions are words.  The format
+	 * of the exceptions is:
+	 *
+	 * Byte 15: invert the specific condition
+	 * Byte 14-12: Reserved
+	 * Byte 11-8: command opcode (must be > 0)
+	 * Byte 7-0: Command specific */
+	unsigned short commands[];
+};
+
+extern int scsi_filter_cmd(struct scsi_cmnd *, struct scsi_cmd_filter *);
+
+/* exception definitions for the filter */
+#define SCSI_FILTER_INVERT		0x8000
+
+/* opcodes for the filter */
+#define SCSI_FILTER_INQUIRY		0x0100
+
+/* useful filter commands */
+#define SCSI_FILTER_INQUIRY_36		(SCSI_FILTER_INQUIRY | 36)
+#define SCSI_FILTER_INQUIRY_NOT36	(SCSI_FILTER_INVERT | SCSI_FILTER_INQUIRY | 36)
+
+static inline unsigned short scsi_filter_opcode(unsigned short command) {
+	return command & 0x7f00;
+}
+
+static inline unsigned char scsi_filter_data(unsigned short command) {
+	return (unsigned char)(command & 0x00ff);
+}
+
 #endif /* _SCSI_H */
===== drivers/scsi/scsi_lib.c 1.75 vs edited =====
--- 1.75/drivers/scsi/scsi_lib.c	Fri Mar 14 18:35:27 2003
+++ edited/drivers/scsi/scsi_lib.c	Sat Apr  5 09:27:35 2003
@@ -1375,3 +1375,71 @@
 		kmem_cache_destroy(sgp->slab);
 	}
 }
+
+static inline int scsi_filter_exceptions(struct scsi_cmnd *cmd,
+					 unsigned short command)
+{
+	int found = 0;
+
+	/* specials begin at 0x100 */
+	if(command < 0x100)
+		return 0;
+
+	switch(scsi_filter_opcode(command)) {
+
+	case SCSI_FILTER_INQUIRY:
+		if(cmd->cmnd[0] != INQUIRY)
+			return 0;
+		/* does the transfer length match the data */
+		found = (cmd->cmnd[4] == scsi_filter_data(command));
+		/* now check for inversion */
+		if(command & SCSI_FILTER_INVERT)
+			found = !found;
+		return found;
+	default:
+		/* unrecognized filter */
+		return 0;
+	}
+}
+
+/**
+ * scsi_filter_cmd - Filter a given command against a list
+ * @cmd: command to be filtered.
+ * @filter: pointer to the filter containing the type (black/white list) and
+ * zero terminated list of commands to filter against (first byte only).
+ *
+ * Returns 0 if the filter passed successfully and the driver can continue
+ * processing the command or 1 if the filter failed and the command should
+ * be finished (via ->scsi_done).  In the latter case, the command will have
+ * the sense fields filled in indicating the correct sense for an illegal
+ * request.
+ **/
+int scsi_filter_cmd(struct scsi_cmnd *cmd, struct scsi_cmd_filter *filter)
+{
+	int found = 0;
+	unsigned short *command;
+
+	for(command = filter->commands; *command; command++) {
+		found = scsi_filter_exceptions(cmd, *command);
+		found += (cmd->cmnd[0] != *command);
+		if(found)
+			break;
+	}
+
+	if((found && filter->type == SCSI_FILTER_WHITELIST) ||
+	   (!found && filter->type == SCSI_FILTER_BLACKLIST))
+		return 0;
+
+	/* fill in the Check Condition/Illegal request */
+	cmd->result = SAM_STAT_CHECK_CONDITION;
+	memset(cmd->sense_buffer, '\0', sizeof(cmd->sense_buffer));
+	cmd->sense_buffer[0] = 0xF0; /* valid, response code 0x70 */
+	cmd->sense_buffer[2] = ILLEGAL_REQUEST;
+
+	/* ASC 0x20, ASCQ 0x00: Invalid command operation code */
+	cmd->sense_buffer[12] = 0x20;
+	cmd->sense_buffer[13] = 0x00;
+
+	return 1;
+}
+	

  reply	other threads:[~2003-04-05 15:19 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20030322193046.A17056@one-eyed-alien.net>
     [not found] ` <20030322193149.B17056@one-eyed-alien.net>
2003-03-23  3:37   ` PATCH: exclude certain commands from emulated SCSI hosts Matthew Dharm
2003-03-23  4:09     ` Linus Torvalds
2003-03-23  7:31       ` Matthew Dharm
2003-03-23  7:39         ` Linus Torvalds
2003-03-23 18:13           ` [usb-storage] " Matthew Dharm
2003-03-24  1:05             ` Douglas Gilbert
2003-03-24  1:26         ` James Bottomley
2003-03-24  1:37           ` Matthew Dharm
2003-03-24  1:39             ` James Bottomley
2003-03-24  7:04               ` Matthew Dharm
2003-03-24 15:15                 ` James Bottomley
2003-03-24 16:29                   ` Linus Torvalds
2003-03-24 16:43                     ` James Bottomley
2003-03-24 16:52                     ` Jens Axboe
2003-03-24 16:56                       ` James Bottomley
2003-03-24 17:30                   ` Matthew Dharm
2003-04-05 15:30                     ` James Bottomley [this message]
2003-04-05 19:27                       ` Matthew Dharm
2003-04-05 19:45                         ` James Bottomley
2003-04-05 19:55                           ` Matthew Dharm
2003-04-05 20:08                             ` James Bottomley
2003-04-06  0:20                               ` Matthew Dharm
2003-04-06  0:22                           ` Matthew Dharm
2003-04-06 15:39                             ` James Bottomley
2003-04-07 22:33                       ` Patrick Mansfield
2003-04-07 23:14                         ` James Bottomley
2003-04-08  0:51                           ` Patrick Mansfield
2003-04-20 21:33                       ` Matthew Dharm
2003-04-20 21:35                         ` Matthew Dharm
2003-04-21 16:20                           ` James Bottomley
2003-04-21 17:02                             ` Matthew Dharm
2003-04-21 16:28                         ` James Bottomley
2003-04-21 17:01                           ` Matthew Dharm
2003-04-21 19:23                             ` James Bottomley
2003-04-21 19:35                               ` Matthew Dharm
2003-04-21 21:27                                 ` James Bottomley
2003-04-21 23:37                                   ` Matthew Dharm
2003-04-21 21:28                                 ` Patrick Mansfield
2003-04-21 23:45                                   ` Matthew Dharm
2003-03-24  1:58             ` Linus Torvalds
2003-03-24  6:58               ` Matthew Dharm
2003-04-22 17:37 [usb-storage] " James Bottomley
2003-04-22 18:13 ` Alan Stern
  -- strict thread matches above, loose matches on Subject: below --
2003-04-22 19:30 Andries.Brouwer
2003-04-22 19:41 ` James Bottomley
2003-04-22 19:50 Andries.Brouwer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1049556643.1762.16.camel@mulgrave \
    --to=james.bottomley@steeleye.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=linux-usb-devel@lists.sourceforge.net \
    --cc=mdharm-scsi@one-eyed-alien.net \
    --cc=torvalds@transmeta.com \
    --cc=usb-storage@one-eyed-alien.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.