- add new netlink type from linux v4.18 and v4.19

- fix coverity warning (CID 1390634)
 - fix ioctl(SIOCGIFCONF) crash
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJcXC7VAAoJEPMMOL0/L748KrMQALVIHaIwXFIF5l+GHBWnRKpN
 ApeignlyxCzy6s9wT9B8rw0JLgHu6DPeZ7D07A4VfQbN5G84IJ1uwqAOVXoHqAUe
 JfHYqGakhwbvueM4NjGzwS4o/OyjqsGOvnWtRM784rFTP8IHcgG15PxUYv3QUqpR
 BrpBEWImJJeBAulJ8F1CT0IU60wZNCf9XR9dSwSP0fwC9P+i38A0V7tfVJmnBNTA
 DrrXHop0MrHkrkvaAKKRA40VGxSXsXpjX90ACcsAdy4Qx3puIeh2BUaBZso/gcJP
 nCv6ks6YfbqDo4qoL0h/d0BElN3ZqynpFjrCLusn/pouLZYcwqW+rJfd7RY7uQrv
 8Fw/Y8NeRzbYej7ZqyAXDkhIBYp4NJt+jTaaUYRjGu2HT0pchaziQKCpAXfkV/+/
 m+3us3qesopkn6/O9BsCw5f2V4KYvjYVSs64u1bTsr6NRpi7dHHKztRCjcPhmxmj
 nkBcGPDgPlAwkHUraRBNsMkDQ3F5DFKL1xB/AHg2LIucXlzw/jP/HDgjzy73jiGq
 Jm4vQ2ETCzAWjVOgT6GsZx9vWj5p3dhL8OufkmNhk6WzSu4g4K1zoHTWNywFV/s3
 aUaIi4isYGpD3FCVjWTDKtpmtR58wKhBCpfW7jEmnNMLgzNGR37WmhYEGeuTjJ/i
 TTzqQ2hEVMNyQUgteTgg
 =ptgL
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-4.0-pull-request' into staging

- add new netlink type from linux v4.18 and v4.19
- fix coverity warning (CID 1390634)
- fix ioctl(SIOCGIFCONF) crash

# gpg: Signature made Thu 07 Feb 2019 13:12:53 GMT
# gpg:                using RSA key F30C38BD3F2FBE3C
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full]
# gpg:                 aka "Laurent Vivier <laurent@vivier.eu>" [full]
# gpg:                 aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full]
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F  5173 F30C 38BD 3F2F BE3C

* remotes/vivier2/tags/linux-user-for-4.0-pull-request:
  linux-user: add new netlink types
  linux-user: Check sscanf return value in open_net_route()
  Fix linux-user crashes in ioctl(SIOCGIFCONF) when ifc_buf is NULL.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2019-02-07 18:18:23 +00:00
commit ff372bb5c4
2 changed files with 48 additions and 28 deletions

View File

@ -129,6 +129,8 @@ enum {
QEMU_IFLA_CARRIER_UP_COUNT, QEMU_IFLA_CARRIER_UP_COUNT,
QEMU_IFLA_CARRIER_DOWN_COUNT, QEMU_IFLA_CARRIER_DOWN_COUNT,
QEMU_IFLA_NEW_IFINDEX, QEMU_IFLA_NEW_IFINDEX,
QEMU_IFLA_MIN_MTU,
QEMU_IFLA_MAX_MTU,
QEMU___IFLA_MAX QEMU___IFLA_MAX
}; };
@ -166,6 +168,8 @@ enum {
QEMU_IFLA_BRPORT_BCAST_FLOOD, QEMU_IFLA_BRPORT_BCAST_FLOOD,
QEMU_IFLA_BRPORT_GROUP_FWD_MASK, QEMU_IFLA_BRPORT_GROUP_FWD_MASK,
QEMU_IFLA_BRPORT_NEIGH_SUPPRESS, QEMU_IFLA_BRPORT_NEIGH_SUPPRESS,
QEMU_IFLA_BRPORT_ISOLATED,
QEMU_IFLA_BRPORT_BACKUP_PORT,
QEMU___IFLA_BRPORT_MAX QEMU___IFLA_BRPORT_MAX
}; };
@ -510,6 +514,7 @@ static abi_long host_to_target_slave_data_bridge_nlattr(struct nlattr *nlattr,
case QEMU_IFLA_BRPORT_VLAN_TUNNEL: case QEMU_IFLA_BRPORT_VLAN_TUNNEL:
case QEMU_IFLA_BRPORT_BCAST_FLOOD: case QEMU_IFLA_BRPORT_BCAST_FLOOD:
case QEMU_IFLA_BRPORT_NEIGH_SUPPRESS: case QEMU_IFLA_BRPORT_NEIGH_SUPPRESS:
case QEMU_IFLA_BRPORT_ISOLATED:
break; break;
/* uint16_t */ /* uint16_t */
case QEMU_IFLA_BRPORT_PRIORITY: case QEMU_IFLA_BRPORT_PRIORITY:
@ -523,6 +528,7 @@ static abi_long host_to_target_slave_data_bridge_nlattr(struct nlattr *nlattr,
break; break;
/* uin32_t */ /* uin32_t */
case QEMU_IFLA_BRPORT_COST: case QEMU_IFLA_BRPORT_COST:
case QEMU_IFLA_BRPORT_BACKUP_PORT:
u32 = NLA_DATA(nlattr); u32 = NLA_DATA(nlattr);
*u32 = tswap32(*u32); *u32 = tswap32(*u32);
break; break;
@ -787,6 +793,8 @@ static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr)
case QEMU_IFLA_GSO_MAX_SIZE: case QEMU_IFLA_GSO_MAX_SIZE:
case QEMU_IFLA_CARRIER_UP_COUNT: case QEMU_IFLA_CARRIER_UP_COUNT:
case QEMU_IFLA_CARRIER_DOWN_COUNT: case QEMU_IFLA_CARRIER_DOWN_COUNT:
case QEMU_IFLA_MIN_MTU:
case QEMU_IFLA_MAX_MTU:
u32 = RTA_DATA(rtattr); u32 = RTA_DATA(rtattr);
*u32 = tswap32(*u32); *u32 = tswap32(*u32);
break; break;

View File

@ -4187,28 +4187,33 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
unlock_user(argptr, arg, 0); unlock_user(argptr, arg, 0);
host_ifconf = (struct ifconf *)(unsigned long)buf_temp; host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
target_ifc_len = host_ifconf->ifc_len;
target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf; target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
target_ifreq_size = thunk_type_size(ifreq_arg_type, 0); target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
nb_ifreq = target_ifc_len / target_ifreq_size;
host_ifc_len = nb_ifreq * sizeof(struct ifreq);
outbufsz = sizeof(*host_ifconf) + host_ifc_len; if (target_ifc_buf != 0) {
if (outbufsz > MAX_STRUCT_SIZE) { target_ifc_len = host_ifconf->ifc_len;
/* We can't fit all the extents into the fixed size buffer. nb_ifreq = target_ifc_len / target_ifreq_size;
* Allocate one that is large enough and use it instead. host_ifc_len = nb_ifreq * sizeof(struct ifreq);
*/
host_ifconf = malloc(outbufsz); outbufsz = sizeof(*host_ifconf) + host_ifc_len;
if (!host_ifconf) { if (outbufsz > MAX_STRUCT_SIZE) {
return -TARGET_ENOMEM; /*
* We can't fit all the extents into the fixed size buffer.
* Allocate one that is large enough and use it instead.
*/
host_ifconf = malloc(outbufsz);
if (!host_ifconf) {
return -TARGET_ENOMEM;
}
memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
free_buf = 1;
} }
memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf)); host_ifc_buf = (char *)host_ifconf + sizeof(*host_ifconf);
free_buf = 1;
}
host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
host_ifconf->ifc_len = host_ifc_len; host_ifconf->ifc_len = host_ifc_len;
} else {
host_ifc_buf = NULL;
}
host_ifconf->ifc_buf = host_ifc_buf; host_ifconf->ifc_buf = host_ifc_buf;
ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_ifconf)); ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_ifconf));
@ -4231,15 +4236,16 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET); thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
unlock_user(argptr, arg, target_size); unlock_user(argptr, arg, target_size);
/* copy ifreq[] to target user */ if (target_ifc_buf != 0) {
/* copy ifreq[] to target user */
argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0); argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
for (i = 0; i < nb_ifreq ; i++) { for (i = 0; i < nb_ifreq ; i++) {
thunk_convert(argptr + i * target_ifreq_size, thunk_convert(argptr + i * target_ifreq_size,
host_ifc_buf + i * sizeof(struct ifreq), host_ifc_buf + i * sizeof(struct ifreq),
ifreq_arg_type, THUNK_TARGET); ifreq_arg_type, THUNK_TARGET);
}
unlock_user(argptr, target_ifc_buf, target_ifc_len);
} }
unlock_user(argptr, target_ifc_buf, target_ifc_len);
} }
if (free_buf) { if (free_buf) {
@ -6762,9 +6768,15 @@ static int open_net_route(void *cpu_env, int fd)
char iface[16]; char iface[16];
uint32_t dest, gw, mask; uint32_t dest, gw, mask;
unsigned int flags, refcnt, use, metric, mtu, window, irtt; unsigned int flags, refcnt, use, metric, mtu, window, irtt;
sscanf(line, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n", int fields;
iface, &dest, &gw, &flags, &refcnt, &use, &metric,
&mask, &mtu, &window, &irtt); fields = sscanf(line,
"%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
iface, &dest, &gw, &flags, &refcnt, &use, &metric,
&mask, &mtu, &window, &irtt);
if (fields != 11) {
continue;
}
dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n", dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
iface, tswap32(dest), tswap32(gw), flags, refcnt, use, iface, tswap32(dest), tswap32(gw), flags, refcnt, use,
metric, tswap32(mask), mtu, window, irtt); metric, tswap32(mask), mtu, window, irtt);