6753802 procfs may access kernel data it shouldn't
authorAntonello Cruz <Antonello.Cruz@Sun.COM>
Fri Oct 24 12:57:08 2008 -0700 (22 months ago)
changeset 79373160250b7dc5
parent 7936881bde3ddb48
child 79380e8e6d1a4d1e
6753802 procfs may access kernel data it shouldn't
usr/src/uts/common/contract/device.c
usr/src/uts/common/contract/process.c
usr/src/uts/common/fs/ctfs/ctfs_tmpl.c
usr/src/uts/common/fs/proc/prioctl.c
usr/src/uts/common/os/contract.c
usr/src/uts/common/sys/contract_impl.h
       1 --- a/usr/src/uts/common/contract/device.c	Fri Oct 24 14:23:54 2008 -0500
       2 +++ b/usr/src/uts/common/contract/device.c	Fri Oct 24 12:57:08 2008 -0700
       3 @@ -22,8 +22,6 @@
       4   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
       5   * Use is subject to license terms.
       6   */
       7 -
       8 -#pragma ident	"%Z%%M%	%I%	%E% SMI"
       9  
      10  #include <sys/mutex.h>
      11  #include <sys/debug.h>
      12 @@ -498,9 +496,11 @@
      13   * the {PRIV_SYS_DEVICES} privilege asserted in its effective set.
      14   */
      15  static int
      16 -ctmpl_device_set(struct ct_template *tmpl, ct_param_t *param, const cred_t *cr)
      17 +ctmpl_device_set(struct ct_template *tmpl, ct_kparam_t *kparam,
      18 +    const cred_t *cr)
      19  {
      20  	ctmpl_device_t *dtmpl = tmpl->ctmpl_data;
      21 +	ct_param_t *param = &kparam->param;
      22  	int error;
      23  	dev_info_t *dip;
      24  	int spec_type;
      25 @@ -510,12 +510,12 @@
      26  	ASSERT(MUTEX_HELD(&tmpl->ctmpl_lock));
      27  
      28  	if (param->ctpm_id == CTDP_MINOR) {
      29 -		str_value = (char *)param->ctpm_value;
      30 +		str_value = (char *)kparam->ctpm_kbuf;
      31  		str_value[param->ctpm_size - 1] = '\0';
      32  	} else {
      33  		if (param->ctpm_size < sizeof (uint64_t))
      34  			return (EINVAL);
      35 -		param_value = *(uint64_t *)param->ctpm_value;
      36 +		param_value = *(uint64_t *)kparam->ctpm_kbuf;
      37  	}
      38  
      39  	switch (param->ctpm_id) {
      40 @@ -597,10 +597,11 @@
      41   * returns the value of the requested term.
      42   */
      43  static int
      44 -ctmpl_device_get(struct ct_template *template, ct_param_t *param)
      45 +ctmpl_device_get(struct ct_template *template, ct_kparam_t *kparam)
      46  {
      47  	ctmpl_device_t *dtmpl = template->ctmpl_data;
      48 -	uint64_t *param_value = param->ctpm_value;
      49 +	ct_param_t *param = &kparam->param;
      50 +	uint64_t *param_value = kparam->ctpm_kbuf;
      51  
      52  	ASSERT(MUTEX_HELD(&template->ctmpl_lock));
      53  
      54 @@ -608,7 +609,7 @@
      55  	    param->ctpm_id == CTDP_NONEG) {
      56  		if (param->ctpm_size < sizeof (uint64_t))
      57  			return (EINVAL);
      58 -		param->ctpm_size = sizeof (uint64_t);
      59 +		kparam->ret_size = sizeof (uint64_t);
      60  	}
      61  
      62  	switch (param->ctpm_id) {
      63 @@ -620,9 +621,9 @@
      64  		break;
      65  	case CTDP_MINOR:
      66  		if (dtmpl->ctd_minor) {
      67 -			param->ctpm_size = strlcpy((char *)param->ctpm_value,
      68 +			kparam->ret_size = strlcpy((char *)kparam->ctpm_kbuf,
      69  			    dtmpl->ctd_minor, param->ctpm_size);
      70 -			param->ctpm_size++;
      71 +			kparam->ret_size++;
      72  		} else {
      73  			return (ENOENT);
      74  		}
     1.1 --- a/usr/src/uts/common/contract/process.c	Fri Oct 24 14:23:54 2008 -0500
     1.2 +++ b/usr/src/uts/common/contract/process.c	Fri Oct 24 12:57:08 2008 -0700
     1.3 @@ -22,8 +22,6 @@
     1.4   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     1.5   * Use is subject to license terms.
     1.6   */
     1.7 -
     1.8 -#pragma ident	"%Z%%M%	%I%	%E% SMI"
     1.9  
    1.10  #include <sys/mutex.h>
    1.11  #include <sys/debug.h>
    1.12 @@ -223,9 +221,11 @@
    1.13   * the desired terms.
    1.14   */
    1.15  static int
    1.16 -ctmpl_process_set(struct ct_template *tmpl, ct_param_t *param, const cred_t *cr)
    1.17 +ctmpl_process_set(struct ct_template *tmpl, ct_kparam_t *kparam,
    1.18 +    const cred_t *cr)
    1.19  {
    1.20  	ctmpl_process_t *ctp = tmpl->ctmpl_data;
    1.21 +	ct_param_t *param = &kparam->param;
    1.22  	contract_t *ct;
    1.23  	int error;
    1.24  	uint64_t param_value;
    1.25 @@ -233,12 +233,12 @@
    1.26  
    1.27  	if ((param->ctpm_id == CTPP_SVC_FMRI) ||
    1.28  	    (param->ctpm_id == CTPP_CREATOR_AUX)) {
    1.29 -		str_value = (char *)param->ctpm_value;
    1.30 +		str_value = (char *)kparam->ctpm_kbuf;
    1.31  		str_value[param->ctpm_size - 1] = '\0';
    1.32  	} else {
    1.33  		if (param->ctpm_size < sizeof (uint64_t))
    1.34  			return (EINVAL);
    1.35 -		param_value = *(uint64_t *)param->ctpm_value;
    1.36 +		param_value = *(uint64_t *)kparam->ctpm_kbuf;
    1.37  		/*
    1.38  		 * No process contract parameters are > 32 bits.
    1.39  		 * Unless it is a string.
    1.40 @@ -355,17 +355,18 @@
    1.41   * returns the requested term.
    1.42   */
    1.43  static int
    1.44 -ctmpl_process_get(struct ct_template *template, ct_param_t *param)
    1.45 +ctmpl_process_get(struct ct_template *template, ct_kparam_t *kparam)
    1.46  {
    1.47  	ctmpl_process_t *ctp = template->ctmpl_data;
    1.48 -	uint64_t *param_value = param->ctpm_value;
    1.49 +	ct_param_t *param = &kparam->param;
    1.50 +	uint64_t *param_value = kparam->ctpm_kbuf;
    1.51  
    1.52  	if (param->ctpm_id == CTPP_SUBSUME ||
    1.53  	    param->ctpm_id == CTPP_PARAMS ||
    1.54  	    param->ctpm_id == CTPP_EV_FATAL) {
    1.55  		if (param->ctpm_size < sizeof (uint64_t))
    1.56  			return (EINVAL);
    1.57 -		param->ctpm_size = sizeof (uint64_t);
    1.58 +		kparam->ret_size = sizeof (uint64_t);
    1.59  	}
    1.60  
    1.61  	switch (param->ctpm_id) {
    1.62 @@ -378,28 +379,28 @@
    1.63  		break;
    1.64  	case CTPP_SVC_FMRI:
    1.65  		if (ctp->ctp_svc_fmri == NULL) {
    1.66 -			param->ctpm_size =
    1.67 -			    strlcpy((char *)param->ctpm_value,
    1.68 +			kparam->ret_size =
    1.69 +			    strlcpy((char *)kparam->ctpm_kbuf,
    1.70  			    CT_PR_SVC_DEFAULT, param->ctpm_size);
    1.71  		} else {
    1.72 -			param->ctpm_size =
    1.73 -			    strlcpy((char *)param->ctpm_value,
    1.74 +			kparam->ret_size =
    1.75 +			    strlcpy((char *)kparam->ctpm_kbuf,
    1.76  			    refstr_value(ctp->ctp_svc_fmri), param->ctpm_size);
    1.77  		}
    1.78 -		param->ctpm_size++;
    1.79 +		kparam->ret_size++;
    1.80  		break;
    1.81  	case CTPP_CREATOR_AUX:
    1.82  		if (ctp->ctp_svc_aux == NULL) {
    1.83 -			param->ctpm_size =
    1.84 -			    strlcpy((char *)param->ctpm_value,
    1.85 +			kparam->ret_size =
    1.86 +			    strlcpy((char *)kparam->ctpm_kbuf,
    1.87  			    refstr_value(conp_svc_aux_default),
    1.88  			    param->ctpm_size);
    1.89  		} else {
    1.90 -			param->ctpm_size =
    1.91 -			    strlcpy((char *)param->ctpm_value,
    1.92 +			kparam->ret_size =
    1.93 +			    strlcpy((char *)kparam->ctpm_kbuf,
    1.94  			    refstr_value(ctp->ctp_svc_aux), param->ctpm_size);
    1.95  		}
    1.96 -		param->ctpm_size++;
    1.97 +		kparam->ret_size++;
    1.98  		break;
    1.99  	case CTPP_EV_FATAL:
   1.100  		*param_value = ctp->ctp_ev_fatal;
     2.1 --- a/usr/src/uts/common/fs/ctfs/ctfs_tmpl.c	Fri Oct 24 14:23:54 2008 -0500
     2.2 +++ b/usr/src/uts/common/fs/ctfs/ctfs_tmpl.c	Fri Oct 24 12:57:08 2008 -0700
     2.3 @@ -22,8 +22,6 @@
     2.4   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     2.5   * Use is subject to license terms.
     2.6   */
     2.7 -
     2.8 -#pragma ident	"%Z%%M%	%I%	%E% SMI"
     2.9  
    2.10  #include <sys/types.h>
    2.11  #include <sys/param.h>
    2.12 @@ -125,13 +123,10 @@
    2.13  	caller_context_t *ct)
    2.14  {
    2.15  	ctfs_tmplnode_t	*tmplnode = vp->v_data;
    2.16 -	ct_param_t param;
    2.17 -	STRUCT_DECL(ct_param, uarg);
    2.18 +	ct_kparam_t kparam;
    2.19 +	ct_param_t *param = &kparam.param;
    2.20  	ctid_t ctid;
    2.21 -	uint32_t local_ctpm_size;
    2.22  	int error;
    2.23 -
    2.24 -	STRUCT_INIT(uarg, flag);
    2.25  
    2.26  	switch (cmd) {
    2.27  	case CT_TACTIVATE:
    2.28 @@ -150,39 +145,24 @@
    2.29  		*rvalp = ctid;
    2.30  		break;
    2.31  	case CT_TSET:
    2.32 -		if (copyin((void *)arg, STRUCT_BUF(uarg), STRUCT_SIZE(uarg)))
    2.33 -			return (EFAULT);
    2.34 -		param.ctpm_id = STRUCT_FGET(uarg, ctpm_id);
    2.35 -		param.ctpm_size = STRUCT_FGET(uarg, ctpm_size);
    2.36 -		if (param.ctpm_size > CT_PARAM_MAX_SIZE ||
    2.37 -		    param.ctpm_size == 0)
    2.38 -			return (EINVAL);
    2.39 -		param.ctpm_value = kmem_alloc(param.ctpm_size, KM_SLEEP);
    2.40 -		if (copyin(STRUCT_FGETP(uarg, ctpm_value), param.ctpm_value,
    2.41 -		    param.ctpm_size))
    2.42 -			return (EFAULT);
    2.43 -		error = ctmpl_set(tmplnode->ctfs_tmn_tmpl, &param, cr);
    2.44 -		kmem_free(param.ctpm_value, param.ctpm_size);
    2.45 +		error = ctparam_copyin((void *)arg, &kparam, flag, cmd);
    2.46 +		if (error != 0)
    2.47 +			return (error);
    2.48 +		error = ctmpl_set(tmplnode->ctfs_tmn_tmpl, &kparam, cr);
    2.49 +		kmem_free(kparam.ctpm_kbuf, param->ctpm_size);
    2.50 +
    2.51  		return (error);
    2.52  	case CT_TGET:
    2.53 -		if (copyin((void *)arg, STRUCT_BUF(uarg), STRUCT_SIZE(uarg)))
    2.54 -			return (EFAULT);
    2.55 -		param.ctpm_id = STRUCT_FGET(uarg, ctpm_id);
    2.56 -		param.ctpm_size = STRUCT_FGET(uarg, ctpm_size);
    2.57 -		if (param.ctpm_size > CT_PARAM_MAX_SIZE)
    2.58 -			param.ctpm_size = CT_PARAM_MAX_SIZE;
    2.59 -		if (param.ctpm_size == 0)
    2.60 -			return (EINVAL);
    2.61 -		local_ctpm_size = param.ctpm_size;
    2.62 -		param.ctpm_value = kmem_alloc(param.ctpm_size, KM_SLEEP);
    2.63 -		error = ctmpl_get(tmplnode->ctfs_tmn_tmpl, &param);
    2.64 -		STRUCT_FSET(uarg, ctpm_size, param.ctpm_size);
    2.65 -		if (!error &&
    2.66 -		    (copyout(param.ctpm_value, STRUCT_FGETP(uarg, ctpm_value),
    2.67 -		    MIN(local_ctpm_size, param.ctpm_size))) ||
    2.68 -		    copyout(STRUCT_BUF(uarg), (void *)arg, STRUCT_SIZE(uarg)))
    2.69 -			error = EFAULT;
    2.70 -		kmem_free(param.ctpm_value, local_ctpm_size);
    2.71 +		error = ctparam_copyin((void *)arg, &kparam, flag, cmd);
    2.72 +		if (error != 0)
    2.73 +			return (error);
    2.74 +		error = ctmpl_get(tmplnode->ctfs_tmn_tmpl, &kparam);
    2.75 +		if (error != 0) {
    2.76 +			kmem_free(kparam.ctpm_kbuf, param->ctpm_size);
    2.77 +		} else {
    2.78 +			error = ctparam_copyout(&kparam, (void *)arg, flag);
    2.79 +		}
    2.80 +
    2.81  		return (error);
    2.82  	default:
    2.83  		return (EINVAL);
     3.1 --- a/usr/src/uts/common/fs/proc/prioctl.c	Fri Oct 24 14:23:54 2008 -0500
     3.2 +++ b/usr/src/uts/common/fs/proc/prioctl.c	Fri Oct 24 12:57:08 2008 -0700
     3.3 @@ -25,9 +25,6 @@
     3.4  
     3.5  /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     3.6  /*	  All rights reserved.  	*/
     3.7 -
     3.8 -
     3.9 -#pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.29	*/
    3.10  
    3.11  #include <sys/types.h>
    3.12  #include <sys/param.h>
    3.13 @@ -86,39 +83,45 @@
    3.14  extern	void	oprgetpsinfo(proc_t *, prpsinfo_t *, kthread_t *);
    3.15  static	int	oprgetmap(proc_t *, list_t *);
    3.16  
    3.17 -/*ARGSUSED*/
    3.18  static int
    3.19  prctioctl(prnode_t *pnp, int cmd, intptr_t arg, int flag, cred_t *cr)
    3.20  {
    3.21  	int error = 0;
    3.22 -	ct_param_t param;
    3.23 +	ct_kparam_t kparam;
    3.24 +	ct_param_t *param = &kparam.param;
    3.25  	ct_template_t *tmpl;
    3.26  
    3.27  	if (cmd != CT_TSET && cmd != CT_TGET)
    3.28  		return (EINVAL);
    3.29  
    3.30 -	if (copyin((void *)arg, &param, sizeof (ct_param_t)))
    3.31 -		return (EFAULT);
    3.32 +	error = ctparam_copyin((void *)arg, &kparam, flag, cmd);
    3.33 +	if (error != 0)
    3.34 +		return (error);
    3.35  
    3.36 -	if ((error = prlock(pnp, ZNO)) != 0)
    3.37 +	if ((error = prlock(pnp, ZNO)) != 0) {
    3.38 +		kmem_free(kparam.ctpm_kbuf, param->ctpm_size);
    3.39  		return (error);
    3.40 +	}
    3.41  
    3.42  	tmpl = pnp->pr_common->prc_thread->t_lwp->lwp_ct_active[pnp->pr_cttype];
    3.43  	if (tmpl == NULL) {
    3.44  		prunlock(pnp);
    3.45 +		kmem_free(kparam.ctpm_kbuf, param->ctpm_size);
    3.46  		return (ESTALE);
    3.47  	}
    3.48  
    3.49  	if (cmd == CT_TSET)
    3.50 -		error = ctmpl_set(tmpl, &param, cr);
    3.51 +		error = ctmpl_set(tmpl, &kparam, cr);
    3.52  	else
    3.53 -		error = ctmpl_get(tmpl, &param);
    3.54 +		error = ctmpl_get(tmpl, &kparam);
    3.55  
    3.56  	prunlock(pnp);
    3.57  
    3.58 -	if (cmd == CT_TGET && error == 0 &&
    3.59 -	    copyout(&param, (void *)arg, sizeof (ct_param_t)))
    3.60 -		error = EFAULT;
    3.61 +	if (cmd == CT_TGET && error == 0) {
    3.62 +		error = ctparam_copyout(&kparam, (void *)arg, flag);
    3.63 +	} else {
    3.64 +		kmem_free(kparam.ctpm_kbuf, param->ctpm_size);
    3.65 +	}
    3.66  
    3.67  	return (error);
    3.68  }
     4.1 --- a/usr/src/uts/common/os/contract.c	Fri Oct 24 14:23:54 2008 -0500
     4.2 +++ b/usr/src/uts/common/os/contract.c	Fri Oct 24 12:57:08 2008 -0700
     4.3 @@ -22,8 +22,6 @@
     4.4   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     4.5   * Use is subject to license terms.
     4.6   */
     4.7 -
     4.8 -#pragma ident	"%Z%%M%	%I%	%E% SMI"
     4.9  
    4.10  /*
    4.11   * Contracts
    4.12 @@ -171,6 +169,7 @@
    4.13  #include <sys/list.h>
    4.14  #include <sys/sysmacros.h>
    4.15  #include <sys/proc.h>
    4.16 +#include <sys/ctfs.h>
    4.17  #include <sys/contract_impl.h>
    4.18  #include <sys/contract/process_impl.h>
    4.19  #include <sys/dditypes.h>
    4.20 @@ -1418,6 +1417,82 @@
    4.21  }
    4.22  
    4.23  /*
    4.24 + * ctparam_copyin
    4.25 + *
    4.26 + * copyin a ct_param_t for CT_TSET or CT_TGET commands.
    4.27 + * If ctparam_copyout() is not called after ctparam_copyin(), then
    4.28 + * the caller must kmem_free() the buffer pointed by kparam->ctpm_kbuf.
    4.29 + *
    4.30 + * The copyin/out of ct_param_t is not done in ctmpl_set() and ctmpl_get()
    4.31 + * because prctioctl() calls ctmpl_set() and ctmpl_get() while holding a
    4.32 + * process lock.
    4.33 + */
    4.34 +int
    4.35 +ctparam_copyin(const void *uaddr, ct_kparam_t *kparam, int flag, int cmd)
    4.36 +{
    4.37 +	uint32_t size;
    4.38 +	void *ubuf;
    4.39 +	ct_param_t *param = &kparam->param;
    4.40 +	STRUCT_DECL(ct_param, uarg);
    4.41 +
    4.42 +	STRUCT_INIT(uarg, flag);
    4.43 +	if (copyin(uaddr, STRUCT_BUF(uarg), STRUCT_SIZE(uarg)))
    4.44 +		return (EFAULT);
    4.45 +	size = STRUCT_FGET(uarg, ctpm_size);
    4.46 +	ubuf = STRUCT_FGETP(uarg, ctpm_value);
    4.47 +
    4.48 +	if (size > CT_PARAM_MAX_SIZE || size == 0)
    4.49 +		return (EINVAL);
    4.50 +
    4.51 +	kparam->ctpm_kbuf = kmem_alloc(size, KM_SLEEP);
    4.52 +	if (cmd == CT_TSET) {
    4.53 +		if (copyin(ubuf, kparam->ctpm_kbuf, size)) {
    4.54 +			kmem_free(kparam->ctpm_kbuf, size);
    4.55 +			return (EFAULT);
    4.56 +		}
    4.57 +	}
    4.58 +	param->ctpm_id = STRUCT_FGET(uarg, ctpm_id);
    4.59 +	param->ctpm_size = size;
    4.60 +	param->ctpm_value = ubuf;
    4.61 +	kparam->ret_size = 0;
    4.62 +
    4.63 +	return (0);
    4.64 +}
    4.65 +
    4.66 +/*
    4.67 + * ctparam_copyout
    4.68 + *
    4.69 + * copyout a ct_kparam_t and frees the buffer pointed by the member
    4.70 + * ctpm_kbuf of ct_kparam_t
    4.71 + */
    4.72 +int
    4.73 +ctparam_copyout(ct_kparam_t *kparam, void *uaddr, int flag)
    4.74 +{
    4.75 +	int r = 0;
    4.76 +	ct_param_t *param = &kparam->param;
    4.77 +	STRUCT_DECL(ct_param, uarg);
    4.78 +
    4.79 +	STRUCT_INIT(uarg, flag);
    4.80 +
    4.81 +	STRUCT_FSET(uarg, ctpm_id, param->ctpm_id);
    4.82 +	STRUCT_FSET(uarg, ctpm_size, kparam->ret_size);
    4.83 +	STRUCT_FSETP(uarg, ctpm_value, param->ctpm_value);
    4.84 +	if (copyout(STRUCT_BUF(uarg), uaddr, STRUCT_SIZE(uarg))) {
    4.85 +		r = EFAULT;
    4.86 +		goto error;
    4.87 +	}
    4.88 +	if (copyout(kparam->ctpm_kbuf, param->ctpm_value,
    4.89 +	    MIN(kparam->ret_size, param->ctpm_size))) {
    4.90 +		r = EFAULT;
    4.91 +	}
    4.92 +
    4.93 +error:
    4.94 +	kmem_free(kparam->ctpm_kbuf, param->ctpm_size);
    4.95 +
    4.96 +	return (r);
    4.97 +}
    4.98 +
    4.99 +/*
   4.100   * ctmpl_free
   4.101   *
   4.102   * Frees a template.
   4.103 @@ -1458,9 +1533,10 @@
   4.104   * Sets the requested terms of a template.
   4.105   */
   4.106  int
   4.107 -ctmpl_set(ct_template_t *template, ct_param_t *param, const cred_t *cr)
   4.108 +ctmpl_set(ct_template_t *template, ct_kparam_t *kparam, const cred_t *cr)
   4.109  {
   4.110  	int result = 0;
   4.111 +	ct_param_t *param = &kparam->param;
   4.112  	uint64_t param_value;
   4.113  
   4.114  	if (param->ctpm_id == CTP_COOKIE ||
   4.115 @@ -1469,7 +1545,7 @@
   4.116  		if (param->ctpm_size < sizeof (uint64_t)) {
   4.117  			return (EINVAL);
   4.118  		} else {
   4.119 -			param_value = *(uint64_t *)param->ctpm_value;
   4.120 +			param_value = *(uint64_t *)kparam->ctpm_kbuf;
   4.121  		}
   4.122  	}
   4.123  
   4.124 @@ -1503,7 +1579,7 @@
   4.125  		 */
   4.126  		/* FALLTHROUGH */
   4.127  	default:
   4.128 -		result = template->ctmpl_ops->ctop_set(template, param, cr);
   4.129 +		result = template->ctmpl_ops->ctop_set(template, kparam, cr);
   4.130  	}
   4.131  	mutex_exit(&template->ctmpl_lock);
   4.132  
   4.133 @@ -1517,7 +1593,7 @@
   4.134   *
   4.135   * If the term requested is a variable-sized term and the buffer
   4.136   * provided is too small for the data, we truncate the data and return
   4.137 - * the buffer size necessary to fit the term in param->ctpm_size. If the
   4.138 + * the buffer size necessary to fit the term in kparam->ret_size. If the
   4.139   * term requested is fix-sized (uint64_t) and the buffer provided is too
   4.140   * small, we return EINVAL.  This should never happen if you're using
   4.141   * libcontract(3LIB), only if you call ioctl with a hand constructed
   4.142 @@ -1527,9 +1603,10 @@
   4.143   * parameters.
   4.144   */
   4.145  int
   4.146 -ctmpl_get(ct_template_t *template, ct_param_t *param)
   4.147 +ctmpl_get(ct_template_t *template, ct_kparam_t *kparam)
   4.148  {
   4.149  	int result = 0;
   4.150 +	ct_param_t *param = &kparam->param;
   4.151  	uint64_t *param_value;
   4.152  
   4.153  	if (param->ctpm_id == CTP_COOKIE ||
   4.154 @@ -1538,8 +1615,8 @@
   4.155  		if (param->ctpm_size < sizeof (uint64_t)) {
   4.156  			return (EINVAL);
   4.157  		} else {
   4.158 -			param_value = param->ctpm_value;
   4.159 -			param->ctpm_size = sizeof (uint64_t);
   4.160 +			param_value = kparam->ctpm_kbuf;
   4.161 +			kparam->ret_size = sizeof (uint64_t);
   4.162  		}
   4.163  	}
   4.164  
   4.165 @@ -1555,7 +1632,7 @@
   4.166  		*param_value = template->ctmpl_ev_crit;
   4.167  		break;
   4.168  	default:
   4.169 -		result = template->ctmpl_ops->ctop_get(template, param);
   4.170 +		result = template->ctmpl_ops->ctop_get(template, kparam);
   4.171  	}
   4.172  	mutex_exit(&template->ctmpl_lock);
   4.173  
     5.1 --- a/usr/src/uts/common/sys/contract_impl.h	Fri Oct 24 14:23:54 2008 -0500
     5.2 +++ b/usr/src/uts/common/sys/contract_impl.h	Fri Oct 24 12:57:08 2008 -0700
     5.3 @@ -25,8 +25,6 @@
     5.4  
     5.5  #ifndef	_SYS_CONTRACT_IMPL_H
     5.6  #define	_SYS_CONTRACT_IMPL_H
     5.7 -
     5.8 -#pragma ident	"%Z%%M%	%I%	%E% SMI"
     5.9  
    5.10  #include <sys/types.h>
    5.11  #include <sys/list.h>
    5.12 @@ -108,6 +106,15 @@
    5.13  
    5.14  #endif /* _SYSCALL32 */
    5.15  
    5.16 +/*
    5.17 + * in kernel version of parameter structure.
    5.18 + */
    5.19 +typedef struct ct_kparam {
    5.20 +	ct_param_t	param;		/* copy of user ct_param_t */
    5.21 +	void		*ctpm_kbuf;	/* kernel buffer for parameter value */
    5.22 +	uint32_t	ret_size;	/* parameter value size for copyout */
    5.23 +} ct_kparam_t;
    5.24 +
    5.25  struct proc;
    5.26  
    5.27  /*
    5.28 @@ -116,9 +123,9 @@
    5.29  typedef struct ctmplops {
    5.30  	struct ct_template	*(*ctop_dup)(struct ct_template *);
    5.31  	void		(*ctop_free)(struct ct_template *);
    5.32 -	int		(*ctop_set)(struct ct_template *, ct_param_t *,
    5.33 +	int		(*ctop_set)(struct ct_template *, ct_kparam_t *,
    5.34  			const cred_t *);
    5.35 -	int		(*ctop_get)(struct ct_template *, ct_param_t *);
    5.36 +	int		(*ctop_get)(struct ct_template *, ct_kparam_t *);
    5.37  	int		(*ctop_create)(struct ct_template *, ctid_t *);
    5.38  	uint_t		allevents;
    5.39  } ctmplops_t;
    5.40 @@ -308,12 +315,18 @@
    5.41   * Contract template interfaces
    5.42   */
    5.43  void ctmpl_free(ct_template_t *);
    5.44 -int ctmpl_set(ct_template_t *, ct_param_t *, const cred_t *);
    5.45 -int ctmpl_get(ct_template_t *, ct_param_t *);
    5.46 +int ctmpl_set(ct_template_t *, ct_kparam_t *, const cred_t *);
    5.47 +int ctmpl_get(ct_template_t *, ct_kparam_t *);
    5.48  ct_template_t *ctmpl_dup(ct_template_t *);
    5.49  void ctmpl_activate(ct_template_t *);
    5.50  void ctmpl_clear(ct_template_t *);
    5.51  int ctmpl_create(ct_template_t *, ctid_t *);
    5.52 +
    5.53 +/*
    5.54 + * Contract parameter functions
    5.55 + */
    5.56 +int ctparam_copyin(const void *, ct_kparam_t *, int, int);
    5.57 +int ctparam_copyout(ct_kparam_t *, void *, int);
    5.58  
    5.59  /*
    5.60   * Contract functions