summary refs log tree commit diff stats
path: root/results/classifier/zero-shot-user-mode/instruction/2410
blob: 35334b96626507820062740e3fac2e9c6199280a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
instruction: 0.345
syscall: 0.328
runtime: 0.327



linux-user: `Setsockopt` with IP_OPTIONS returns "Protocol not available" error
Description of problem:
It seems that call to `setsockopt(sd, SOL_IP, IP_OPTIONS,_)` behaves differently on RISC-V Qemu than on x64 Linux. 
On Linux syscall returns 0, but on Qemu it fails with `Protocol not available`.
According [man](https://man7.org/linux/man-pages/man7/ip.7.html) `IP_OPTIONS` on `SOCK_STREAM` socket "should work".
Steps to reproduce:
1. Use below toy program `setsockopt.c` and compile it without optimizations like:
```
    gcc -Wall -W -Wextra -std=gnu17 -pedantic setsockopt.c -o setsockopt
```

```
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    {
        int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if(sd < 0) {
            perror("Opening stream socket error");
            exit(1);
        }
        else
            printf("Opening stream socket....OK.\n");

        struct sockaddr_in local_address = {AF_INET, htons(1234), {inet_addr("255.255.255.255")}, {0}};
        int err = connect(sd, (struct sockaddr*)&local_address, (socklen_t)16);

        if (err < 0) {
            perror("Connect error");
            close(sd);
        }
        else
            printf("Connect...OK.\n");
    }
    {
        int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if(sd < 0) {
            perror("Opening stream socket error");
            exit(1);
        }
        else
            printf("Opening stream socket....OK.\n");

        char option[4] = {0};
        if(setsockopt(sd, SOL_IP, IP_OPTIONS, (char *)option, sizeof(option)) < 0) {
            perror("setsockopt error");
            close(sd);
            exit(1);
        }
        else
            printf("setsockopt...OK.\n");

        struct sockaddr_in local_address = {AF_INET, htons(1234), {inet_addr("255.255.255.255")}, {0}};
        int err = connect(sd, (struct sockaddr*)&local_address, (socklen_t)16);

        if (err < 0) {
            perror("Connect error");
            close(sd);
        }
        else
            printf("Connect...OK.\n");
    }
    return 0;
}
```


2. Run program on Qemu and compare output with output from x64 build. In my case it looks like:
```
root@AMDC4705:~/runtime/connect$ ./setsockopt-x64
Opening stream socket....OK.
Connect error: Network is unreachable
Opening stream socket....OK.
setsockopt...OK.
Connect error: Network is unreachable

root@AMDC4705:/runtime/connect# ./setsockopt-riscv
Opening stream socket....OK.
Connect error: Network is unreachable
Opening stream socket....OK.
setsockopt error: Protocol not available
```
Additional information:
In above demo option `value` is quite artificial. However I tried passing many different `option` arguments (with same `SOL_IP` + `IP_OPTIONS` combination) but always ended up with `setsockopt` failure. 
From the other hand on x64 it worked fine. Then I realized that appropriate path in Qemu was unimplemented: https://github.com/qemu/qemu/blob/master/linux-user/syscall.c#L2141