Print this page
10092 sysevent_evc_control() dereferences pointer before checking for NULL


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 /*




  26  * This file contains the source of the general purpose event channel extension
  27  * to the sysevent framework. This implementation is made up mainly of four
  28  * layers of functionality: the event queues (evch_evq_*()), the handling of
  29  * channels (evch_ch*()), the kernel interface (sysevent_evc_*()) and the
  30  * interface for the sysevent pseudo driver (evch_usr*()).
  31  * Libsysevent.so uses the pseudo driver sysevent's ioctl to access the event
  32  * channel extensions. The driver in turn uses the evch_usr*() functions below.
  33  *
  34  * The interfaces for user land and kernel are declared in sys/sysevent.h
  35  * Internal data structures for event channels are defined in
  36  * sys/sysevent_impl.h.
  37  *
  38  * The basic data structure for an event channel is of type evch_chan_t.
  39  * All channels are maintained by a list named evch_list. The list head
  40  * is of type evch_dlist_t.
  41  */
  42 
  43 #include <sys/types.h>
  44 #include <sys/errno.h>
  45 #include <sys/stropts.h>


1959 
1960                 err = nvlist_pack(attr, &patt, &asz, NV_ENCODE_NATIVE,
1961                     km_flags & EVCH_SLEEP ? KM_SLEEP : KM_NOSLEEP);
1962 
1963                 ASSERT(err != ENOMEM);
1964 
1965                 if (err != 0) {
1966                         return (EINVAL);
1967                 }
1968 
1969                 evp->seh_attr_off = attr_offset;
1970                 SE_FLAG(evp) = SE_PACKED_BUF;
1971         }
1972         return (evch_chpublish((evch_bind_t *)scp, evp, flags));
1973 }
1974 
1975 int
1976 sysevent_evc_control(evchan_t *scp, int cmd, ...)
1977 {
1978         va_list         ap;
1979         evch_chan_t     *chp = ((evch_bind_t *)scp)->bd_channel;
1980         uint32_t        *chlenp;
1981         uint32_t        chlen;
1982         uint32_t        ochlen;
1983         int             rc = 0;
1984 
1985         if (scp == NULL) {
1986                 return (EINVAL);
1987         }
1988 


1989         va_start(ap, cmd);
1990         mutex_enter(&chp->ch_mutex);
1991         switch (cmd) {
1992         case EVCH_GET_CHAN_LEN:
1993                 chlenp = va_arg(ap, uint32_t *);
1994                 *chlenp = chp->ch_maxev;
1995                 break;
1996         case EVCH_SET_CHAN_LEN:
1997                 chlen = va_arg(ap, uint32_t);
1998                 ochlen = chp->ch_maxev;
1999                 chp->ch_maxev = min(chlen, evch_events_max);
2000                 if (ochlen < chp->ch_maxev) {
2001                         cv_signal(&chp->ch_pubcv);
2002                 }
2003                 break;
2004         case EVCH_GET_CHAN_LEN_MAX:
2005                 *va_arg(ap, uint32_t *) = evch_events_max;
2006                 break;
2007         default:
2008                 rc = EINVAL;




   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 /*
  26  * Copyright (c) 2018, Joyent, Inc.
  27  */
  28 
  29 /*
  30  * This file contains the source of the general purpose event channel extension
  31  * to the sysevent framework. This implementation is made up mainly of four
  32  * layers of functionality: the event queues (evch_evq_*()), the handling of
  33  * channels (evch_ch*()), the kernel interface (sysevent_evc_*()) and the
  34  * interface for the sysevent pseudo driver (evch_usr*()).
  35  * Libsysevent.so uses the pseudo driver sysevent's ioctl to access the event
  36  * channel extensions. The driver in turn uses the evch_usr*() functions below.
  37  *
  38  * The interfaces for user land and kernel are declared in sys/sysevent.h
  39  * Internal data structures for event channels are defined in
  40  * sys/sysevent_impl.h.
  41  *
  42  * The basic data structure for an event channel is of type evch_chan_t.
  43  * All channels are maintained by a list named evch_list. The list head
  44  * is of type evch_dlist_t.
  45  */
  46 
  47 #include <sys/types.h>
  48 #include <sys/errno.h>
  49 #include <sys/stropts.h>


1963 
1964                 err = nvlist_pack(attr, &patt, &asz, NV_ENCODE_NATIVE,
1965                     km_flags & EVCH_SLEEP ? KM_SLEEP : KM_NOSLEEP);
1966 
1967                 ASSERT(err != ENOMEM);
1968 
1969                 if (err != 0) {
1970                         return (EINVAL);
1971                 }
1972 
1973                 evp->seh_attr_off = attr_offset;
1974                 SE_FLAG(evp) = SE_PACKED_BUF;
1975         }
1976         return (evch_chpublish((evch_bind_t *)scp, evp, flags));
1977 }
1978 
1979 int
1980 sysevent_evc_control(evchan_t *scp, int cmd, ...)
1981 {
1982         va_list         ap;
1983         evch_chan_t     *chp;
1984         uint32_t        *chlenp;
1985         uint32_t        chlen;
1986         uint32_t        ochlen;
1987         int             rc = 0;
1988 
1989         if (scp == NULL) {
1990                 return (EINVAL);
1991         }
1992 
1993         chp = ((evch_bind_t *)scp)->bd_channel;
1994 
1995         va_start(ap, cmd);
1996         mutex_enter(&chp->ch_mutex);
1997         switch (cmd) {
1998         case EVCH_GET_CHAN_LEN:
1999                 chlenp = va_arg(ap, uint32_t *);
2000                 *chlenp = chp->ch_maxev;
2001                 break;
2002         case EVCH_SET_CHAN_LEN:
2003                 chlen = va_arg(ap, uint32_t);
2004                 ochlen = chp->ch_maxev;
2005                 chp->ch_maxev = min(chlen, evch_events_max);
2006                 if (ochlen < chp->ch_maxev) {
2007                         cv_signal(&chp->ch_pubcv);
2008                 }
2009                 break;
2010         case EVCH_GET_CHAN_LEN_MAX:
2011                 *va_arg(ap, uint32_t *) = evch_events_max;
2012                 break;
2013         default:
2014                 rc = EINVAL;