| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 /* | 7 /* |
| 8 * NaCl service run-time, non-platform specific system call helper routines. | 8 * NaCl service run-time, non-platform specific system call helper routines. |
| 9 */ | 9 */ |
| 10 #include <sys/types.h> | 10 #include <sys/types.h> |
| (...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 struct NaClDesc *ndp; | 718 struct NaClDesc *ndp; |
| 719 | 719 |
| 720 NaClLog(3, | 720 NaClLog(3, |
| 721 ("Entered NaClCommonSysGetdents(0x%08"NACL_PRIxPTR", " | 721 ("Entered NaClCommonSysGetdents(0x%08"NACL_PRIxPTR", " |
| 722 "%d, 0x%08"NACL_PRIxPTR", " | 722 "%d, 0x%08"NACL_PRIxPTR", " |
| 723 "%"NACL_PRIdS"[0x%"NACL_PRIxS"])\n"), | 723 "%"NACL_PRIdS"[0x%"NACL_PRIxS"])\n"), |
| 724 (uintptr_t) natp, d, (uintptr_t) dirp, count, count); | 724 (uintptr_t) natp, d, (uintptr_t) dirp, count, count); |
| 725 | 725 |
| 726 NaClSysCommonThreadSyscallEnter(natp); | 726 NaClSysCommonThreadSyscallEnter(natp); |
| 727 | 727 |
| 728 sysaddr = NaClUserToSysAddrRange(natp->nap, (uintptr_t) dirp, count); | |
| 729 if (kNaClBadAddress == sysaddr) { | |
| 730 NaClLog(4, " illegal address for directory data\n"); | |
| 731 retval = -NACL_ABI_EFAULT; | |
| 732 goto cleanup; | |
| 733 } | |
| 734 ndp = NaClGetDesc(natp->nap, d); | 728 ndp = NaClGetDesc(natp->nap, d); |
| 735 if (NULL == ndp) { | 729 if (NULL == ndp) { |
| 736 retval = -NACL_ABI_EBADF; | 730 retval = -NACL_ABI_EBADF; |
| 737 goto cleanup; | 731 goto cleanup; |
| 738 } | 732 } |
| 739 | 733 |
| 734 sysaddr = NaClUserToSysAddrRange(natp->nap, (uintptr_t) dirp, count); |
| 735 if (kNaClBadAddress == sysaddr) { |
| 736 NaClLog(4, " illegal address for directory data\n"); |
| 737 retval = -NACL_ABI_EFAULT; |
| 738 goto cleanup_unref; |
| 739 } |
| 740 |
| 740 /* | 741 /* |
| 741 * Clamp count to INT32_MAX to avoid the possibility of Getdents returning | 742 * Clamp count to INT32_MAX to avoid the possibility of Getdents returning |
| 742 * a value that is outside the range of an int32. | 743 * a value that is outside the range of an int32. |
| 743 */ | 744 */ |
| 744 if (count > INT32_MAX) { | 745 if (count > INT32_MAX) { |
| 745 count = INT32_MAX; | 746 count = INT32_MAX; |
| 746 } | 747 } |
| 747 getdents_ret = (*((struct NaClDescVtbl const *) ndp->base.vtbl)-> | 748 getdents_ret = (*((struct NaClDescVtbl const *) ndp->base.vtbl)-> |
| 748 Getdents)(ndp, | 749 Getdents)(ndp, |
| 749 (void *) sysaddr, | 750 (void *) sysaddr, |
| 750 count); | 751 count); |
| 751 if ((getdents_ret < INT32_MIN && !NaClSSizeIsNegErrno(&getdents_ret)) | 752 if ((getdents_ret < INT32_MIN && !NaClSSizeIsNegErrno(&getdents_ret)) |
| 752 || INT32_MAX < getdents_ret) { | 753 || INT32_MAX < getdents_ret) { |
| 753 /* This should never happen, because we already clamped the input count */ | 754 /* This should never happen, because we already clamped the input count */ |
| 754 NaClLog(LOG_FATAL, "Overflow in Getdents: return value is %"NACL_PRIxS, | 755 NaClLog(LOG_FATAL, "Overflow in Getdents: return value is %"NACL_PRIxS, |
| 755 getdents_ret); | 756 getdents_ret); |
| 756 } else { | 757 } else { |
| 757 retval = (int32_t) getdents_ret; | 758 retval = (int32_t) getdents_ret; |
| 758 } | 759 } |
| 759 if (retval > 0) { | 760 if (retval > 0) { |
| 760 NaClLog(4, "getdents returned %d bytes\n", retval); | 761 NaClLog(4, "getdents returned %d bytes\n", retval); |
| 761 NaClLog(8, "getdents result: %.*s\n", retval, (char *) sysaddr); | 762 NaClLog(8, "getdents result: %.*s\n", retval, (char *) sysaddr); |
| 762 } else { | 763 } else { |
| 763 NaClLog(4, "getdents returned %d\n", retval); | 764 NaClLog(4, "getdents returned %d\n", retval); |
| 764 } | 765 } |
| 766 |
| 767 cleanup_unref: |
| 765 NaClDescUnref(ndp); | 768 NaClDescUnref(ndp); |
| 766 | 769 |
| 767 cleanup: | 770 cleanup: |
| 768 NaClSysCommonThreadSyscallLeave(natp); | 771 NaClSysCommonThreadSyscallLeave(natp); |
| 769 | 772 |
| 770 return retval; | 773 return retval; |
| 771 } | 774 } |
| 772 | 775 |
| 773 int32_t NaClCommonSysRead(struct NaClAppThread *natp, | 776 int32_t NaClCommonSysRead(struct NaClAppThread *natp, |
| 774 int d, | 777 int d, |
| 775 void *buf, | 778 void *buf, |
| 776 size_t count) { | 779 size_t count) { |
| 777 int32_t retval = -NACL_ABI_EINVAL; | 780 int32_t retval = -NACL_ABI_EINVAL; |
| 778 ssize_t read_result = -NACL_ABI_EINVAL; | 781 ssize_t read_result = -NACL_ABI_EINVAL; |
| 779 uintptr_t sysaddr; | 782 uintptr_t sysaddr; |
| 780 struct NaClDesc *ndp; | 783 struct NaClDesc *ndp; |
| 781 | 784 |
| 782 | 785 |
| 783 NaClLog(3, | 786 NaClLog(3, |
| 784 ("Entered NaClCommonSysRead(0x%08"NACL_PRIxPTR", " | 787 ("Entered NaClCommonSysRead(0x%08"NACL_PRIxPTR", " |
| 785 "%d, 0x%08"NACL_PRIxPTR", " | 788 "%d, 0x%08"NACL_PRIxPTR", " |
| 786 "%"NACL_PRIdS"[0x%"NACL_PRIxS"])\n"), | 789 "%"NACL_PRIdS"[0x%"NACL_PRIxS"])\n"), |
| 787 (uintptr_t) natp, d, (uintptr_t) buf, count, count); | 790 (uintptr_t) natp, d, (uintptr_t) buf, count, count); |
| 788 | 791 |
| 789 NaClSysCommonThreadSyscallEnter(natp); | 792 NaClSysCommonThreadSyscallEnter(natp); |
| 790 | 793 |
| 791 sysaddr = NaClUserToSysAddrRange(natp->nap, (uintptr_t) buf, count); | |
| 792 if (kNaClBadAddress == sysaddr) { | |
| 793 retval = -NACL_ABI_EFAULT; | |
| 794 goto cleanup; | |
| 795 } | |
| 796 ndp = NaClGetDesc(natp->nap, d); | 794 ndp = NaClGetDesc(natp->nap, d); |
| 797 if (NULL == ndp) { | 795 if (NULL == ndp) { |
| 798 retval = -NACL_ABI_EBADF; | 796 retval = -NACL_ABI_EBADF; |
| 799 goto cleanup; | 797 goto cleanup; |
| 800 } | 798 } |
| 801 | 799 |
| 800 sysaddr = NaClUserToSysAddrRange(natp->nap, (uintptr_t) buf, count); |
| 801 if (kNaClBadAddress == sysaddr) { |
| 802 NaClDescUnref(ndp); |
| 803 retval = -NACL_ABI_EFAULT; |
| 804 goto cleanup; |
| 805 } |
| 806 |
| 802 /* | 807 /* |
| 803 * The maximum length for read and write is INT32_MAX--anything larger and | 808 * The maximum length for read and write is INT32_MAX--anything larger and |
| 804 * the return value would overflow. Passing larger values isn't an error-- | 809 * the return value would overflow. Passing larger values isn't an error-- |
| 805 * we'll just clamp the request size if it's too large. | 810 * we'll just clamp the request size if it's too large. |
| 806 */ | 811 */ |
| 807 if (count > INT32_MAX) { | 812 if (count > INT32_MAX) { |
| 808 count = INT32_MAX; | 813 count = INT32_MAX; |
| 809 } | 814 } |
| 810 | 815 |
| 811 read_result = (*((struct NaClDescVtbl const *) ndp->base.vtbl)-> | 816 read_result = (*((struct NaClDescVtbl const *) ndp->base.vtbl)-> |
| (...skipping 26 matching lines...) Expand all Loading... |
| 838 struct NaClDesc *ndp; | 843 struct NaClDesc *ndp; |
| 839 | 844 |
| 840 NaClLog(3, | 845 NaClLog(3, |
| 841 "Entered NaClCommonSysWrite(0x%08"NACL_PRIxPTR", " | 846 "Entered NaClCommonSysWrite(0x%08"NACL_PRIxPTR", " |
| 842 "%d, 0x%08"NACL_PRIxPTR", " | 847 "%d, 0x%08"NACL_PRIxPTR", " |
| 843 "%"NACL_PRIdS"[0x%"NACL_PRIxS"])\n", | 848 "%"NACL_PRIdS"[0x%"NACL_PRIxS"])\n", |
| 844 (uintptr_t) natp, d, (uintptr_t) buf, count, count); | 849 (uintptr_t) natp, d, (uintptr_t) buf, count, count); |
| 845 | 850 |
| 846 NaClSysCommonThreadSyscallEnter(natp); | 851 NaClSysCommonThreadSyscallEnter(natp); |
| 847 | 852 |
| 853 ndp = NaClGetDesc(natp->nap, d); |
| 854 if (NULL == ndp) { |
| 855 retval = -NACL_ABI_EBADF; |
| 856 goto cleanup; |
| 857 } |
| 858 |
| 848 sysaddr = NaClUserToSysAddrRange(natp->nap, (uintptr_t) buf, count); | 859 sysaddr = NaClUserToSysAddrRange(natp->nap, (uintptr_t) buf, count); |
| 849 if (kNaClBadAddress == sysaddr) { | 860 if (kNaClBadAddress == sysaddr) { |
| 861 NaClDescUnref(ndp); |
| 850 retval = -NACL_ABI_EFAULT; | 862 retval = -NACL_ABI_EFAULT; |
| 851 goto cleanup; | 863 goto cleanup; |
| 852 } | 864 } |
| 853 | 865 |
| 854 NaClLog(4, "In NaClSysWrite(%d, %.*s, %"NACL_PRIdS")\n", | 866 NaClLog(4, "In NaClSysWrite(%d, %.*s, %"NACL_PRIdS")\n", |
| 855 d, (int) count, (char *) sysaddr, count); | 867 d, (int) count, (char *) sysaddr, count); |
| 856 | 868 |
| 857 ndp = NaClGetDesc(natp->nap, d); | |
| 858 if (NULL == ndp) { | |
| 859 retval = -NACL_ABI_EBADF; | |
| 860 goto cleanup; | |
| 861 } | |
| 862 | |
| 863 /* | 869 /* |
| 864 * The maximum length for read and write is INT32_MAX--anything larger and | 870 * The maximum length for read and write is INT32_MAX--anything larger and |
| 865 * the return value would overflow. Passing larger values isn't an error-- | 871 * the return value would overflow. Passing larger values isn't an error-- |
| 866 * we'll just clamp the request size if it's too large. | 872 * we'll just clamp the request size if it's too large. |
| 867 */ | 873 */ |
| 868 if (count > INT32_MAX) { | 874 if (count > INT32_MAX) { |
| 869 count = INT32_MAX; | 875 count = INT32_MAX; |
| 870 } | 876 } |
| 871 | 877 |
| 872 write_result = (*((struct NaClDescVtbl const *) ndp->base.vtbl)-> | 878 write_result = (*((struct NaClDescVtbl const *) ndp->base.vtbl)-> |
| (...skipping 24 matching lines...) Expand all Loading... |
| 897 int32_t retval = -NACL_ABI_EINVAL; | 903 int32_t retval = -NACL_ABI_EINVAL; |
| 898 struct NaClDesc *ndp; | 904 struct NaClDesc *ndp; |
| 899 | 905 |
| 900 NaClLog(3, | 906 NaClLog(3, |
| 901 ("Entered NaClCommonSysLseek(0x%08"NACL_PRIxPTR", %d," | 907 ("Entered NaClCommonSysLseek(0x%08"NACL_PRIxPTR", %d," |
| 902 " 0x%08"NACL_PRIxPTR", %d)\n"), | 908 " 0x%08"NACL_PRIxPTR", %d)\n"), |
| 903 (uintptr_t) natp, d, (uintptr_t) offp, whence); | 909 (uintptr_t) natp, d, (uintptr_t) offp, whence); |
| 904 | 910 |
| 905 NaClSysCommonThreadSyscallEnter(natp); | 911 NaClSysCommonThreadSyscallEnter(natp); |
| 906 | 912 |
| 907 sysaddr = NaClUserToSysAddrRange(natp->nap, (uintptr_t) offp, sizeof offset); | |
| 908 if (kNaClBadAddress == sysaddr) { | |
| 909 retval = -NACL_ABI_EFAULT; | |
| 910 goto cleanup; | |
| 911 } | |
| 912 offset = *(nacl_abi_off_t volatile *) sysaddr; | |
| 913 NaClLog(4, "offset 0x%08"NACL_PRIxNACL_OFF"\n", offset); | |
| 914 ndp = NaClGetDesc(natp->nap, d); | 913 ndp = NaClGetDesc(natp->nap, d); |
| 915 if (NULL == ndp) { | 914 if (NULL == ndp) { |
| 916 retval = -NACL_ABI_EBADF; | 915 retval = -NACL_ABI_EBADF; |
| 917 goto cleanup; | 916 goto cleanup; |
| 918 } | 917 } |
| 919 | 918 |
| 919 sysaddr = NaClUserToSysAddrRange(natp->nap, (uintptr_t) offp, sizeof offset); |
| 920 if (kNaClBadAddress == sysaddr) { |
| 921 retval = -NACL_ABI_EFAULT; |
| 922 goto cleanup_unref; |
| 923 } |
| 924 offset = *(nacl_abi_off_t volatile *) sysaddr; |
| 925 NaClLog(4, "offset 0x%08"NACL_PRIxNACL_OFF"\n", offset); |
| 926 |
| 920 retval64 = (*((struct NaClDescVtbl const *) ndp->base.vtbl)-> | 927 retval64 = (*((struct NaClDescVtbl const *) ndp->base.vtbl)-> |
| 921 Seek)(ndp, (nacl_off64_t) offset, whence); | 928 Seek)(ndp, (nacl_off64_t) offset, whence); |
| 922 if (NaClOff64IsNegErrno(&retval64)) { | 929 if (NaClOff64IsNegErrno(&retval64)) { |
| 923 retval = (int32_t) retval64; | 930 retval = (int32_t) retval64; |
| 924 } else { | 931 } else { |
| 925 *(nacl_abi_off_t volatile *) sysaddr = retval64; | 932 *(nacl_abi_off_t volatile *) sysaddr = retval64; |
| 926 retval = 0; | 933 retval = 0; |
| 927 } | 934 } |
| 935 cleanup_unref: |
| 928 NaClDescUnref(ndp); | 936 NaClDescUnref(ndp); |
| 929 cleanup: | 937 cleanup: |
| 930 NaClSysCommonThreadSyscallLeave(natp); | 938 NaClSysCommonThreadSyscallLeave(natp); |
| 931 return retval; | 939 return retval; |
| 932 } | 940 } |
| 933 | 941 |
| 934 int32_t NaClCommonSysIoctl(struct NaClAppThread *natp, | 942 int32_t NaClCommonSysIoctl(struct NaClAppThread *natp, |
| 935 int d, | 943 int d, |
| 936 int request, | 944 int request, |
| 937 void *arg) { | 945 void *arg) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 996 ", %d, 0x%08"NACL_PRIxPTR")\n"), | 1004 ", %d, 0x%08"NACL_PRIxPTR")\n"), |
| 997 (uintptr_t) natp, | 1005 (uintptr_t) natp, |
| 998 d, (uintptr_t) nasp); | 1006 d, (uintptr_t) nasp); |
| 999 | 1007 |
| 1000 NaClSysCommonThreadSyscallEnter(natp); | 1008 NaClSysCommonThreadSyscallEnter(natp); |
| 1001 | 1009 |
| 1002 NaClLog(4, | 1010 NaClLog(4, |
| 1003 " sizeof(struct nacl_abi_stat) = %"NACL_PRIdS" (0x%"NACL_PRIxS")\n", | 1011 " sizeof(struct nacl_abi_stat) = %"NACL_PRIdS" (0x%"NACL_PRIxS")\n", |
| 1004 sizeof *nasp, sizeof *nasp); | 1012 sizeof *nasp, sizeof *nasp); |
| 1005 | 1013 |
| 1006 sysaddr = NaClUserToSysAddrRange(natp->nap, (uintptr_t) nasp, sizeof *nasp); | |
| 1007 if (kNaClBadAddress == sysaddr) { | |
| 1008 NaClLog(4, "bad addr\n"); | |
| 1009 retval = -NACL_ABI_EFAULT; | |
| 1010 goto cleanup; | |
| 1011 } | |
| 1012 | |
| 1013 ndp = NaClGetDesc(natp->nap, d); | 1014 ndp = NaClGetDesc(natp->nap, d); |
| 1014 if (NULL == ndp) { | 1015 if (NULL == ndp) { |
| 1015 NaClLog(4, "bad desc\n"); | 1016 NaClLog(4, "bad desc\n"); |
| 1016 retval = -NACL_ABI_EBADF; | 1017 retval = -NACL_ABI_EBADF; |
| 1017 goto cleanup; | 1018 goto cleanup; |
| 1018 } | 1019 } |
| 1019 retval = (*((struct NaClDescVtbl const *) ndp->base.vtbl)-> | 1020 |
| 1020 Fstat)(ndp, (struct nacl_abi_stat *) sysaddr); | 1021 sysaddr = NaClUserToSysAddrRange(natp->nap, (uintptr_t) nasp, sizeof *nasp); |
| 1022 if (kNaClBadAddress == sysaddr) { |
| 1023 NaClLog(4, "bad addr\n"); |
| 1024 retval = -NACL_ABI_EFAULT; |
| 1025 } else { |
| 1026 retval = (*((struct NaClDescVtbl const *) ndp->base.vtbl)-> |
| 1027 Fstat)(ndp, (struct nacl_abi_stat *) sysaddr); |
| 1028 } |
| 1021 | 1029 |
| 1022 NaClDescUnref(ndp); | 1030 NaClDescUnref(ndp); |
| 1023 cleanup: | 1031 cleanup: |
| 1024 NaClSysCommonThreadSyscallLeave(natp); | 1032 NaClSysCommonThreadSyscallLeave(natp); |
| 1025 | 1033 |
| 1026 return retval; | 1034 return retval; |
| 1027 } | 1035 } |
| 1028 | 1036 |
| 1029 int32_t NaClCommonSysStat(struct NaClAppThread *natp, | 1037 int32_t NaClCommonSysStat(struct NaClAppThread *natp, |
| 1030 const char *pathname, | 1038 const char *pathname, |
| (...skipping 1717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2748 retval = -NACL_ABI_EBADF; | 2756 retval = -NACL_ABI_EBADF; |
| 2749 goto cleanup; | 2757 goto cleanup; |
| 2750 } | 2758 } |
| 2751 | 2759 |
| 2752 retval = (*((struct NaClDescVtbl const *) desc->base.vtbl)->GetValue)(desc); | 2760 retval = (*((struct NaClDescVtbl const *) desc->base.vtbl)->GetValue)(desc); |
| 2753 NaClDescUnref(desc); | 2761 NaClDescUnref(desc); |
| 2754 cleanup: | 2762 cleanup: |
| 2755 NaClSysCommonThreadSyscallLeave(natp); | 2763 NaClSysCommonThreadSyscallLeave(natp); |
| 2756 return retval; | 2764 return retval; |
| 2757 } | 2765 } |
| OLD | NEW |