diff --git a/components/lwp/terminal/freebsd/tty.c b/components/lwp/terminal/freebsd/tty.c index e5a6e79f13cf..cc0cf5525357 100644 --- a/components/lwp/terminal/freebsd/tty.c +++ b/components/lwp/terminal/freebsd/tty.c @@ -1146,12 +1146,38 @@ static int tty_generic_ioctl(struct lwp_tty *tp, rt_ubase_t cmd, void *data, /* This device supports non-blocking operation. */ return 0; case FIONREAD: - *(int *)data = ttyinq_bytescanonicalized(&tp->t_inq); + { + int nread = ttyinq_bytescanonicalized(&tp->t_inq); + if (lwp_in_user_space((void *)data)) + { + if (lwp_put_to_user(data, &nread, sizeof(int)) != sizeof(int)) + { + return -EFAULT; + } + } + else + { + *(int *)data = nread; + } return 0; + } case FIONWRITE: case TIOCOUTQ: - *(int *)data = ttyoutq_bytesused(&tp->t_outq); + { + int nused = ttyoutq_bytesused(&tp->t_outq); + if (lwp_in_user_space((void *)data)) + { + if (lwp_put_to_user(data, &nused, sizeof(int)) != sizeof(int)) + { + return -EFAULT; + } + } + else + { + *(int *)data = nused; + } return 0; + } #if BSD_USING_FIO_OWNERSHIP case FIOSETOWN: if (tp->t_session != NULL && !tty_is_ctty(tp, td->lwp)) @@ -1269,21 +1295,50 @@ static int tty_generic_ioctl(struct lwp_tty *tp, rt_ubase_t cmd, void *data, *(int *)data = TTYDISC; return 0; case TIOCGPGRP: + { + int pgrp; if (!tty_is_ctty(tp, td->lwp)) + { return -ENOTTY; + } - if (tp->t_pgrp != NULL) - *(int *)data = tp->t_pgrp->pgid; + pgrp = (tp->t_pgrp != NULL) ? tp->t_pgrp->pgid : NO_PID; + if (lwp_in_user_space((void *)data)) + { + if (lwp_put_to_user(data, &pgrp, sizeof(int)) != sizeof(int)) + { + return -EFAULT; + } + } else - *(int *)data = NO_PID; + { + *(int *)data = pgrp; + } return 0; + } case TIOCGSID: + { + int sid; if (!tty_is_ctty(tp, td->lwp)) + { return -ENOTTY; + } MPASS(tp->t_session); - *(int *)data = tp->t_session->sid; + sid = tp->t_session->sid; + if (lwp_in_user_space((void *)data)) + { + if (lwp_put_to_user(data, &sid, sizeof(int)) != sizeof(int)) + { + return -EFAULT; + } + } + else + { + *(int *)data = sid; + } return 0; + } case TIOCNOTTY: return tty_drop_ctty(tp, td->lwp); case TIOCSCTTY: @@ -1338,11 +1393,33 @@ static int tty_generic_ioctl(struct lwp_tty *tp, rt_ubase_t cmd, void *data, return (error); case TIOCGWINSZ: /* Obtain window size. */ - *(struct winsize *)data = tp->t_winsize; + if (lwp_in_user_space((void *)data)) + { + if (lwp_put_to_user(data, &tp->t_winsize, sizeof(struct winsize)) != sizeof(struct winsize)) + { + return -EFAULT; + } + } + else + { + *(struct winsize *)data = tp->t_winsize; + } return 0; case TIOCSWINSZ: /* Set window size. */ - tty_set_winsize(tp, data); + if (lwp_in_user_space((void *)data)) + { + struct winsize ws; + if (lwp_get_from_user(&ws, data, sizeof(struct winsize)) != sizeof(struct winsize)) + { + return -EFAULT; + } + tty_set_winsize(tp, &ws); + } + else + { + tty_set_winsize(tp, data); + } return 0; case TIOCEXCL: tp->t_flags |= TF_EXCLUDE; diff --git a/components/lwp/terminal/freebsd/tty_compat.c b/components/lwp/terminal/freebsd/tty_compat.c index 08ff49f8017e..6fdd399a6eaf 100644 --- a/components/lwp/terminal/freebsd/tty_compat.c +++ b/components/lwp/terminal/freebsd/tty_compat.c @@ -507,45 +507,122 @@ int lwp_tty_ioctl_adapter(lwp_tty_t tp, int cmd, int oflags, void *args, rt_thre /* Controlling terminal */ case TIOCSCTTY: case TIOCNOTTY: + error = IOCTL(cmd, RT_NULL, fflags, td); + break; /* Process group and session ID */ case TIOCGPGRP: + { + int pgrp; + error = IOCTL(TIOCGPGRP, (rt_caddr_t)&pgrp, fflags, td); + if (!error) + { + error = _copy_to_user(args, &pgrp, sizeof(pgrp)); + } + break; + } + case TIOCSPGRP: + { + int pgrp; + error = _copy_from_user(&pgrp, args, sizeof(pgrp)); + if (!error) + { + error = IOCTL(TIOCSPGRP, (rt_caddr_t)&pgrp, fflags, td); + } + break; + } + case TIOCGSID: + { + int sid; + error = IOCTL(TIOCGSID, (rt_caddr_t)&sid, fflags, td); + if (!error) + { + error = _copy_to_user(args, &sid, sizeof(sid)); + } + break; + } - /* TIOCOUTQ */ - /* TIOCSTI */ case TIOCGWINSZ: + { + struct winsize ws; + error = IOCTL(TIOCGWINSZ, (rt_caddr_t)&ws, fflags, td); + if (!error) + { + error = _copy_to_user(args, &ws, sizeof(ws)); + } + break; + } + case TIOCSWINSZ: - error = IOCTL(cmd, (rt_caddr_t)args, fflags, td); + { + struct winsize ws; + error = _copy_from_user(&ws, args, sizeof(ws)); + if (!error) + { + error = IOCTL(TIOCSWINSZ, (rt_caddr_t)&ws, fflags, td); + } break; -#ifdef USING_BSD_IOCTL_EXT - case TIOCMGET: - args->cmd = TIOCMGET; - error = (sys_ioctl(td, (struct ioctl_args *)args)); + } + + case TIOCSTI: + { + char ch; + error = _copy_from_user(&ch, args, sizeof(ch)); + if (!error) + { + error = IOCTL(TIOCSTI, (rt_caddr_t)&ch, fflags, td); + } break; + } - case TIOCMBIS: - args->cmd = TIOCMBIS; - error = (sys_ioctl(td, (struct ioctl_args *)args)); + case TIOCOUTQ: + case FIONWRITE: + { + int nout; + error = IOCTL(cmd, (rt_caddr_t)&nout, fflags, td); + if (!error) + { + error = _copy_to_user(args, &nout, sizeof(nout)); + } break; + } - case TIOCMBIC: - args->cmd = TIOCMBIC; - error = (sys_ioctl(td, (struct ioctl_args *)args)); + case TIOCMGET: + { + int bits; + error = IOCTL(TIOCMGET, (rt_caddr_t)&bits, fflags, td); + if (!error) + { + error = _copy_to_user(args, &bits, sizeof(bits)); + } break; + } + case TIOCMBIS: + case TIOCMBIC: case TIOCMSET: - args->cmd = TIOCMSET; - error = (sys_ioctl(td, (struct ioctl_args *)args)); + { + int bits; + error = _copy_from_user(&bits, args, sizeof(bits)); + if (!error) + { + error = IOCTL(cmd, (rt_caddr_t)&bits, fflags, td); + } break; -#endif /* USING_BSD_IOCTL_EXT */ - /* TIOCGSOFTCAR */ - /* TIOCSSOFTCAR */ + } case FIONREAD: /* TIOCINQ */ - error = (IOCTL(FIONREAD, args, fflags, td)); + { + int nread; + error = IOCTL(FIONREAD, (rt_caddr_t)&nread, fflags, td); + if (!error) + { + error = _copy_to_user(args, &nread, sizeof(nread)); + } break; + } #ifdef USING_BSD_IOCTL_EXT /* TIOCLINUX */ diff --git a/components/lwp/terminal/tty_internal.h b/components/lwp/terminal/tty_internal.h index 8bf336cb89a8..da151f02c051 100644 --- a/components/lwp/terminal/tty_internal.h +++ b/components/lwp/terminal/tty_internal.h @@ -17,6 +17,31 @@ extern struct cdevsw bsd_ttydev_methods; extern struct bsd_fileops bsd_ptsdev_methods; +enum lwp_ptmx_ioctl_arg_type +{ + LWP_PTMX_IOCTL_UNSUPPORTED, + LWP_PTMX_IOCTL_NONE, + LWP_PTMX_IOCTL_INT_IN, + LWP_PTMX_IOCTL_INT_OUT, + LWP_PTMX_IOCTL_UINT_OUT, + LWP_PTMX_IOCTL_CHAR_IN, + LWP_PTMX_IOCTL_WINSIZE_IN, + LWP_PTMX_IOCTL_WINSIZE_OUT, + LWP_PTMX_IOCTL_TERMIOS_IN, + LWP_PTMX_IOCTL_TERMIOS_OUT, +}; + +enum lwp_ptmx_ioctl_arg_type lwp_ptmx_ioctl_arg_type(rt_ubase_t cmd); + +typedef rt_size_t (*lwp_ptmx_copy_fn)(void *dst, void *src, rt_size_t size, + void *context); +typedef int (*lwp_ptmx_ioctl_fn)(rt_ubase_t cmd, void *arg, void *context); + +int lwp_ptmx_ioctl_forward(rt_ubase_t cmd, void *arg, + lwp_ptmx_copy_fn copy_from_user, + lwp_ptmx_copy_fn copy_to_user, + lwp_ptmx_ioctl_fn ioctl, void *context); + /* bsd devsw porting */ void bsd_devsw_init(struct lwp_ttydevsw *tsw); diff --git a/components/lwp/terminal/tty_ptmx.c b/components/lwp/terminal/tty_ptmx.c index 5938bf010390..36b82510ced4 100644 --- a/components/lwp/terminal/tty_ptmx.c +++ b/components/lwp/terminal/tty_ptmx.c @@ -38,7 +38,9 @@ static int ptm_fops_open(struct dfs_file *file) /* detached operation from devfs */ if (rc == 0) + { file->vnode->fops = &ptm_fops; + } } else { @@ -157,6 +159,196 @@ static ssize_t ptm_fops_write(struct dfs_file *file, const void *buf, return rc; } +enum lwp_ptmx_ioctl_arg_type lwp_ptmx_ioctl_arg_type(rt_ubase_t cmd) +{ + switch (cmd) + { + case TIOCSDTR: + case TIOCCDTR: + case TIOCNOTTY: + case TIOCSCTTY: + case TIOCDRAIN: + case TIOCEXCL: + case TIOCNXCL: + case TIOCSTOP: + case TIOCSTART: + case TIOCSTAT: + case TIOCSBRK: + case TIOCCBRK: + return LWP_PTMX_IOCTL_NONE; + + case TIOCPKT: + case TIOCSIG: + case FIONBIO: + case TIOCSPGRP: + case TIOCMSET: + case TIOCMBIS: + case TIOCMBIC: + case FIOASYNC: + case FIOSETOWN: + case TIOCFLUSH: + case TIOCSDRAINWAIT: + case TIOCCONS: + case TIOCSETD: + return LWP_PTMX_IOCTL_INT_IN; + + case TIOCGPGRP: + case TIOCGSID: + case FIONREAD: + case TIOCOUTQ: + case FIONWRITE: + case TIOCMGET: + case FIOGETOWN: + case TIOCGETD: + case TIOCGDRAINWAIT: + return LWP_PTMX_IOCTL_INT_OUT; + + case TIOCGPTN: + return LWP_PTMX_IOCTL_UINT_OUT; + + case TIOCSTI: + return LWP_PTMX_IOCTL_CHAR_IN; + + case TIOCSWINSZ: + return LWP_PTMX_IOCTL_WINSIZE_IN; + + case TIOCGWINSZ: + return LWP_PTMX_IOCTL_WINSIZE_OUT; + + case TCSETS: + case TCSETSW: + case TCSETSF: + return LWP_PTMX_IOCTL_TERMIOS_IN; + + case TCGETS: + return LWP_PTMX_IOCTL_TERMIOS_OUT; + + default: + return LWP_PTMX_IOCTL_UNSUPPORTED; + } +} + +int lwp_ptmx_ioctl_forward(rt_ubase_t cmd, void *arg, + lwp_ptmx_copy_fn copy_from_user, + lwp_ptmx_copy_fn copy_to_user, + lwp_ptmx_ioctl_fn ioctl, void *context) +{ + int rc; + rt_size_t arg_size = 0; + rt_bool_t copy_out = RT_FALSE; + void *kernel_arg = RT_NULL; + enum lwp_ptmx_ioctl_arg_type arg_type; + union + { + int int_value; + unsigned int uint_value; + char char_value; + struct winsize winsize_value; + struct termios termios_value; + } value; + + arg_type = lwp_ptmx_ioctl_arg_type(cmd); + switch (arg_type) + { + case LWP_PTMX_IOCTL_NONE: + break; + case LWP_PTMX_IOCTL_INT_IN: + kernel_arg = &value.int_value; + arg_size = sizeof(value.int_value); + break; + case LWP_PTMX_IOCTL_INT_OUT: + kernel_arg = &value.int_value; + arg_size = sizeof(value.int_value); + copy_out = RT_TRUE; + break; + case LWP_PTMX_IOCTL_UINT_OUT: + kernel_arg = &value.uint_value; + arg_size = sizeof(value.uint_value); + copy_out = RT_TRUE; + break; + case LWP_PTMX_IOCTL_CHAR_IN: + kernel_arg = &value.char_value; + arg_size = sizeof(value.char_value); + break; + case LWP_PTMX_IOCTL_WINSIZE_IN: + kernel_arg = &value.winsize_value; + arg_size = sizeof(value.winsize_value); + break; + case LWP_PTMX_IOCTL_WINSIZE_OUT: + kernel_arg = &value.winsize_value; + arg_size = sizeof(value.winsize_value); + copy_out = RT_TRUE; + break; + case LWP_PTMX_IOCTL_TERMIOS_IN: + kernel_arg = &value.termios_value; + arg_size = sizeof(value.termios_value); + break; + case LWP_PTMX_IOCTL_TERMIOS_OUT: + kernel_arg = &value.termios_value; + arg_size = sizeof(value.termios_value); + copy_out = RT_TRUE; + break; + default: + return -ENOTTY; + } + + if (arg_size && !copy_out && + copy_from_user(kernel_arg, arg, arg_size, context) != arg_size) + { + return -EFAULT; + } + + rc = ioctl(cmd, kernel_arg, context); + if (!rc && copy_out && + copy_to_user(arg, kernel_arg, arg_size, context) != arg_size) + { + rc = -EFAULT; + } + + return rc; +} + +struct ptm_ioctl_context +{ + struct dfs_file *file; + lwp_tty_t tp; +}; + +static rt_size_t ptm_copy_from_user(void *dst, void *src, rt_size_t size, + void *context) +{ + RT_UNUSED(context); + return lwp_get_from_user(dst, src, size); +} + +static rt_size_t ptm_copy_to_user(void *dst, void *src, rt_size_t size, + void *context) +{ + RT_UNUSED(context); + return lwp_put_to_user(dst, src, size); +} + +static int ptm_ioctl_backend(rt_ubase_t cmd, void *arg, void *context) +{ + struct ptm_ioctl_context *ptm_context = context; + + return bsd_ptsdev_methods.fo_ioctl( + ptm_context->tp, cmd, arg, 0, FFLAGS(ptm_context->file->flags), + rt_thread_self()); +} + +static int ptm_ioctl_forward(struct dfs_file *file, lwp_tty_t tp, + rt_ubase_t cmd, void *arg) +{ + struct ptm_ioctl_context context = { + .file = file, + .tp = tp, + }; + + return lwp_ptmx_ioctl_forward(cmd, arg, ptm_copy_from_user, + ptm_copy_to_user, ptm_ioctl_backend, &context); +} + static int ptm_fops_ioctl(struct dfs_file *file, int cmd, void *arg) { int rc; @@ -171,35 +363,40 @@ static int ptm_fops_ioctl(struct dfs_file *file, int cmd, void *arg) switch (cmd_normal) { - case TIOCSPTLCK: + case TIOCSPTLCK: + { + int is_lock; + if (lwp_get_from_user(&is_lock, arg, sizeof(int)) != sizeof(int)) { - int is_lock; - if (lwp_get_from_user(&is_lock, arg, sizeof(int)) != sizeof(int)) - return -EFAULT; - pts_set_lock(tp, is_lock); - rc = 0; + return -EFAULT; } - break; - case TIOCGPTLCK: + pts_set_lock(tp, is_lock); + rc = 0; + } + break; + case TIOCGPTLCK: + { + int is_lock = pts_is_locked(tp); + if (lwp_put_to_user(arg, &is_lock, sizeof(int)) != sizeof(int)) { - int is_lock = pts_is_locked(tp); - if (lwp_put_to_user(arg, &is_lock, sizeof(int)) != sizeof(int)) - return -EFAULT; - rc = 0; + return -EFAULT; } - break; - case TIOCGPKT: + rc = 0; + } + break; + case TIOCGPKT: + { + int pktmode = pts_get_pktmode(tp); + if (lwp_put_to_user(arg, &pktmode, sizeof(int)) != sizeof(int)) { - int pktmode = pts_get_pktmode(tp); - if (lwp_put_to_user(arg, &pktmode, sizeof(int)) != sizeof(int)) - return -EFAULT; - rc = 0; + return -EFAULT; } + rc = 0; + } + break; + default: + rc = ptm_ioctl_forward(file, tp, cmd_normal, arg); break; - default: - rc = bsd_ptsdev_methods.fo_ioctl( - tp, cmd_normal, arg, 0, FFLAGS(file->flags), rt_thread_self()); - break; } } else diff --git a/components/lwp/utest/Kconfig b/components/lwp/utest/Kconfig index 2901f8f86a4d..7bdcfefbea41 100644 --- a/components/lwp/utest/Kconfig +++ b/components/lwp/utest/Kconfig @@ -6,11 +6,11 @@ config RT_UTEST_LWP default n config RT_UTEST_LWP_TTY_PTMX - bool "Enable Utest for tty_ptmx buffer overflow regression (V-004)" + bool "Enable tty_ptmx regression tests" depends on RT_USING_SMART default n help - Regression guard for the snprintf buffer bounds fix in - components/lwp/terminal/tty_ptmx.c. + Regression guards for tty_ptmx buffer bounds and ioctl argument + handling. endmenu diff --git a/components/lwp/utest/tty_ptmx_tc.c b/components/lwp/utest/tty_ptmx_tc.c index 74416bf5ef1e..f8dc8c955396 100644 --- a/components/lwp/utest/tty_ptmx_tc.c +++ b/components/lwp/utest/tty_ptmx_tc.c @@ -38,6 +38,7 @@ #include "utest_assert.h" +#include "../terminal/tty_internal.h" #include #include #include @@ -45,6 +46,71 @@ #define DEV_REL_PATH "/ptmx" #define CANARY 0xAB +struct tty_ptmx_forward_state +{ + int copy_from_calls; + int copy_to_calls; + int ioctl_calls; + int fail_copy_from; + int fail_copy_to; + int output_value; + int forwarded_value; + rt_size_t copy_size; + rt_ubase_t forwarded_cmd; + void *forwarded_arg; +}; + +static rt_size_t tty_ptmx_copy_from(void *dst, void *src, rt_size_t size, + void *context) +{ + struct tty_ptmx_forward_state *state = context; + + state->copy_from_calls++; + state->copy_size = size; + if (state->fail_copy_from) + { + return 0; + } + memcpy(dst, src, size); + return size; +} + +static rt_size_t tty_ptmx_copy_to(void *dst, void *src, rt_size_t size, + void *context) +{ + struct tty_ptmx_forward_state *state = context; + + state->copy_to_calls++; + state->copy_size = size; + if (state->fail_copy_to) + { + return 0; + } + memcpy(dst, src, size); + return size; +} + +static int tty_ptmx_forward_ioctl(rt_ubase_t cmd, void *arg, void *context) +{ + struct tty_ptmx_forward_state *state = context; + + state->ioctl_calls++; + state->forwarded_cmd = cmd; + state->forwarded_arg = arg; + if (arg) + { + if (cmd == TIOCMGET) + { + *(int *)arg = state->output_value; + } + else + { + state->forwarded_value = *(int *)arg; + } + } + return 0; +} + static void tty_ptmx_buffer_bounds_tc(void) { /* Simulate the allocation and snprintf call from lwp_ptmx_init(). */ @@ -89,6 +155,87 @@ static void tty_ptmx_buffer_bounds_tc(void) } } +static void tty_ptmx_ioctl_arg_type_tc(void) +{ + uassert_int_equal(lwp_ptmx_ioctl_arg_type(TIOCSPGRP), LWP_PTMX_IOCTL_INT_IN); + uassert_int_equal(lwp_ptmx_ioctl_arg_type(TIOCMGET), LWP_PTMX_IOCTL_INT_OUT); + uassert_int_equal(lwp_ptmx_ioctl_arg_type(TIOCSTI), LWP_PTMX_IOCTL_CHAR_IN); + uassert_int_equal(lwp_ptmx_ioctl_arg_type(TIOCEXCL), LWP_PTMX_IOCTL_NONE); + uassert_int_equal(lwp_ptmx_ioctl_arg_type(0xffffffffU), LWP_PTMX_IOCTL_UNSUPPORTED); +} + +static void tty_ptmx_ioctl_forward_tc(void) +{ + struct tty_ptmx_forward_state state; + int value; + int rc; + + memset(&state, 0, sizeof(state)); + value = 73; + rc = lwp_ptmx_ioctl_forward(TIOCSPGRP, &value, tty_ptmx_copy_from, + tty_ptmx_copy_to, tty_ptmx_forward_ioctl, &state); + uassert_int_equal(rc, 0); + uassert_int_equal(state.copy_from_calls, 1); + uassert_int_equal(state.copy_to_calls, 0); + uassert_int_equal(state.ioctl_calls, 1); + uassert_int_equal(state.copy_size, sizeof(value)); + uassert_int_equal(state.forwarded_cmd, TIOCSPGRP); + uassert_int_equal(state.forwarded_value, value); + + memset(&state, 0, sizeof(state)); + state.output_value = 41; + value = 0; + rc = lwp_ptmx_ioctl_forward(TIOCMGET, &value, tty_ptmx_copy_from, + tty_ptmx_copy_to, tty_ptmx_forward_ioctl, &state); + uassert_int_equal(rc, 0); + uassert_int_equal(state.copy_from_calls, 0); + uassert_int_equal(state.copy_to_calls, 1); + uassert_int_equal(state.ioctl_calls, 1); + uassert_int_equal(value, state.output_value); + + memset(&state, 0, sizeof(state)); + value = 1; + rc = lwp_ptmx_ioctl_forward(FIONBIO, &value, tty_ptmx_copy_from, + tty_ptmx_copy_to, tty_ptmx_forward_ioctl, &state); + uassert_int_equal(rc, 0); + uassert_int_equal(state.copy_from_calls, 1); + uassert_int_equal(state.forwarded_value, value); + + memset(&state, 0, sizeof(state)); + rc = lwp_ptmx_ioctl_forward(TIOCEXCL, RT_NULL, tty_ptmx_copy_from, + tty_ptmx_copy_to, tty_ptmx_forward_ioctl, &state); + uassert_int_equal(rc, 0); + uassert_int_equal(state.copy_from_calls, 0); + uassert_int_equal(state.copy_to_calls, 0); + uassert_int_equal(state.ioctl_calls, 1); + uassert_null(state.forwarded_arg); + + memset(&state, 0, sizeof(state)); + state.fail_copy_from = 1; + value = 73; + rc = lwp_ptmx_ioctl_forward(TIOCSPGRP, &value, tty_ptmx_copy_from, + tty_ptmx_copy_to, tty_ptmx_forward_ioctl, &state); + uassert_int_equal(rc, -EFAULT); + uassert_int_equal(state.ioctl_calls, 0); + + memset(&state, 0, sizeof(state)); + state.fail_copy_to = 1; + state.output_value = 41; + rc = lwp_ptmx_ioctl_forward(TIOCMGET, &value, tty_ptmx_copy_from, + tty_ptmx_copy_to, tty_ptmx_forward_ioctl, &state); + uassert_int_equal(rc, -EFAULT); + uassert_int_equal(state.copy_to_calls, 1); + uassert_int_equal(state.ioctl_calls, 1); + + memset(&state, 0, sizeof(state)); + rc = lwp_ptmx_ioctl_forward(0xffffffffU, &value, tty_ptmx_copy_from, + tty_ptmx_copy_to, tty_ptmx_forward_ioctl, &state); + uassert_int_equal(rc, -ENOTTY); + uassert_int_equal(state.copy_from_calls, 0); + uassert_int_equal(state.copy_to_calls, 0); + uassert_int_equal(state.ioctl_calls, 0); +} + static rt_err_t utest_tc_init(void) { return RT_EOK; @@ -102,5 +249,7 @@ static rt_err_t utest_tc_cleanup(void) static void testcase(void) { UTEST_UNIT_RUN(tty_ptmx_buffer_bounds_tc); + UTEST_UNIT_RUN(tty_ptmx_ioctl_arg_type_tc); + UTEST_UNIT_RUN(tty_ptmx_ioctl_forward_tc); } UTEST_TC_EXPORT(testcase, "testcases.lwp.tty_ptmx.buffer_bounds", utest_tc_init, utest_tc_cleanup, 10);