The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/clockctl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: clockctl.c,v 1.39 2022/03/28 12:33:20 riastradh Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2001 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Emmanuel Dreyfus.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __KERNEL_RCSID(0, "$NetBSD: clockctl.c,v 1.39 2022/03/28 12:33:20 riastradh Exp $");
   35 
   36 #ifdef _KERNEL_OPT
   37 #include "opt_ntp.h"
   38 #include "opt_compat_netbsd.h"
   39 #endif
   40 
   41 #include <sys/param.h>
   42 #include <sys/systm.h>
   43 #include <sys/proc.h>
   44 #include <sys/errno.h>
   45 #include <sys/ioctl.h>
   46 #include <sys/device.h>
   47 #include <sys/time.h>
   48 #include <sys/conf.h>
   49 #include <sys/timex.h>
   50 #include <sys/kauth.h>
   51 #include <sys/module.h>
   52 #include <sys/mutex.h>
   53 #include <sys/compat_stub.h>
   54 
   55 #include <sys/clockctl.h>
   56 #include <compat/sys/clockctl.h>
   57 #include <compat/sys/time_types.h>
   58 
   59 
   60 kmutex_t clockctl_mtx;
   61 int clockctl_refcnt;
   62 
   63 #include "ioconf.h"
   64 
   65 dev_type_ioctl(clockctlioctl);
   66 
   67 const struct cdevsw clockctl_cdevsw = {
   68         .d_open = clockctlopen,
   69         .d_close = clockctlclose,
   70         .d_read = noread,
   71         .d_write = nowrite,
   72         .d_ioctl = clockctlioctl,
   73         .d_stop = nostop,
   74         .d_tty = notty,
   75         .d_poll = nopoll,
   76         .d_mmap = nommap,
   77         .d_kqfilter = nokqfilter,
   78         .d_discard = nodiscard,
   79         .d_flag = D_OTHER,
   80 };
   81 
   82 static kauth_listener_t clockctl_listener;
   83 
   84 static int
   85 clockctl_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
   86     void *arg0, void *arg1, void *arg2, void *arg3)
   87 {
   88         int result;
   89         enum kauth_system_req req;
   90         bool device_context;
   91 
   92         result = KAUTH_RESULT_DEFER;
   93         req = (enum kauth_system_req)(uintptr_t)arg0;
   94 
   95         if ((action != KAUTH_SYSTEM_TIME) ||
   96             (req != KAUTH_REQ_SYSTEM_TIME_SYSTEM))
   97                 return result;
   98 
   99         device_context = arg3 != NULL;
  100 
  101         /* Device is controlled by permissions, so allow. */
  102         if (device_context)
  103                 result = KAUTH_RESULT_ALLOW;
  104 
  105         return result;
  106 }
  107 
  108 /*ARGSUSED*/
  109 void
  110 clockctlattach(int num)
  111 {
  112 
  113 /*
  114  * Don't initialize the listener here - it will get handled as part
  115  * of module initialization.
  116  */
  117 #if 0
  118         clockctl_listener = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
  119             clockctl_listener_cb, NULL);
  120 #endif
  121 }
  122 
  123 /*
  124  * Maintain a refcount for each open/close, so we know when it is
  125  * safe to call devsw_detach()
  126  */
  127 int
  128 clockctlopen(dev_t dev, int flag, int mode, struct lwp *l)
  129 {
  130 
  131         mutex_enter(&clockctl_mtx);
  132         clockctl_refcnt++;
  133         mutex_exit(&clockctl_mtx);
  134 
  135         return 0;
  136 }
  137 
  138 int
  139 clockctlclose(dev_t dev, int flag, int mode, struct lwp *l)
  140 {
  141 
  142         mutex_enter(&clockctl_mtx);
  143         clockctl_refcnt--;
  144         mutex_exit(&clockctl_mtx);
  145 
  146         return 0;
  147 }
  148 
  149 MODULE(MODULE_CLASS_DRIVER, clockctl, NULL);
  150 
  151 int
  152 clockctl_modcmd(modcmd_t cmd, void *data)
  153 {
  154         int error;
  155 #ifdef _MODULE
  156         int bmajor, cmajor;
  157 #endif
  158 
  159         error = 0;
  160 
  161         switch (cmd) {
  162         case MODULE_CMD_INIT:
  163                 mutex_init(&clockctl_mtx, MUTEX_DEFAULT, IPL_NONE);
  164 
  165                 clockctl_listener = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
  166                     clockctl_listener_cb, NULL);
  167 
  168 #ifdef _MODULE
  169                 bmajor = cmajor = -1;
  170                 error = devsw_attach("clockctl", NULL, &bmajor,
  171                     &clockctl_cdevsw, &cmajor);
  172                 if (error != 0)
  173                         kauth_unlisten_scope(clockctl_listener);
  174 #endif
  175 
  176                 break;
  177 
  178         case MODULE_CMD_FINI:
  179                 mutex_enter(&clockctl_mtx);
  180                 if (clockctl_refcnt != 0) {
  181                         mutex_exit(&clockctl_mtx);
  182                         return EBUSY;
  183                 }
  184 #ifdef _MODULE
  185                 devsw_detach(NULL, &clockctl_cdevsw);
  186 #endif
  187                 mutex_exit(&clockctl_mtx);
  188 
  189                 kauth_unlisten_scope(clockctl_listener);
  190                 mutex_destroy(&clockctl_mtx);
  191                 break;
  192 
  193         default:
  194                 error = ENOTTY;
  195                 break;
  196         }
  197 
  198         return error;
  199 }
  200 
  201 int
  202 clockctlioctl(
  203     dev_t dev,
  204     u_long cmd,
  205     void *data,
  206     int flags,
  207     struct lwp *l)
  208 {
  209         int error = 0;
  210 
  211         switch (cmd) {
  212         case CLOCKCTL_SETTIMEOFDAY: {
  213                 struct clockctl_settimeofday *args = data;
  214 
  215                 error = settimeofday1(args->tv, true, args->tzp, l, false);
  216                 break;
  217         }
  218         case CLOCKCTL_ADJTIME: {
  219                 struct timeval atv, oldatv;
  220                 struct clockctl_adjtime *args = data;
  221 
  222                 if (args->delta) {
  223                         error = copyin(args->delta, &atv, sizeof(atv));
  224                         if (error)
  225                                 return (error);
  226                 }
  227                 adjtime1(args->delta ? &atv : NULL,
  228                     args->olddelta ? &oldatv : NULL, l->l_proc);
  229                 if (args->olddelta)
  230                         error = copyout(&oldatv, args->olddelta,
  231                             sizeof(oldatv));
  232                 break;
  233         }
  234         case CLOCKCTL_CLOCK_SETTIME: {
  235                 struct clockctl_clock_settime *args = data;
  236                 struct timespec ts;
  237 
  238                 error = copyin(args->tp, &ts, sizeof ts);
  239                 if (error)
  240                         return (error);
  241                 error = clock_settime1(l->l_proc, args->clock_id, &ts, false);
  242                 break;
  243         }
  244         case CLOCKCTL_NTP_ADJTIME: {
  245                 struct clockctl_ntp_adjtime *args = data;
  246                 struct timex ntv;
  247 
  248                 if (vec_ntp_timestatus == NULL) {
  249                         error = ENOTTY;
  250                         break;
  251                 }
  252                 error = copyin(args->tp, &ntv, sizeof(ntv));
  253                 if (error)
  254                         return (error);
  255 
  256                 (*vec_ntp_adjtime1)(&ntv);
  257 
  258                 error = copyout(&ntv, args->tp, sizeof(ntv));
  259                 if (error == 0)
  260                         args->retval = (*vec_ntp_timestatus)();
  261                 break;
  262         }
  263         default:
  264                 MODULE_HOOK_CALL(clockctl_ioctl_50_hook,
  265                     (dev, cmd, data, flags, l), enosys(), error);
  266                 if (error == ENOSYS)
  267                         error = ENOTTY;
  268         }
  269 
  270         return (error);
  271 }

Cache object: 89b93951cae4348eac8e2c57ed91207c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.