1 /* $NetBSD: prop_kern.c,v 1.13 2009/10/11 12:13:45 bad Exp $ */
4 * Copyright (c) 2006, 2009 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/types.h>
34 #include <libprop/proplib.h>
36 #if !defined(_KERNEL) && !defined(_STANDALONE)
42 #include <sys/ioctl.h>
45 _prop_object_externalize_to_pref(prop_object_t obj, struct plistref *pref, char **bufp)
49 switch (prop_object_type(obj)) {
50 case PROP_TYPE_DICTIONARY:
51 buf = prop_dictionary_externalize(obj);
54 buf = prop_array_externalize(obj);
60 /* Assume we ran out of memory. */
63 pref->pref_plist = buf;
64 pref->pref_len = strlen(buf) + 1;
72 * prop_array_externalize_to_pref --
73 * Externalize an array into a plistref for sending to the kernel.
76 prop_array_externalize_to_pref(prop_array_t array, struct plistref *prefp)
81 rv = _prop_object_externalize_to_pref(array, prefp, &buf);
83 errno = rv; /* pass up error value in errno */
88 * prop_dictionary_externalize_to_pref --
89 * Externalize an dictionary into a plistref for sending to the kernel.
92 prop_dictionary_externalize_to_pref(prop_dictionary_t dict, struct plistref *prefp)
97 rv = _prop_object_externalize_to_pref(dict, prefp, &buf);
99 errno = rv; /* pass up error value in errno */
104 _prop_object_send_ioctl(prop_object_t obj, int fd, unsigned long cmd)
106 struct plistref pref;
110 error = _prop_object_externalize_to_pref(obj, &pref, &buf);
114 if (ioctl(fd, cmd, &pref) == -1)
125 * prop_array_send_ioctl --
126 * Send an array to the kernel using the specified ioctl.
129 prop_array_send_ioctl(prop_array_t array, int fd, unsigned long cmd)
132 return (_prop_object_send_ioctl(array, fd, cmd));
136 * prop_dictionary_send_ioctl --
137 * Send a dictionary to the kernel using the specified ioctl.
140 prop_dictionary_send_ioctl(prop_dictionary_t dict, int fd, unsigned long cmd)
143 return (_prop_object_send_ioctl(dict, fd, cmd));
147 _prop_object_internalize_from_pref(const struct plistref *pref, prop_type_t type,
150 prop_object_t obj = NULL;
154 if (pref->pref_len == 0) {
156 * This should never happen; we should always get the XML
157 * for an empty dictionary if it's really empty.
162 buf = pref->pref_plist;
163 buf[pref->pref_len - 1] = '\0'; /* extra insurance */
165 case PROP_TYPE_DICTIONARY:
166 obj = prop_dictionary_internalize(buf);
168 case PROP_TYPE_ARRAY:
169 obj = prop_array_internalize(buf);
174 (void) munmap(buf, pref->pref_len);
175 if (obj == NULL && error == 0)
186 * prop_array_recv_ioctl --
187 * Receive an array from the kernel using the specified ioctl.
190 prop_array_recv_ioctl(int fd, unsigned long cmd, prop_array_t *arrayp)
192 struct plistref pref;
194 if (ioctl(fd, cmd, &pref) == -1)
197 return (_prop_object_internalize_from_pref(&pref, PROP_TYPE_ARRAY,
198 (prop_object_t *)arrayp));
202 * prop_dictionary_recv_ioctl --
203 * Receive a dictionary from the kernel using the specified ioctl.
206 prop_dictionary_recv_ioctl(int fd, unsigned long cmd, prop_dictionary_t *dictp)
208 struct plistref pref;
210 if (ioctl(fd, cmd, &pref) == -1)
213 return (_prop_object_internalize_from_pref(&pref, PROP_TYPE_DICTIONARY,
214 (prop_object_t *)dictp));
218 * prop_dictionary_sendrecv_ioctl --
219 * Combination send/receive a dictionary to/from the kernel using
220 * the specified ioctl.
223 prop_dictionary_sendrecv_ioctl(prop_dictionary_t dict, int fd,
224 unsigned long cmd, prop_dictionary_t *dictp)
226 struct plistref pref;
230 error = _prop_object_externalize_to_pref(dict, &pref, &buf);
234 if (ioctl(fd, cmd, &pref) == -1)
244 return (_prop_object_internalize_from_pref(&pref, PROP_TYPE_DICTIONARY,
245 (prop_object_t *)dictp));
247 #endif /* !_KERNEL && !_STANDALONE */
250 #include <sys/param.h>
251 #include <sys/mman.h>
252 #include <sys/errno.h>
253 #include <sys/malloc.h>
254 #include <sys/systm.h>
255 #include <sys/proc.h>
256 #include <sys/resource.h>
257 #include <sys/objcache.h>
258 #include <sys/ioccom.h>
260 #include <vm/vm_extern.h>
261 #include <vm/vm_param.h>
263 #include "prop_object_impl.h"
265 /* Arbitrary limit ioctl input to 64KB */
266 unsigned int prop_object_copyin_limit = 65536;
269 _prop_object_copyin(const struct plistref *pref, const prop_type_t type,
272 prop_object_t obj = NULL;
277 * Allocate an extra byte so we can guarantee NUL-termination.
279 * Allow malloc to fail in case pmap would be exhausted.
281 buf = kmalloc(pref->pref_len + 1, M_TEMP, M_WAITOK);
284 error = copyin(pref->pref_plist, buf, pref->pref_len);
289 buf[pref->pref_len] = '\0';
292 case PROP_TYPE_ARRAY:
293 obj = prop_array_internalize(buf);
295 case PROP_TYPE_DICTIONARY:
296 obj = prop_dictionary_internalize(buf);
314 _prop_object_copyin_ioctl(const struct plistref *pref, const prop_type_t type,
315 const u_long cmd, prop_object_t *objp)
317 if ((cmd & IOC_IN) == 0)
320 return _prop_object_copyin(pref, type, objp);
324 * prop_array_copyin --
325 * Copy in an array passed as a syscall arg.
328 prop_array_copyin(const struct plistref *pref, prop_array_t *arrayp)
330 return (_prop_object_copyin(pref, PROP_TYPE_ARRAY,
331 (prop_object_t *)arrayp));
335 * prop_dictionary_copyin --
336 * Copy in a dictionary passed as a syscall arg.
339 prop_dictionary_copyin(const struct plistref *pref, prop_dictionary_t *dictp)
341 return (_prop_object_copyin(pref, PROP_TYPE_DICTIONARY,
342 (prop_object_t *)dictp));
347 * prop_array_copyin_ioctl --
348 * Copy in an array send with an ioctl.
351 prop_array_copyin_ioctl(const struct plistref *pref, const u_long cmd,
352 prop_array_t *arrayp)
354 return (_prop_object_copyin_ioctl(pref, PROP_TYPE_ARRAY,
355 cmd, (prop_object_t *)arrayp));
359 * prop_dictionary_copyin_ioctl --
360 * Copy in a dictionary sent with an ioctl.
363 prop_dictionary_copyin_ioctl(const struct plistref *pref, const u_long cmd,
364 prop_dictionary_t *dictp)
366 return (_prop_object_copyin_ioctl(pref, PROP_TYPE_DICTIONARY,
367 cmd, (prop_object_t *)dictp));
371 _prop_object_copyout_ioctl(struct plistref *pref, const u_long cmd,
374 struct proc *p = curproc;
380 if ((cmd & IOC_OUT) == 0)
383 switch (prop_object_type(obj)) {
384 case PROP_TYPE_ARRAY:
385 buf = prop_array_externalize(obj);
387 case PROP_TYPE_DICTIONARY:
388 buf = prop_dictionary_externalize(obj);
396 len = strlen(buf) + 1;
397 rlen = round_page(len);
400 * See sys_mmap() in sys/uvm/uvm_mmap.c.
401 * Let's act as if we were calling mmap(0, ...)
404 uaddr = p->p_emul->e_vm_default_addr(p,
405 (vaddr_t)p->p_vmspace->vm_daddr, rlen);
407 uaddr = round_page((vm_offset_t)p->p_vmspace->vm_daddr + maxdsiz);
409 error = vm_mmap(&p->p_vmspace->vm_map,
411 VM_PROT_READ|VM_PROT_WRITE,
412 VM_PROT_READ|VM_PROT_WRITE,
413 MAP_PRIVATE|MAP_ANON,
416 error = copyout(buf, (char *)uaddr, len);
418 pref->pref_plist = (char *)uaddr;
419 pref->pref_len = len;
429 * prop_array_copyout_ioctl --
430 * Copy out an array being received with an ioctl.
433 prop_array_copyout_ioctl(struct plistref *pref, const u_long cmd,
436 return (_prop_object_copyout_ioctl(pref, cmd, array));
440 * prop_dictionary_copyout_ioctl --
441 * Copy out a dictionary being received with an ioctl.
444 prop_dictionary_copyout_ioctl(struct plistref *pref, const u_long cmd,
445 prop_dictionary_t dict)
447 return (_prop_object_copyout_ioctl(pref, cmd, dict));