Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/scsipi Prevent a process being swapped out during I/...



details:   https://anonhg.NetBSD.org/src/rev/ebd7c9650022
branches:  trunk
changeset: 487563:ebd7c9650022
user:      enami <enami%NetBSD.org@localhost>
date:      Fri Jun 09 08:54:19 2000 +0000

description:
Prevent a process being swapped out during I/O if the data buffer is
allocated on stack.  This potential problem is noticed by Noriyuki Soda
and the idea and sample code to fix is given by Jason R. Thorpe.

diffstat:

 sys/dev/scsipi/cd.c          |  72 ++++++++++++++++++++++++++-----------------
 sys/dev/scsipi/cd_atapi.c    |  24 +++++++-------
 sys/dev/scsipi/cd_scsi.c     |  19 ++++++----
 sys/dev/scsipi/ch.c          |  26 +++++++++------
 sys/dev/scsipi/if_se.c       |   8 +++-
 sys/dev/scsipi/scsiconf.c    |   5 +-
 sys/dev/scsipi/scsipi_base.c |   5 +-
 sys/dev/scsipi/scsipiconf.c  |  35 ++++++++++++++++++++-
 sys/dev/scsipi/scsipiconf.h  |  17 +++-------
 sys/dev/scsipi/sd.c          |   4 +-
 sys/dev/scsipi/sd_atapi.c    |   6 +-
 sys/dev/scsipi/sd_scsi.c     |   7 ++-
 sys/dev/scsipi/ss_mustek.c   |   8 ++--
 sys/dev/scsipi/ss_scanjet.c  |   6 +-
 sys/dev/scsipi/st.c          |  19 +++++++----
 15 files changed, 160 insertions(+), 101 deletions(-)

diffs (truncated from 871 to 300 lines):

diff -r 3f4b5997e645 -r ebd7c9650022 sys/dev/scsipi/cd.c
--- a/sys/dev/scsipi/cd.c       Fri Jun 09 08:22:13 2000 +0000
+++ b/sys/dev/scsipi/cd.c       Fri Jun 09 08:54:19 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cd.c,v 1.140 2000/05/30 01:08:23 augustss Exp $        */
+/*     $NetBSD: cd.c,v 1.141 2000/06/09 08:54:19 enami Exp $   */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -123,10 +123,10 @@
 int    cd_pause __P((struct cd_softc *, int));
 int    cd_reset __P((struct cd_softc *));
 int    cd_read_subchannel __P((struct cd_softc *, int, int, int,
-           struct cd_sub_channel_info *, int));
-int    cd_read_toc __P((struct cd_softc *, int, int, void *, int, int));
+           struct cd_sub_channel_info *, int, int));
+int    cd_read_toc __P((struct cd_softc *, int, int, void *, int, int, int));
 int    cd_get_parms __P((struct cd_softc *, int));
-int    cd_load_toc __P((struct cd_softc *, struct cd_toc *));
+int    cd_load_toc __P((struct cd_softc *, struct cd_toc *, int));
 int    dvd_auth __P((struct cd_softc *, dvd_authinfo *));
 int    dvd_read_physical __P((struct cd_softc *, dvd_struct *));
 int    dvd_read_copyright __P((struct cd_softc *, dvd_struct *));
@@ -931,7 +931,8 @@
                    len < sizeof(struct cd_sub_channel_header))
                        return (EINVAL);
                error = cd_read_subchannel(cd, args->address_format,
-                   args->data_format, args->track, &data, len);
+                   args->data_format, args->track, &data, len,
+                   XS_CTL_DATA_ONSTACK);
                if (error)
                        return (error);
                len = min(len, _2btol(data.header.data_len) +
@@ -941,7 +942,8 @@
        case CDIOREADTOCHEADER: {
                struct ioc_toc_header th;
 
-               if ((error = cd_read_toc(cd, 0, 0, &th, sizeof(th), 0)) != 0)
+               if ((error = cd_read_toc(cd, 0, 0, &th, sizeof(th),
+                   XS_CTL_DATA_ONSTACK, 0)) != 0)
                        return (error);
                if (cd->sc_link->quirks & ADEV_LITTLETOC) {
 #if BYTE_ORDER == BIG_ENDIAN
@@ -967,7 +969,8 @@
                    len < sizeof(struct cd_toc_entry))
                        return (EINVAL);
                error = cd_read_toc(cd, te->address_format, te->starting_track,
-                   &toc, len + sizeof(struct ioc_toc_header), 0);
+                   &toc, len + sizeof(struct ioc_toc_header),
+                   XS_CTL_DATA_ONSTACK, 0);
                if (error)
                        return (error);
                if (te->address_format == CD_LBA_FORMAT)
@@ -1004,6 +1007,7 @@
 
                error = cd_read_toc(cd, 0, 0, &toc,
                  sizeof(struct ioc_toc_header) + sizeof(struct cd_toc_entry),
+                 XS_CTL_DATA_ONSTACK,
                  0x40 /* control word for "get MS info" */);
 
                if (error)
@@ -1237,7 +1241,7 @@
        if (scsipi_command(cd->sc_link,
            (struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
            (u_char *)&rdcap, sizeof(rdcap), CDRETRIES, 30000, NULL,
-           flags | XS_CTL_DATA_IN) != 0)
+           flags | XS_CTL_DATA_IN | XS_CTL_DATA_ONSTACK) != 0)
                return (0);
 
        blksize = _4btol(rdcap.length);
@@ -1289,7 +1293,7 @@
        if (strack > etrack)
                return (EINVAL);
 
-       if ((error = cd_load_toc(cd, &toc)) != 0)
+       if ((error = cd_load_toc(cd, &toc, XS_CTL_DATA_ONSTACK)) != 0)
                return (error);
 
        if (++etrack > (toc.header.ending_track+1))
@@ -1365,10 +1369,11 @@
  * Read subchannel
  */
 int
-cd_read_subchannel(cd, mode, format, track, data, len)
+cd_read_subchannel(cd, mode, format, track, data, len, flags)
        struct cd_softc *cd;
        int mode, format, track, len;
        struct cd_sub_channel_info *data;
+       int flags;
 {
        struct scsipi_read_subchannel scsipi_cmd;
 
@@ -1383,17 +1388,18 @@
        return (scsipi_command(cd->sc_link,
            (struct scsipi_generic *)&scsipi_cmd,
            sizeof(struct scsipi_read_subchannel), (u_char *)data, len,
-           CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_SILENT));
+           CDRETRIES, 30000, NULL, flags|XS_CTL_DATA_IN|XS_CTL_SILENT));
 }
 
 /*
  * Read table of contents
  */
 int
-cd_read_toc(cd, mode, start, data, len, control)
+cd_read_toc(cd, mode, start, data, len, flags, control)
        struct cd_softc *cd;
        int mode, start, len, control;
        void *data;
+       int flags;
 {
        struct scsipi_read_toc scsipi_cmd;
        int ntoc;
@@ -1415,23 +1421,26 @@
        return (scsipi_command(cd->sc_link,
            (struct scsipi_generic *)&scsipi_cmd,
            sizeof(struct scsipi_read_toc), (u_char *)data, len, CDRETRIES,
-           30000, NULL, XS_CTL_DATA_IN));
+           30000, NULL, flags|XS_CTL_DATA_IN));
 }
 
 int
-cd_load_toc(cd, toc)
+cd_load_toc(cd, toc, flags)
        struct cd_softc *cd;
        struct cd_toc *toc;
+       int flags;
 {
        int ntracks, len, error;
 
-       if ((error = cd_read_toc(cd, 0, 0, toc, sizeof(toc->header), 0)) != 0)
+       if ((error = cd_read_toc(cd, 0, 0, toc, sizeof(toc->header),
+           flags, 0)) != 0)
                return (error);
 
        ntracks = toc->header.ending_track - toc->header.starting_track + 1;
        len = (ntracks + 1) * sizeof(struct cd_toc_entry) +
            sizeof(toc->header);
-       if ((error = cd_read_toc(cd, CD_MSF_FORMAT, 0, toc, len, 0)) != 0)
+       if ((error = cd_read_toc(cd, CD_MSF_FORMAT, 0, toc, len,
+           flags, 0)) != 0)
                return (error);
        return (0);
 }
@@ -1497,7 +1506,8 @@
                cmd.bytes[8] = 8;
                cmd.bytes[9] = 0 | (0 << 6);
                error = scsipi_command(cd->sc_link, &cmd, 16, buf, 8,
-                   CDRETRIES, 30000, NULL, XS_CTL_DATA_IN);
+                   CDRETRIES, 30000, NULL,
+                   XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
                if (error)
                        return (error);
                a->lsa.agid = buf[7] >> 6;
@@ -1508,7 +1518,8 @@
                cmd.bytes[8] = 16;
                cmd.bytes[9] = 1 | (a->lsc.agid << 6);
                error = scsipi_command(cd->sc_link, &cmd, 16, buf, 16,
-                   CDRETRIES, 30000, NULL, XS_CTL_DATA_IN);
+                   CDRETRIES, 30000, NULL,
+                   XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
                if (error)
                        return (error);
                dvd_copy_challenge(a->lsc.chal, &buf[4]);
@@ -1519,7 +1530,8 @@
                cmd.bytes[8] = 12;
                cmd.bytes[9] = 2 | (a->lsk.agid << 6);
                error = scsipi_command(cd->sc_link, &cmd, 16, buf, 12,
-                   CDRETRIES, 30000, NULL, XS_CTL_DATA_IN);
+                   CDRETRIES, 30000, NULL,
+                   XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
                if (error)
                        return (error);
                dvd_copy_key(a->lsk.key, &buf[4]);
@@ -1531,7 +1543,8 @@
                cmd.bytes[8] = 12;
                cmd.bytes[9] = 4 | (a->lstk.agid << 6);
                error = scsipi_command(cd->sc_link, &cmd, 16, buf, 12,
-                   CDRETRIES, 30000, NULL, XS_CTL_DATA_IN);
+                   CDRETRIES, 30000, NULL,
+                   XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
                if (error)
                        return (error);
                a->lstk.cpm = (buf[4] >> 7) & 1;
@@ -1545,7 +1558,8 @@
                cmd.bytes[8] = 8;
                cmd.bytes[9] = 5 | (a->lsasf.agid << 6);
                error = scsipi_command(cd->sc_link, &cmd, 16, buf, 8,
-                   CDRETRIES, 30000, NULL, XS_CTL_DATA_IN);
+                   CDRETRIES, 30000, NULL,
+                   XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
                if (error)
                        return (error);
                a->lsasf.asf = buf[7] & 1;
@@ -1558,7 +1572,8 @@
                buf[1] = 14;
                dvd_copy_challenge(&buf[4], a->hsc.chal);
                error = scsipi_command(cd->sc_link, &cmd, 16, buf, 16,
-                   CDRETRIES, 30000, NULL, XS_CTL_DATA_OUT|XS_CTL_DATA_IN);
+                   CDRETRIES, 30000, NULL,
+                   XS_CTL_DATA_OUT|XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
                if (error)
                        return (error);
                a->type = DVD_LU_SEND_KEY1;
@@ -1571,7 +1586,8 @@
                buf[1] = 10;
                dvd_copy_key(&buf[4], a->hsk.key);
                error = scsipi_command(cd->sc_link, &cmd, 16, buf, 12,
-                   CDRETRIES, 30000, NULL, XS_CTL_DATA_OUT|XS_CTL_DATA_IN);
+                   CDRETRIES, 30000, NULL,
+                   XS_CTL_DATA_OUT|XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
                if (error) {
                        a->type = DVD_AUTH_FAILURE;
                        return (error);
@@ -1612,7 +1628,7 @@
 
        cmd.bytes[5] = s->physical.layer_num;
        error = scsipi_command(cd->sc_link, &cmd, 16, buf, sizeof(buf),
-           CDRETRIES, 30000, NULL, XS_CTL_DATA_IN);
+           CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
        if (error)
                return (error);
        for (i = 0, bufp = &buf[4], layer = &s->physical.layer[0]; i < 4;
@@ -1652,7 +1668,7 @@
 
        cmd.bytes[5] = s->copyright.layer_num;
        error = scsipi_command(cd->sc_link, &cmd, 16, buf, sizeof(buf),
-           CDRETRIES, 30000, NULL, XS_CTL_DATA_IN);
+           CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
        if (error)
                return (error);
        s->copyright.cpst = buf[4];
@@ -1677,7 +1693,7 @@
 
        cmd.bytes[9] = s->disckey.agid << 6;
        error = scsipi_command(cd->sc_link, &cmd, 16, buf, sizeof(buf),
-           CDRETRIES, 30000, NULL, XS_CTL_DATA_IN);
+           CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
        if (error)
                return (error);
        memcpy(s->disckey.value, &buf[4], 2048);
@@ -1700,7 +1716,7 @@
        _lto2b(sizeof(buf), &cmd.bytes[7]);
 
        error = scsipi_command(cd->sc_link, &cmd, 16, buf, sizeof(buf),
-           CDRETRIES, 30000, NULL, XS_CTL_DATA_IN);
+           CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
        if (error)
                return (error);
        s->bca.len = _2btol(&buf[0]);
@@ -1726,7 +1742,7 @@
        _lto2b(sizeof(buf), &cmd.bytes[7]);
 
        error = scsipi_command(cd->sc_link, &cmd, 16, buf, sizeof(buf),
-           CDRETRIES, 30000, NULL, XS_CTL_DATA_IN);
+           CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
        if (error)
                return (error);
        s->manufact.len = _2btol(&buf[0]);
diff -r 3f4b5997e645 -r ebd7c9650022 sys/dev/scsipi/cd_atapi.c
--- a/sys/dev/scsipi/cd_atapi.c Fri Jun 09 08:22:13 2000 +0000
+++ b/sys/dev/scsipi/cd_atapi.c Fri Jun 09 08:54:19 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cd_atapi.c,v 1.12 2000/03/29 03:43:32 simonb Exp $     */
+/*     $NetBSD: cd_atapi.c,v 1.13 2000/06/09 08:54:20 enami Exp $      */
 
 /*
  * Copyright (c) 1997 Manuel Bouyer.  All rights reserved.
@@ -151,16 +151,16 @@
        int error;
 
        if ((error = atapi_mode_sense(cd->sc_link, ATAPI_AUDIO_PAGE,
-           (struct atapi_mode_header *)&data, AUDIOPAGESIZE, flags,
-           CDRETRIES, 20000)) != 0)
+           (struct atapi_mode_header *)&data, AUDIOPAGESIZE,
+           flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000)) != 0)
                return (error);
        data.pages.audio.port[LEFT_PORT].channels = p0;
        data.pages.audio.port[RIGHT_PORT].channels = p1;
        data.pages.audio.port[2].channels = p2;
        data.pages.audio.port[3].channels = p3;
        return (atapi_mode_select(cd->sc_link,
-           (struct atapi_mode_header *)&data, AUDIOPAGESIZE, flags,
-           CDRETRIES, 20000));
+           (struct atapi_mode_header *)&data, AUDIOPAGESIZE,
+           flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000));
 }
 
 int
@@ -173,8 +173,8 @@
        int error;
 
        if ((error = atapi_mode_sense(cd->sc_link, ATAPI_AUDIO_PAGE,
-           (struct atapi_mode_header *)&data, AUDIOPAGESIZE, flags,
-           CDRETRIES, 20000)) != 0)
+           (struct atapi_mode_header *)&data, AUDIOPAGESIZE,
+           flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000)) != 0)
                return (error);
        arg->vol[0] = data.pages.audio.port[0].volume;
        arg->vol[1] = data.pages.audio.port[1].volume;



Home | Main Index | Thread Index | Old Index