Host errno must be converted to target errno in IP_RECVERR
and IPV6_RECVERR socket options.
Fixes: ee1ac3a1822 ("linux-user: Add sockopts for IPv6")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/602
Reported-by: Conrad Meyer <cem@FreeBSD.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
v2: Corrected patch description
---
linux-user/syscall.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ccd3892b2df..edc9d6b5ba2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1967,7 +1967,8 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
tgt_len != sizeof(struct errhdr_t)) {
goto unimplemented;
}
- __put_user(errh->ee.ee_errno, &target_errh->ee.ee_errno);
+ __put_user(get_errno(errh->ee.ee_errno),
+ &target_errh->ee.ee_errno);
__put_user(errh->ee.ee_origin, &target_errh->ee.ee_origin);
__put_user(errh->ee.ee_type, &target_errh->ee.ee_type);
__put_user(errh->ee.ee_code, &target_errh->ee.ee_code);
@@ -2011,7 +2012,8 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
tgt_len != sizeof(struct errhdr6_t)) {
goto unimplemented;
}
- __put_user(errh->ee.ee_errno, &target_errh->ee.ee_errno);
+ __put_user(get_errno(errh->ee.ee_errno),
+ &target_errh->ee.ee_errno);
__put_user(errh->ee.ee_origin, &target_errh->ee.ee_origin);
__put_user(errh->ee.ee_type, &target_errh->ee.ee_type);
__put_user(errh->ee.ee_code, &target_errh->ee.ee_code);
--
2.31.1
Le 11/09/2021 à 19:08, Philippe Mathieu-Daudé a écrit : > Host errno must be converted to target errno in IP_RECVERR > and IPV6_RECVERR socket options. > > Fixes: ee1ac3a1822 ("linux-user: Add sockopts for IPv6") > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/602 > Reported-by: Conrad Meyer <cem@FreeBSD.org> > Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> > --- > v2: Corrected patch description > --- > linux-user/syscall.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index ccd3892b2df..edc9d6b5ba2 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -1967,7 +1967,8 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh, > tgt_len != sizeof(struct errhdr_t)) { > goto unimplemented; > } > - __put_user(errh->ee.ee_errno, &target_errh->ee.ee_errno); > + __put_user(get_errno(errh->ee.ee_errno), > + &target_errh->ee.ee_errno); > __put_user(errh->ee.ee_origin, &target_errh->ee.ee_origin); > __put_user(errh->ee.ee_type, &target_errh->ee.ee_type); > __put_user(errh->ee.ee_code, &target_errh->ee.ee_code); > @@ -2011,7 +2012,8 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh, > tgt_len != sizeof(struct errhdr6_t)) { > goto unimplemented; > } > - __put_user(errh->ee.ee_errno, &target_errh->ee.ee_errno); > + __put_user(get_errno(errh->ee.ee_errno), > + &target_errh->ee.ee_errno); > __put_user(errh->ee.ee_origin, &target_errh->ee.ee_origin); > __put_user(errh->ee.ee_type, &target_errh->ee.ee_type); > __put_user(errh->ee.ee_code, &target_errh->ee.ee_code); > I don't think it's the correct use of get_errno() here. get_errno() is: static inline abi_long get_errno(abi_long ret) { if (ret == -1) return -host_to_target_errno(errno); else return ret; } and ee_errno is: struct sock_extended_err { __u32 ee_errno; __u8 ee_origin; __u8 ee_type; __u8 ee_code; __u8 ee_pad; __u32 ee_info; union { __u32 ee_data; struct sock_ee_data_rfc4884 ee_rfc4884; }; }; https://man7.org/linux/man-pages/man7/ip.7.html ee_errno contains the errno number of the queued error. so ee_errno is never negative. You should use "host_to_target_errno(errh->ee.ee_errno)" Thanks, Laurent
© 2016 - 2024 Red Hat, Inc.