* In the unlikely case when user specified n greater then the last * open file descriptor, check that no bits are set after the last * valid fd. We must return EBADF if any is set. * * There are applications that rely on the behaviour. * * nd is fd_nfiles. */
| 1026 | * nd is fd_nfiles. |
| 1027 | */ |
| 1028 | static int |
| 1029 | select_check_badfd(fd_set *fd_in, int nd, int ndu, int abi_nfdbits) |
| 1030 | { |
| 1031 | char *addr, *oaddr; |
| 1032 | int b, i, res; |
| 1033 | uint8_t bits; |
| 1034 | |
| 1035 | if (nd >= ndu || fd_in == NULL) |
| 1036 | return (0); |
| 1037 | |
| 1038 | oaddr = NULL; |
| 1039 | bits = 0; /* silence gcc */ |
| 1040 | for (i = nd; i < ndu; i++) { |
| 1041 | b = i / NBBY; |
| 1042 | #if BYTE_ORDER == LITTLE_ENDIAN |
| 1043 | addr = (char *)fd_in + b; |
| 1044 | #else |
| 1045 | addr = (char *)fd_in; |
| 1046 | if (abi_nfdbits == NFDBITS) { |
| 1047 | addr += rounddown(b, sizeof(fd_mask)) + |
| 1048 | sizeof(fd_mask) - 1 - b % sizeof(fd_mask); |
| 1049 | } else { |
| 1050 | addr += rounddown(b, sizeof(uint32_t)) + |
| 1051 | sizeof(uint32_t) - 1 - b % sizeof(uint32_t); |
| 1052 | } |
| 1053 | #endif |
| 1054 | if (addr != oaddr) { |
| 1055 | res = fubyte(addr); |
| 1056 | if (res == -1) |
| 1057 | return (EFAULT); |
| 1058 | oaddr = addr; |
| 1059 | bits = res; |
| 1060 | } |
| 1061 | if ((bits & (1 << (i % NBBY))) != 0) |
| 1062 | return (EBADF); |
| 1063 | } |
| 1064 | return (0); |
| 1065 | } |
| 1066 | |
| 1067 | int |
| 1068 | kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, |