* Return interface configuration * of system. List may be used * in later ioctl's (above) to get * other information. */ ARGSUSED*/
| 3197 | */ |
| 3198 | /*ARGSUSED*/ |
| 3199 | static int |
| 3200 | ifconf(u_long cmd, caddr_t data) |
| 3201 | { |
| 3202 | struct ifconf *ifc = (struct ifconf *)data; |
| 3203 | struct ifnet *ifp; |
| 3204 | struct ifaddr *ifa; |
| 3205 | struct ifreq ifr; |
| 3206 | struct sbuf *sb; |
| 3207 | int error, full = 0, valid_len, max_len; |
| 3208 | |
| 3209 | /* Limit initial buffer size to maxphys to avoid DoS from userspace. */ |
| 3210 | max_len = maxphys - 1; |
| 3211 | |
| 3212 | /* Prevent hostile input from being able to crash the system */ |
| 3213 | if (ifc->ifc_len <= 0) |
| 3214 | return (EINVAL); |
| 3215 | |
| 3216 | again: |
| 3217 | if (ifc->ifc_len <= max_len) { |
| 3218 | max_len = ifc->ifc_len; |
| 3219 | full = 1; |
| 3220 | } |
| 3221 | sb = sbuf_new(NULL, NULL, max_len + 1, SBUF_FIXEDLEN); |
| 3222 | max_len = 0; |
| 3223 | valid_len = 0; |
| 3224 | |
| 3225 | IFNET_RLOCK(); |
| 3226 | CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { |
| 3227 | struct epoch_tracker et; |
| 3228 | int addrs; |
| 3229 | |
| 3230 | /* |
| 3231 | * Zero the ifr to make sure we don't disclose the contents |
| 3232 | * of the stack. |
| 3233 | */ |
| 3234 | memset(&ifr, 0, sizeof(ifr)); |
| 3235 | |
| 3236 | if (strlcpy(ifr.ifr_name, ifp->if_xname, sizeof(ifr.ifr_name)) |
| 3237 | >= sizeof(ifr.ifr_name)) { |
| 3238 | sbuf_delete(sb); |
| 3239 | IFNET_RUNLOCK(); |
| 3240 | return (ENAMETOOLONG); |
| 3241 | } |
| 3242 | |
| 3243 | addrs = 0; |
| 3244 | NET_EPOCH_ENTER(et); |
| 3245 | CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { |
| 3246 | struct sockaddr *sa = ifa->ifa_addr; |
| 3247 | |
| 3248 | if (prison_if(curthread->td_ucred, sa) != 0) |
| 3249 | continue; |
| 3250 | addrs++; |
| 3251 | if (sa->sa_len <= sizeof(*sa)) { |
| 3252 | if (sa->sa_len < sizeof(*sa)) { |
| 3253 | memset(&ifr.ifr_ifru.ifru_addr, 0, |
| 3254 | sizeof(ifr.ifr_ifru.ifru_addr)); |
| 3255 | memcpy(&ifr.ifr_ifru.ifru_addr, sa, |
| 3256 | sa->sa_len); |
no test coverage detected