Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cdrom: Make device operations read-only

Since function tables are a common target for attackers, it's best to keep
them in read-only memory. As such, this makes the CDROM device ops tables
const. This drops additionally n_minors, since it isn't used meaningfully,
and sets the only user of cdrom_dummy_generic_packet explicitly so the
variables can all be const.

Inspired by similar changes in grsecurity/PaX.

Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jens Axboe <axboe@fb.com>

authored by

Kees Cook and committed by
Jens Axboe
853fe1bf d1a987f3

+37 -45
+1 -8
Documentation/cdrom/cdrom-standard.tex
··· 249 249 unsigned\ long);\cr 250 250 \noalign{\medskip} 251 251 &const\ int& capability;& capability flags \cr 252 - &int& n_minors;& number of active minor devices \cr 253 252 \};\cr 254 253 } 255 254 $$ ··· 257 258 function is not implemented, however, this $struct$ should contain a 258 259 NULL instead. The $capability$ flags specify the capabilities of the 259 260 \cdrom\ hardware and/or low-level \cdrom\ driver when a \cdrom\ drive 260 - is registered with the \UCD. The value $n_minors$ should be a positive 261 - value indicating the number of minor devices that are supported by 262 - the low-level device driver, normally~1. Although these two variables 263 - are `informative' rather than `operational,' they are included in 264 - $cdrom_device_ops$ because they describe the capability of the {\em 265 - driver\/} rather than the {\em drive}. Nomenclature has always been 266 - difficult in computer programming. 261 + is registered with the \UCD. 267 262 268 263 Note that most functions have fewer parameters than their 269 264 $blkdev_fops$ counterparts. This is because very little of the
+1 -1
drivers/block/paride/pcd.c
··· 273 273 .check_events = pcd_block_check_events, 274 274 }; 275 275 276 - static struct cdrom_device_ops pcd_dops = { 276 + static const struct cdrom_device_ops pcd_dops = { 277 277 .open = pcd_open, 278 278 .release = pcd_release, 279 279 .drive_status = pcd_drive_status,
+28 -30
drivers/cdrom/cdrom.c
··· 342 342 343 343 static LIST_HEAD(cdrom_list); 344 344 345 - static int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi, 346 - struct packet_command *cgc) 345 + int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi, 346 + struct packet_command *cgc) 347 347 { 348 348 if (cgc->sense) { 349 349 cgc->sense->sense_key = 0x05; ··· 354 354 cgc->stat = -EIO; 355 355 return -EIO; 356 356 } 357 + EXPORT_SYMBOL(cdrom_dummy_generic_packet); 357 358 358 359 static int cdrom_flush_cache(struct cdrom_device_info *cdi) 359 360 { ··· 372 371 static int cdrom_get_disc_info(struct cdrom_device_info *cdi, 373 372 disc_information *di) 374 373 { 375 - struct cdrom_device_ops *cdo = cdi->ops; 374 + const struct cdrom_device_ops *cdo = cdi->ops; 376 375 struct packet_command cgc; 377 376 int ret, buflen; 378 377 ··· 587 586 int register_cdrom(struct cdrom_device_info *cdi) 588 587 { 589 588 static char banner_printed; 590 - struct cdrom_device_ops *cdo = cdi->ops; 589 + const struct cdrom_device_ops *cdo = cdi->ops; 591 590 int *change_capability = (int *)&cdo->capability; /* hack */ 592 591 593 592 cd_dbg(CD_OPEN, "entering register_cdrom\n"); ··· 611 610 ENSURE(reset, CDC_RESET); 612 611 ENSURE(generic_packet, CDC_GENERIC_PACKET); 613 612 cdi->mc_flags = 0; 614 - cdo->n_minors = 0; 615 613 cdi->options = CDO_USE_FFLAGS; 616 614 617 615 if (autoclose == 1 && CDROM_CAN(CDC_CLOSE_TRAY)) ··· 630 630 else 631 631 cdi->cdda_method = CDDA_OLD; 632 632 633 - if (!cdo->generic_packet) 634 - cdo->generic_packet = cdrom_dummy_generic_packet; 633 + WARN_ON(!cdo->generic_packet); 635 634 636 635 cd_dbg(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); 637 636 mutex_lock(&cdrom_mutex); ··· 651 652 if (cdi->exit) 652 653 cdi->exit(cdi); 653 654 654 - cdi->ops->n_minors--; 655 655 cd_dbg(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name); 656 656 } 657 657 ··· 1034 1036 int open_for_data(struct cdrom_device_info *cdi) 1035 1037 { 1036 1038 int ret; 1037 - struct cdrom_device_ops *cdo = cdi->ops; 1039 + const struct cdrom_device_ops *cdo = cdi->ops; 1038 1040 tracktype tracks; 1039 1041 cd_dbg(CD_OPEN, "entering open_for_data\n"); 1040 1042 /* Check if the driver can report drive status. If it can, we ··· 1196 1198 /* This code is similar to that in open_for_data. The routine is called 1197 1199 whenever an audio play operation is requested. 1198 1200 */ 1199 - static int check_for_audio_disc(struct cdrom_device_info * cdi, 1200 - struct cdrom_device_ops * cdo) 1201 + static int check_for_audio_disc(struct cdrom_device_info *cdi, 1202 + const struct cdrom_device_ops *cdo) 1201 1203 { 1202 1204 int ret; 1203 1205 tracktype tracks; ··· 1252 1254 1253 1255 void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode) 1254 1256 { 1255 - struct cdrom_device_ops *cdo = cdi->ops; 1257 + const struct cdrom_device_ops *cdo = cdi->ops; 1256 1258 int opened_for_data; 1257 1259 1258 1260 cd_dbg(CD_CLOSE, "entering cdrom_release\n"); ··· 1292 1294 struct cdrom_changer_info *buf) 1293 1295 { 1294 1296 struct packet_command cgc; 1295 - struct cdrom_device_ops *cdo = cdi->ops; 1297 + const struct cdrom_device_ops *cdo = cdi->ops; 1296 1298 int length; 1297 1299 1298 1300 /* ··· 1641 1643 int ret; 1642 1644 u_char buf[20]; 1643 1645 struct packet_command cgc; 1644 - struct cdrom_device_ops *cdo = cdi->ops; 1646 + const struct cdrom_device_ops *cdo = cdi->ops; 1645 1647 rpc_state_t rpc_state; 1646 1648 1647 1649 memset(buf, 0, sizeof(buf)); ··· 1789 1791 { 1790 1792 unsigned char buf[21], *base; 1791 1793 struct dvd_layer *layer; 1792 - struct cdrom_device_ops *cdo = cdi->ops; 1794 + const struct cdrom_device_ops *cdo = cdi->ops; 1793 1795 int ret, layer_num = s->physical.layer_num; 1794 1796 1795 1797 if (layer_num >= DVD_LAYERS) ··· 1840 1842 { 1841 1843 int ret; 1842 1844 u_char buf[8]; 1843 - struct cdrom_device_ops *cdo = cdi->ops; 1845 + const struct cdrom_device_ops *cdo = cdi->ops; 1844 1846 1845 1847 init_cdrom_command(cgc, buf, sizeof(buf), CGC_DATA_READ); 1846 1848 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE; ··· 1864 1866 { 1865 1867 int ret, size; 1866 1868 u_char *buf; 1867 - struct cdrom_device_ops *cdo = cdi->ops; 1869 + const struct cdrom_device_ops *cdo = cdi->ops; 1868 1870 1869 1871 size = sizeof(s->disckey.value) + 4; 1870 1872 ··· 1892 1894 { 1893 1895 int ret, size = 4 + 188; 1894 1896 u_char *buf; 1895 - struct cdrom_device_ops *cdo = cdi->ops; 1897 + const struct cdrom_device_ops *cdo = cdi->ops; 1896 1898 1897 1899 buf = kmalloc(size, GFP_KERNEL); 1898 1900 if (!buf) ··· 1926 1928 { 1927 1929 int ret = 0, size; 1928 1930 u_char *buf; 1929 - struct cdrom_device_ops *cdo = cdi->ops; 1931 + const struct cdrom_device_ops *cdo = cdi->ops; 1930 1932 1931 1933 size = sizeof(s->manufact.value) + 4; 1932 1934 ··· 1993 1995 struct packet_command *cgc, 1994 1996 int page_code, int page_control) 1995 1997 { 1996 - struct cdrom_device_ops *cdo = cdi->ops; 1998 + const struct cdrom_device_ops *cdo = cdi->ops; 1997 1999 1998 2000 memset(cgc->cmd, 0, sizeof(cgc->cmd)); 1999 2001 ··· 2008 2010 int cdrom_mode_select(struct cdrom_device_info *cdi, 2009 2011 struct packet_command *cgc) 2010 2012 { 2011 - struct cdrom_device_ops *cdo = cdi->ops; 2013 + const struct cdrom_device_ops *cdo = cdi->ops; 2012 2014 2013 2015 memset(cgc->cmd, 0, sizeof(cgc->cmd)); 2014 2016 memset(cgc->buffer, 0, 2); ··· 2023 2025 static int cdrom_read_subchannel(struct cdrom_device_info *cdi, 2024 2026 struct cdrom_subchnl *subchnl, int mcn) 2025 2027 { 2026 - struct cdrom_device_ops *cdo = cdi->ops; 2028 + const struct cdrom_device_ops *cdo = cdi->ops; 2027 2029 struct packet_command cgc; 2028 2030 char buffer[32]; 2029 2031 int ret; ··· 2071 2073 struct packet_command *cgc, int lba, 2072 2074 int blocksize, int nblocks) 2073 2075 { 2074 - struct cdrom_device_ops *cdo = cdi->ops; 2076 + const struct cdrom_device_ops *cdo = cdi->ops; 2075 2077 2076 2078 memset(&cgc->cmd, 0, sizeof(cgc->cmd)); 2077 2079 cgc->cmd[0] = GPCMD_READ_10; ··· 2091 2093 struct packet_command *cgc, 2092 2094 int lba, int nblocks, int format, int blksize) 2093 2095 { 2094 - struct cdrom_device_ops *cdo = cdi->ops; 2096 + const struct cdrom_device_ops *cdo = cdi->ops; 2095 2097 2096 2098 memset(&cgc->cmd, 0, sizeof(cgc->cmd)); 2097 2099 cgc->cmd[0] = GPCMD_READ_CD; ··· 2762 2764 */ 2763 2765 static int cdrom_switch_blocksize(struct cdrom_device_info *cdi, int size) 2764 2766 { 2765 - struct cdrom_device_ops *cdo = cdi->ops; 2767 + const struct cdrom_device_ops *cdo = cdi->ops; 2766 2768 struct packet_command cgc; 2767 2769 struct modesel_head mh; 2768 2770 ··· 2788 2790 static int cdrom_get_track_info(struct cdrom_device_info *cdi, 2789 2791 __u16 track, __u8 type, track_information *ti) 2790 2792 { 2791 - struct cdrom_device_ops *cdo = cdi->ops; 2793 + const struct cdrom_device_ops *cdo = cdi->ops; 2792 2794 struct packet_command cgc; 2793 2795 int ret, buflen; 2794 2796 ··· 3047 3049 void __user *arg, 3048 3050 struct packet_command *cgc) 3049 3051 { 3050 - struct cdrom_device_ops *cdo = cdi->ops; 3052 + const struct cdrom_device_ops *cdo = cdi->ops; 3051 3053 struct cdrom_msf msf; 3052 3054 cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYMSF\n"); 3053 3055 if (copy_from_user(&msf, (struct cdrom_msf __user *)arg, sizeof(msf))) ··· 3067 3069 void __user *arg, 3068 3070 struct packet_command *cgc) 3069 3071 { 3070 - struct cdrom_device_ops *cdo = cdi->ops; 3072 + const struct cdrom_device_ops *cdo = cdi->ops; 3071 3073 struct cdrom_blk blk; 3072 3074 cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYBLK\n"); 3073 3075 if (copy_from_user(&blk, (struct cdrom_blk __user *)arg, sizeof(blk))) ··· 3162 3164 struct packet_command *cgc, 3163 3165 int cmd) 3164 3166 { 3165 - struct cdrom_device_ops *cdo = cdi->ops; 3167 + const struct cdrom_device_ops *cdo = cdi->ops; 3166 3168 cd_dbg(CD_DO_IOCTL, "entering CDROMSTART/CDROMSTOP\n"); 3167 3169 cgc->cmd[0] = GPCMD_START_STOP_UNIT; 3168 3170 cgc->cmd[1] = 1; ··· 3175 3177 struct packet_command *cgc, 3176 3178 int cmd) 3177 3179 { 3178 - struct cdrom_device_ops *cdo = cdi->ops; 3180 + const struct cdrom_device_ops *cdo = cdi->ops; 3179 3181 cd_dbg(CD_DO_IOCTL, "entering CDROMPAUSE/CDROMRESUME\n"); 3180 3182 cgc->cmd[0] = GPCMD_PAUSE_RESUME; 3181 3183 cgc->cmd[8] = (cmd == CDROMRESUME) ? 1 : 0;
+2 -2
drivers/cdrom/gdrom.c
··· 481 481 return -EINVAL; 482 482 } 483 483 484 - static struct cdrom_device_ops gdrom_ops = { 484 + static const struct cdrom_device_ops gdrom_ops = { 485 485 .open = gdrom_open, 486 486 .release = gdrom_release, 487 487 .drive_status = gdrom_drivestatus, ··· 489 489 .get_last_session = gdrom_get_last_session, 490 490 .reset = gdrom_hardreset, 491 491 .audio_ioctl = gdrom_audio_ioctl, 492 + .generic_packet = cdrom_dummy_generic_packet, 492 493 .capability = CDC_MULTI_SESSION | CDC_MEDIA_CHANGED | 493 494 CDC_RESET | CDC_DRIVE_STATUS | CDC_CD_R, 494 - .n_minors = 1, 495 495 }; 496 496 497 497 static int gdrom_bdops_open(struct block_device *bdev, fmode_t mode)
+1 -1
drivers/ide/ide-cd.c
··· 1166 1166 CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_GENERIC_PACKET | \ 1167 1167 CDC_MO_DRIVE | CDC_MRW | CDC_MRW_W | CDC_RAM) 1168 1168 1169 - static struct cdrom_device_ops ide_cdrom_dops = { 1169 + static const struct cdrom_device_ops ide_cdrom_dops = { 1170 1170 .open = ide_cdrom_open_real, 1171 1171 .release = ide_cdrom_release_real, 1172 1172 .drive_status = ide_cdrom_drive_status,
+1 -1
drivers/scsi/sr.c
··· 117 117 unsigned int clearing, int slot); 118 118 static int sr_packet(struct cdrom_device_info *, struct packet_command *); 119 119 120 - static struct cdrom_device_ops sr_dops = { 120 + static const struct cdrom_device_ops sr_dops = { 121 121 .open = sr_open, 122 122 .release = sr_release, 123 123 .drive_status = sr_drive_status,
+3 -2
include/linux/cdrom.h
··· 36 36 37 37 /* Uniform cdrom data structures for cdrom.c */ 38 38 struct cdrom_device_info { 39 - struct cdrom_device_ops *ops; /* link to device_ops */ 39 + const struct cdrom_device_ops *ops; /* link to device_ops */ 40 40 struct list_head list; /* linked list of all device_info */ 41 41 struct gendisk *disk; /* matching block layer disk */ 42 42 void *handle; /* driver-dependent data */ ··· 87 87 88 88 /* driver specifications */ 89 89 const int capability; /* capability flags */ 90 - int n_minors; /* number of active minor devices */ 91 90 /* handle uniform packets for scsi type devices (scsi,atapi) */ 92 91 int (*generic_packet) (struct cdrom_device_info *, 93 92 struct packet_command *); ··· 122 123 int page_code, int page_control); 123 124 extern void init_cdrom_command(struct packet_command *cgc, 124 125 void *buffer, int len, int type); 126 + extern int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi, 127 + struct packet_command *cgc); 125 128 126 129 /* The SCSI spec says there could be 256 slots. */ 127 130 #define CDROM_MAX_SLOTS 256