The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/block/cmd-filter.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright 2004 Peter M. Jones <pjones@redhat.com>
    3  *
    4  * This program is free software; you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License version 2 as
    6  * published by the Free Software Foundation.
    7  *
    8  * This program is distributed in the hope that it will be useful,
    9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   10  *
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public Licens
   15  * along with this program; if not, write to the Free Software
   16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-
   17  *
   18  */
   19 
   20 #include <linux/list.h>
   21 #include <linux/genhd.h>
   22 #include <linux/spinlock.h>
   23 #include <linux/capability.h>
   24 #include <linux/bitops.h>
   25 
   26 #include <scsi/scsi.h>
   27 #include <linux/cdrom.h>
   28 
   29 int blk_verify_command(struct blk_cmd_filter *filter,
   30                        unsigned char *cmd, fmode_t has_write_perm)
   31 {
   32         /* root can do any command. */
   33         if (capable(CAP_SYS_RAWIO))
   34                 return 0;
   35 
   36         /* if there's no filter set, assume we're filtering everything out */
   37         if (!filter)
   38                 return -EPERM;
   39 
   40         /* Anybody who can open the device can do a read-safe command */
   41         if (test_bit(cmd[0], filter->read_ok))
   42                 return 0;
   43 
   44         /* Write-safe commands require a writable open */
   45         if (test_bit(cmd[0], filter->write_ok) && has_write_perm)
   46                 return 0;
   47 
   48         return -EPERM;
   49 }
   50 EXPORT_SYMBOL(blk_verify_command);
   51 
   52 #if 0
   53 /* and now, the sysfs stuff */
   54 static ssize_t rcf_cmds_show(struct blk_cmd_filter *filter, char *page,
   55                              int rw)
   56 {
   57         char *npage = page;
   58         unsigned long *okbits;
   59         int i;
   60 
   61         if (rw == READ)
   62                 okbits = filter->read_ok;
   63         else
   64                 okbits = filter->write_ok;
   65 
   66         for (i = 0; i < BLK_SCSI_MAX_CMDS; i++) {
   67                 if (test_bit(i, okbits)) {
   68                         npage += sprintf(npage, "0x%02x", i);
   69                         if (i < BLK_SCSI_MAX_CMDS - 1)
   70                                 sprintf(npage++, " ");
   71                 }
   72         }
   73 
   74         if (npage != page)
   75                 npage += sprintf(npage, "\n");
   76 
   77         return npage - page;
   78 }
   79 
   80 static ssize_t rcf_readcmds_show(struct blk_cmd_filter *filter, char *page)
   81 {
   82         return rcf_cmds_show(filter, page, READ);
   83 }
   84 
   85 static ssize_t rcf_writecmds_show(struct blk_cmd_filter *filter,
   86                                  char *page)
   87 {
   88         return rcf_cmds_show(filter, page, WRITE);
   89 }
   90 
   91 static ssize_t rcf_cmds_store(struct blk_cmd_filter *filter,
   92                               const char *page, size_t count, int rw)
   93 {
   94         unsigned long okbits[BLK_SCSI_CMD_PER_LONG], *target_okbits;
   95         int cmd, set;
   96         char *p, *status;
   97 
   98         if (rw == READ) {
   99                 memcpy(&okbits, filter->read_ok, sizeof(okbits));
  100                 target_okbits = filter->read_ok;
  101         } else {
  102                 memcpy(&okbits, filter->write_ok, sizeof(okbits));
  103                 target_okbits = filter->write_ok;
  104         }
  105 
  106         while ((p = strsep((char **)&page, " ")) != NULL) {
  107                 set = 1;
  108 
  109                 if (p[0] == '+') {
  110                         p++;
  111                 } else if (p[0] == '-') {
  112                         set = 0;
  113                         p++;
  114                 }
  115 
  116                 cmd = simple_strtol(p, &status, 16);
  117 
  118                 /* either of these cases means invalid input, so do nothing. */
  119                 if ((status == p) || cmd >= BLK_SCSI_MAX_CMDS)
  120                         return -EINVAL;
  121 
  122                 if (set)
  123                         __set_bit(cmd, okbits);
  124                 else
  125                         __clear_bit(cmd, okbits);
  126         }
  127 
  128         memcpy(target_okbits, okbits, sizeof(okbits));
  129         return count;
  130 }
  131 
  132 static ssize_t rcf_readcmds_store(struct blk_cmd_filter *filter,
  133                                   const char *page, size_t count)
  134 {
  135         return rcf_cmds_store(filter, page, count, READ);
  136 }
  137 
  138 static ssize_t rcf_writecmds_store(struct blk_cmd_filter *filter,
  139                                    const char *page, size_t count)
  140 {
  141         return rcf_cmds_store(filter, page, count, WRITE);
  142 }
  143 
  144 struct rcf_sysfs_entry {
  145         struct attribute attr;
  146         ssize_t (*show)(struct blk_cmd_filter *, char *);
  147         ssize_t (*store)(struct blk_cmd_filter *, const char *, size_t);
  148 };
  149 
  150 static struct rcf_sysfs_entry rcf_readcmds_entry = {
  151         .attr = { .name = "read_table", .mode = S_IRUGO | S_IWUSR },
  152         .show = rcf_readcmds_show,
  153         .store = rcf_readcmds_store,
  154 };
  155 
  156 static struct rcf_sysfs_entry rcf_writecmds_entry = {
  157         .attr = {.name = "write_table", .mode = S_IRUGO | S_IWUSR },
  158         .show = rcf_writecmds_show,
  159         .store = rcf_writecmds_store,
  160 };
  161 
  162 static struct attribute *default_attrs[] = {
  163         &rcf_readcmds_entry.attr,
  164         &rcf_writecmds_entry.attr,
  165         NULL,
  166 };
  167 
  168 #define to_rcf(atr) container_of((atr), struct rcf_sysfs_entry, attr)
  169 
  170 static ssize_t
  171 rcf_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
  172 {
  173         struct rcf_sysfs_entry *entry = to_rcf(attr);
  174         struct blk_cmd_filter *filter;
  175 
  176         filter = container_of(kobj, struct blk_cmd_filter, kobj);
  177         if (entry->show)
  178                 return entry->show(filter, page);
  179 
  180         return 0;
  181 }
  182 
  183 static ssize_t
  184 rcf_attr_store(struct kobject *kobj, struct attribute *attr,
  185                         const char *page, size_t length)
  186 {
  187         struct rcf_sysfs_entry *entry = to_rcf(attr);
  188         struct blk_cmd_filter *filter;
  189 
  190         if (!capable(CAP_SYS_RAWIO))
  191                 return -EPERM;
  192 
  193         if (!entry->store)
  194                 return -EINVAL;
  195 
  196         filter = container_of(kobj, struct blk_cmd_filter, kobj);
  197         return entry->store(filter, page, length);
  198 }
  199 
  200 static struct sysfs_ops rcf_sysfs_ops = {
  201         .show = rcf_attr_show,
  202         .store = rcf_attr_store,
  203 };
  204 
  205 static struct kobj_type rcf_ktype = {
  206         .sysfs_ops = &rcf_sysfs_ops,
  207         .default_attrs = default_attrs,
  208 };
  209 
  210 int blk_register_filter(struct gendisk *disk)
  211 {
  212         int ret;
  213         struct blk_cmd_filter *filter = &disk->queue->cmd_filter;
  214 
  215         ret = kobject_init_and_add(&filter->kobj, &rcf_ktype,
  216                                    &disk_to_dev(disk)->kobj,
  217                                    "%s", "cmd_filter");
  218         if (ret < 0)
  219                 return ret;
  220 
  221         return 0;
  222 }
  223 EXPORT_SYMBOL(blk_register_filter);
  224 
  225 void blk_unregister_filter(struct gendisk *disk)
  226 {
  227         struct blk_cmd_filter *filter = &disk->queue->cmd_filter;
  228 
  229         kobject_put(&filter->kobj);
  230 }
  231 EXPORT_SYMBOL(blk_unregister_filter);
  232 #endif

Cache object: 96a336d609b88497aa3b9e89672d8428


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.