1 /* $NetBSD: prop_kern.c,v 1.15 2011/01/19 20:34:23 bouyer 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 */
86 __strong_reference(prop_array_externalize_to_pref, prop_array_send_syscall)
89 * prop_dictionary_externalize_to_pref --
90 * Externalize an dictionary into a plistref for sending to the kernel.
93 prop_dictionary_externalize_to_pref(prop_dictionary_t dict, struct plistref *prefp)
98 rv = _prop_object_externalize_to_pref(dict, prefp, &buf);
100 errno = rv; /* pass up error value in errno */
103 __strong_reference(prop_dictionary_externalize_to_pref,
104 prop_dictionary_send_syscall)
107 _prop_object_send_ioctl(prop_object_t obj, int fd, unsigned long cmd)
109 struct plistref pref;
113 error = _prop_object_externalize_to_pref(obj, &pref, &buf);
117 if (ioctl(fd, cmd, &pref) == -1)
128 * prop_array_send_ioctl --
129 * Send an array to the kernel using the specified ioctl.
132 prop_array_send_ioctl(prop_array_t array, int fd, unsigned long cmd)
135 return (_prop_object_send_ioctl(array, fd, cmd));
139 * prop_dictionary_send_ioctl --
140 * Send a dictionary to the kernel using the specified ioctl.
143 prop_dictionary_send_ioctl(prop_dictionary_t dict, int fd, unsigned long cmd)
146 return (_prop_object_send_ioctl(dict, fd, cmd));
150 _prop_object_internalize_from_pref(const struct plistref *pref, prop_type_t type,
153 prop_object_t obj = NULL;
157 if (pref->pref_len == 0) {
159 * This should never happen; we should always get the XML
160 * for an empty dictionary if it's really empty.
165 buf = pref->pref_plist;
166 buf[pref->pref_len - 1] = '\0'; /* extra insurance */
168 case PROP_TYPE_DICTIONARY:
169 obj = prop_dictionary_internalize(buf);
171 case PROP_TYPE_ARRAY:
172 obj = prop_array_internalize(buf);
177 (void) munmap(buf, pref->pref_len);
178 if (obj == NULL && error == 0)
189 * prop_array_recv_ioctl --
190 * Receive an array from the kernel using the specified ioctl.
193 prop_array_recv_ioctl(int fd, unsigned long cmd, prop_array_t *arrayp)
195 struct plistref pref;
197 if (ioctl(fd, cmd, &pref) == -1)
200 return (_prop_object_internalize_from_pref(&pref, PROP_TYPE_ARRAY,
201 (prop_object_t *)arrayp));
205 * prop_dictionary_recv_ioctl --
206 * Receive a dictionary from the kernel using the specified ioctl.
209 prop_dictionary_recv_ioctl(int fd, unsigned long cmd, prop_dictionary_t *dictp)
211 struct plistref pref;
213 if (ioctl(fd, cmd, &pref) == -1)
216 return (_prop_object_internalize_from_pref(&pref, PROP_TYPE_DICTIONARY,
217 (prop_object_t *)dictp));
221 * prop_array_recv_syscall --
222 * Receive an array from the kernel as pref.
223 * Pref's buf is freed on exit
226 prop_array_recv_syscall(const struct plistref *pref, prop_array_t *arrayp)
228 return (_prop_object_internalize_from_pref(pref, PROP_TYPE_ARRAY,
229 (prop_object_t *)arrayp));
233 * prop_dictionary_recv_syscall --
234 * Receive a dictionary from the kernel as pref.
235 * Pref's buf is freed on exit
238 prop_dictionary_recv_syscall(const struct plistref *pref,
239 prop_dictionary_t *dictp)
241 return (_prop_object_internalize_from_pref(pref, PROP_TYPE_DICTIONARY,
242 (prop_object_t *)dictp));
246 * prop_dictionary_sendrecv_ioctl --
247 * Combination send/receive a dictionary to/from the kernel using
248 * the specified ioctl.
251 prop_dictionary_sendrecv_ioctl(prop_dictionary_t dict, int fd,
252 unsigned long cmd, prop_dictionary_t *dictp)
254 struct plistref pref;
258 error = _prop_object_externalize_to_pref(dict, &pref, &buf);
262 if (ioctl(fd, cmd, &pref) == -1)
272 return (_prop_object_internalize_from_pref(&pref, PROP_TYPE_DICTIONARY,
273 (prop_object_t *)dictp));
275 #endif /* !_KERNEL && !_STANDALONE */
278 #include <sys/param.h>
279 #include <sys/mman.h>
280 #include <sys/errno.h>
281 #include <sys/malloc.h>
282 #include <sys/systm.h>
283 #include <sys/proc.h>
284 #include <sys/resource.h>
285 #include <sys/objcache.h>
286 #include <sys/ioccom.h>
288 #include <vm/vm_extern.h>
289 #include <vm/vm_param.h>
291 #include "prop_object_impl.h"
293 /* Arbitrary limit ioctl input to 64KB */
294 unsigned int prop_object_copyin_limit = 65536;
297 _prop_object_copyin(const struct plistref *pref, const prop_type_t type,
300 prop_object_t obj = NULL;
305 * Allocate an extra byte so we can guarantee NUL-termination.
307 * Allow malloc to fail in case pmap would be exhausted.
309 buf = kmalloc(pref->pref_len + 1, M_TEMP, M_WAITOK);
312 error = copyin(pref->pref_plist, buf, pref->pref_len);
317 buf[pref->pref_len] = '\0';
320 case PROP_TYPE_ARRAY:
321 obj = prop_array_internalize(buf);
323 case PROP_TYPE_DICTIONARY:
324 obj = prop_dictionary_internalize(buf);
342 _prop_object_copyin_ioctl(const struct plistref *pref, const prop_type_t type,
343 const u_long cmd, prop_object_t *objp)
345 if ((cmd & IOC_IN) == 0)
348 return _prop_object_copyin(pref, type, objp);
352 * prop_array_copyin --
353 * Copy in an array passed as a syscall arg.
356 prop_array_copyin(const struct plistref *pref, prop_array_t *arrayp)
358 return (_prop_object_copyin(pref, PROP_TYPE_ARRAY,
359 (prop_object_t *)arrayp));
363 * prop_dictionary_copyin --
364 * Copy in a dictionary passed as a syscall arg.
367 prop_dictionary_copyin(const struct plistref *pref, prop_dictionary_t *dictp)
369 return (_prop_object_copyin(pref, PROP_TYPE_DICTIONARY,
370 (prop_object_t *)dictp));
375 * prop_array_copyin_ioctl --
376 * Copy in an array send with an ioctl.
379 prop_array_copyin_ioctl(const struct plistref *pref, const u_long cmd,
380 prop_array_t *arrayp)
382 return (_prop_object_copyin_ioctl(pref, PROP_TYPE_ARRAY,
383 cmd, (prop_object_t *)arrayp));
387 * prop_dictionary_copyin_ioctl --
388 * Copy in a dictionary sent with an ioctl.
391 prop_dictionary_copyin_ioctl(const struct plistref *pref, const u_long cmd,
392 prop_dictionary_t *dictp)
394 return (_prop_object_copyin_ioctl(pref, PROP_TYPE_DICTIONARY,
395 cmd, (prop_object_t *)dictp));
399 _prop_object_copyout(struct plistref *pref, prop_object_t obj)
401 struct proc *p = curproc;
407 switch (prop_object_type(obj)) {
408 case PROP_TYPE_ARRAY:
409 buf = prop_array_externalize(obj);
411 case PROP_TYPE_DICTIONARY:
412 buf = prop_dictionary_externalize(obj);
420 len = strlen(buf) + 1;
421 rlen = round_page(len);
424 * See sys_mmap() in sys/uvm/uvm_mmap.c.
425 * Let's act as if we were calling mmap(0, ...)
428 uaddr = p->p_emul->e_vm_default_addr(p,
429 (vaddr_t)p->p_vmspace->vm_daddr, rlen);
431 uaddr = round_page((vm_offset_t)p->p_vmspace->vm_daddr + maxdsiz);
433 error = vm_mmap(&p->p_vmspace->vm_map,
435 VM_PROT_READ|VM_PROT_WRITE,
436 VM_PROT_READ|VM_PROT_WRITE,
437 MAP_PRIVATE|MAP_ANON,
440 error = copyout(buf, (char *)uaddr, len);
442 pref->pref_plist = (char *)uaddr;
443 pref->pref_len = len;
453 * prop_array_copyout --
454 * Copy out an array to a syscall arg.
457 prop_array_copyout(struct plistref *pref, prop_array_t array)
459 return (_prop_object_copyout(pref, array));
463 * prop_dictionary_copyout --
464 * Copy out a dictionary to a syscall arg.
467 prop_dictionary_copyout(struct plistref *pref, prop_dictionary_t dict)
469 return (_prop_object_copyout(pref, dict));
473 _prop_object_copyout_ioctl(struct plistref *pref, const u_long cmd,
476 if ((cmd & IOC_OUT) == 0)
478 return _prop_object_copyout(pref, obj);
483 * prop_array_copyout_ioctl --
484 * Copy out an array being received with an ioctl.
487 prop_array_copyout_ioctl(struct plistref *pref, const u_long cmd,
490 return (_prop_object_copyout_ioctl(pref, cmd, array));
494 * prop_dictionary_copyout_ioctl --
495 * Copy out a dictionary being received with an ioctl.
498 prop_dictionary_copyout_ioctl(struct plistref *pref, const u_long cmd,
499 prop_dictionary_t dict)
502 _prop_object_copyout_ioctl(pref, cmd, dict));