2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /* Copyright 2013 OmniTI Computer Consulting, Inc. All rights reserved. */
23
24 /*
25 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
27 */
28
29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
30 /* All Rights Reserved */
31
32 #include <sys/types.h>
33 #include <sys/inttypes.h>
34 #include <sys/param.h>
35 #include <sys/sysmacros.h>
36 #include <sys/systm.h>
37 #include <sys/signal.h>
38 #include <sys/user.h>
39 #include <sys/errno.h>
40 #include <sys/var.h>
41 #include <sys/proc.h>
42 #include <sys/tuneable.h>
43 #include <sys/debug.h>
44 #include <sys/cmn_err.h>
45 #include <sys/cred.h>
46 #include <sys/vnode.h>
47 #include <sys/vfs.h>
48 #include <sys/vm.h>
49 #include <sys/file.h>
50 #include <sys/mman.h>
51 #include <sys/vmparam.h>
52 #include <sys/fcntl.h>
53 #include <sys/lwpchan_impl.h>
54 #include <sys/nbmlock.h>
55
56 #include <vm/hat.h>
57 #include <vm/as.h>
58 #include <vm/seg.h>
59 #include <vm/seg_dev.h>
60 #include <vm/seg_vn.h>
61
62 int use_brk_lpg = 1;
63 int use_stk_lpg = 1;
64
65 static int brk_lpg(caddr_t nva);
66 static int grow_lpg(caddr_t sp);
67
68 int
69 brk(caddr_t nva)
70 {
71 int error;
72 proc_t *p = curproc;
73
74 /*
525
526 if (flags & MAP_FIXED) {
527 (void) as_unmap(as, *addrp, len);
528 return (0);
529 } else if (basep != NULL && ((flags & MAP_ALIGN) == 0) &&
530 !as_gap(as, len, &basep, &lenp, 0, *addrp)) {
531 /* User supplied address was available */
532 *addrp = basep;
533 } else {
534 /*
535 * No user supplied address or the address supplied was not
536 * available.
537 */
538 map_addr(addrp, len, off, vacalign, flags);
539 }
540 if (*addrp == NULL)
541 return (ENOMEM);
542 return (0);
543 }
544
545
546 /*
547 * Used for MAP_ANON - fast way to get anonymous pages
548 */
549 static int
550 zmap(struct as *as, caddr_t *addrp, size_t len, uint_t uprot, int flags,
551 offset_t pos)
552 {
553 struct segvn_crargs vn_a;
554 int error;
555
556 if (((PROT_ALL & uprot) != uprot))
557 return (EACCES);
558
559 if ((flags & MAP_FIXED) != 0) {
560 caddr_t userlimit;
561
562 /*
563 * Use the user address. First verify that
564 * the address to be used is page aligned.
565 * Then make some simple bounds checks.
566 */
567 if (((uintptr_t)*addrp & PAGEOFFSET) != 0)
568 return (EINVAL);
569
570 userlimit = flags & _MAP_LOW32 ?
571 (caddr_t)USERLIMIT32 : as->a_userlimit;
572 switch (valid_usr_range(*addrp, len, uprot, as, userlimit)) {
573 case RANGE_OKAY:
574 break;
575 case RANGE_BADPROT:
576 return (ENOTSUP);
577 case RANGE_BADADDR:
578 default:
579 return (ENOMEM);
580 }
581 }
582 /*
583 * No need to worry about vac alignment for anonymous
584 * pages since this is a "clone" object that doesn't
585 * yet exist.
586 */
587 error = choose_addr(as, addrp, len, pos, ADDR_NOVACALIGN, flags);
588 if (error != 0) {
589 return (error);
590 }
591
592 /*
720 * on the vnode for the current user, maxprot probably
721 * should disallow PROT_EXEC also? This is different
722 * from the write access as this would be a per vnode
723 * test as opposed to a per fd test for writability.
724 */
725
726 /*
727 * Verify that the specified protections are not greater than
728 * the maximum allowable protections. Also test to make sure
729 * that the file descriptor does allows for read access since
730 * "write only" mappings are hard to do since normally we do
731 * the read from the file before the page can be written.
732 */
733 if (((maxprot & uprot) != uprot) || (fp->f_flag & FREAD) == 0)
734 return (EACCES);
735
736 /*
737 * If the user specified an address, do some simple checks here
738 */
739 if ((flags & MAP_FIXED) != 0) {
740 caddr_t userlimit;
741
742 /*
743 * Use the user address. First verify that
744 * the address to be used is page aligned.
745 * Then make some simple bounds checks.
746 */
747 if (((uintptr_t)*addrp & PAGEOFFSET) != 0)
748 return (EINVAL);
749
750 userlimit = flags & _MAP_LOW32 ?
751 (caddr_t)USERLIMIT32 : as->a_userlimit;
752 switch (valid_usr_range(*addrp, len, uprot, as, userlimit)) {
753 case RANGE_OKAY:
754 break;
755 case RANGE_BADPROT:
756 return (ENOTSUP);
757 case RANGE_BADADDR:
758 default:
759 return (ENOMEM);
760 }
761 }
762
763 if ((prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) &&
764 nbl_need_check(vp)) {
765 int svmand;
766 nbl_op_t nop;
767
768 nbl_start_crit(vp, RW_READER);
769 in_crit = 1;
770 error = nbl_svmand(vp, fp->f_cred, &svmand);
771 if (error != 0)
772 goto done;
|
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2013 OmniTI Computer Consulting, Inc. All rights reserved.
24 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
25 */
26
27 /*
28 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
29 * Use is subject to license terms.
30 */
31
32 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
33 /* All Rights Reserved */
34
35 #include <sys/types.h>
36 #include <sys/inttypes.h>
37 #include <sys/param.h>
38 #include <sys/sysmacros.h>
39 #include <sys/systm.h>
40 #include <sys/signal.h>
41 #include <sys/user.h>
42 #include <sys/errno.h>
43 #include <sys/var.h>
44 #include <sys/proc.h>
45 #include <sys/tuneable.h>
46 #include <sys/debug.h>
47 #include <sys/cmn_err.h>
48 #include <sys/cred.h>
49 #include <sys/vnode.h>
50 #include <sys/vfs.h>
51 #include <sys/vm.h>
52 #include <sys/file.h>
53 #include <sys/mman.h>
54 #include <sys/vmparam.h>
55 #include <sys/fcntl.h>
56 #include <sys/lwpchan_impl.h>
57 #include <sys/nbmlock.h>
58 #include <sys/brand.h>
59
60 #include <vm/hat.h>
61 #include <vm/as.h>
62 #include <vm/seg.h>
63 #include <vm/seg_dev.h>
64 #include <vm/seg_vn.h>
65
66 int use_brk_lpg = 1;
67 int use_stk_lpg = 1;
68
69 static int brk_lpg(caddr_t nva);
70 static int grow_lpg(caddr_t sp);
71
72 int
73 brk(caddr_t nva)
74 {
75 int error;
76 proc_t *p = curproc;
77
78 /*
529
530 if (flags & MAP_FIXED) {
531 (void) as_unmap(as, *addrp, len);
532 return (0);
533 } else if (basep != NULL && ((flags & MAP_ALIGN) == 0) &&
534 !as_gap(as, len, &basep, &lenp, 0, *addrp)) {
535 /* User supplied address was available */
536 *addrp = basep;
537 } else {
538 /*
539 * No user supplied address or the address supplied was not
540 * available.
541 */
542 map_addr(addrp, len, off, vacalign, flags);
543 }
544 if (*addrp == NULL)
545 return (ENOMEM);
546 return (0);
547 }
548
549 caddr_t
550 map_userlimit(proc_t *pp, struct as *as, int flags)
551 {
552 if (flags & _MAP_LOW32) {
553 if (PROC_IS_BRANDED(pp) && BROP(pp)->b_map32limit != NULL) {
554 return ((caddr_t)(uintptr_t)BROP(pp)->b_map32limit(pp));
555 } else {
556 return ((caddr_t)_userlimit32);
557 }
558 }
559
560 return (as->a_userlimit);
561 }
562
563
564 /*
565 * Used for MAP_ANON - fast way to get anonymous pages
566 */
567 static int
568 zmap(struct as *as, caddr_t *addrp, size_t len, uint_t uprot, int flags,
569 offset_t pos)
570 {
571 struct segvn_crargs vn_a;
572 int error;
573
574 if (((PROT_ALL & uprot) != uprot))
575 return (EACCES);
576
577 if ((flags & MAP_FIXED) != 0) {
578 /*
579 * Use the user address. First verify that
580 * the address to be used is page aligned.
581 * Then make some simple bounds checks.
582 */
583 if (((uintptr_t)*addrp & PAGEOFFSET) != 0)
584 return (EINVAL);
585
586 switch (valid_usr_range(*addrp, len, uprot, as,
587 map_userlimit(as->a_proc, as, flags))) {
588 case RANGE_OKAY:
589 break;
590 case RANGE_BADPROT:
591 return (ENOTSUP);
592 case RANGE_BADADDR:
593 default:
594 return (ENOMEM);
595 }
596 }
597 /*
598 * No need to worry about vac alignment for anonymous
599 * pages since this is a "clone" object that doesn't
600 * yet exist.
601 */
602 error = choose_addr(as, addrp, len, pos, ADDR_NOVACALIGN, flags);
603 if (error != 0) {
604 return (error);
605 }
606
607 /*
735 * on the vnode for the current user, maxprot probably
736 * should disallow PROT_EXEC also? This is different
737 * from the write access as this would be a per vnode
738 * test as opposed to a per fd test for writability.
739 */
740
741 /*
742 * Verify that the specified protections are not greater than
743 * the maximum allowable protections. Also test to make sure
744 * that the file descriptor does allows for read access since
745 * "write only" mappings are hard to do since normally we do
746 * the read from the file before the page can be written.
747 */
748 if (((maxprot & uprot) != uprot) || (fp->f_flag & FREAD) == 0)
749 return (EACCES);
750
751 /*
752 * If the user specified an address, do some simple checks here
753 */
754 if ((flags & MAP_FIXED) != 0) {
755 /*
756 * Use the user address. First verify that
757 * the address to be used is page aligned.
758 * Then make some simple bounds checks.
759 */
760 if (((uintptr_t)*addrp & PAGEOFFSET) != 0)
761 return (EINVAL);
762 switch (valid_usr_range(*addrp, len, uprot, as,
763 map_userlimit(curproc, as, flags))) {
764 case RANGE_OKAY:
765 break;
766 case RANGE_BADPROT:
767 return (ENOTSUP);
768 case RANGE_BADADDR:
769 default:
770 return (ENOMEM);
771 }
772 }
773
774 if ((prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) &&
775 nbl_need_check(vp)) {
776 int svmand;
777 nbl_op_t nop;
778
779 nbl_start_crit(vp, RW_READER);
780 in_crit = 1;
781 error = nbl_svmand(vp, fp->f_cred, &svmand);
782 if (error != 0)
783 goto done;
|