2 * SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname, char __user *, optval, int, optlen)
9 #include <sys/socket.h>
10 #include <linux/types.h>
22 void (*func
)(struct sockopt
*so
);
25 static const struct sso_funcptr ssoptrs
[] = {
26 { .func
= &ip_setsockopt
},
27 { .func
= &socket_setsockopt
},
28 { .func
= &tcp_setsockopt
},
29 { .func
= &udp_setsockopt
},
30 { .func
= &inet6_setsockopt
},
31 { .func
= &icmpv6_setsockopt
},
32 { .func
= &sctp_setsockopt
},
33 { .func
= &udplite_setsockopt
},
34 { .func
= &raw_setsockopt
},
35 { .func
= &ipx_setsockopt
},
36 { .func
= &ax25_setsockopt
},
37 { .func
= &atalk_setsockopt
},
38 { .func
= &netrom_setsockopt
},
39 { .func
= &rose_setsockopt
},
40 { .func
= &decnet_setsockopt
},
41 { .func
= &x25_setsockopt
},
42 { .func
= &packet_setsockopt
},
43 { .func
= &atm_setsockopt
},
44 { .func
= &aal_setsockopt
},
45 { .func
= &irda_setsockopt
},
46 { .func
= &netbeui_setsockopt
},
47 { .func
= &llc_setsockopt
},
48 { .func
= &dccp_setsockopt
},
49 { .func
= &netlink_setsockopt
},
50 { .func
= &tipc_setsockopt
},
51 { .func
= &rxrpc_setsockopt
},
52 { .func
= &pppol2tp_setsockopt
},
53 { .func
= &bluetooth_setsockopt
},
54 { .func
= &pnpipe_setsockopt
},
55 { .func
= &rds_setsockopt
},
56 { .func
= &iucv_setsockopt
},
57 { .func
= &caif_setsockopt
},
58 { .func
= &alg_setsockopt
},
59 { .func
= &nfc_setsockopt
},
63 * Call a proto specific setsockopt routine from the table above.
65 static void do_setsockopt(struct sockopt
*so
)
67 so
->optval
= (unsigned long) get_non_null_address();
69 // pick a size for optlen. At the minimum, we want an int (overridden below)
71 so
->optlen
= sizeof(int);
73 so
->optlen
= rand() % 256;
75 if (rand() % 100 > 0) {
76 ssoptrs
[rand() % ARRAY_SIZE(ssoptrs
)].func(so
);
79 so
->optname
= (rand() % 0x100); /* random operation. */
83 * 10% of the time, mangle the options.
84 * This should catch new options we don't know about, and also maybe some missing bounds checks.
86 if ((rand() % 100) < 10)
87 so
->optname
|= (1 << (rand() % 32));
89 /* optval should be nonzero to enable a boolean option, or zero if the option is to be disabled.
90 * Let's disable it half the time.
97 * This is called during socket creation at startup, on each socket,
98 * and also periodically from regenerate()
100 void sso_socket(struct socket_triplet
*triplet
, struct sockopt
*so
, int fd
)
103 unsigned int tries
= 0;
105 /* skip over bluetooth due to weird linger bug */
106 if (triplet
->family
== PF_BLUETOOTH
)
112 ret
= setsockopt(fd
, so
->level
, so
->optname
, (void *)so
->optval
, so
->optlen
);
114 output(2, "Setsockopt(%lx %lx %lx %lx) on fd %d [%d:%d:%d]\n",
115 so
->level
, so
->optname
, so
->optval
, so
->optlen
, fd
,
116 triplet
->family
, triplet
->type
, triplet
->protocol
);
126 static void sanitise_setsockopt(int childno
)
128 struct sockopt so
= { 0, 0, 0, 0 };
132 /* copy the generated values to the shm. */
133 shm
->syscall
[childno
].a2
= so
.level
;
134 shm
->syscall
[childno
].a3
= so
.optname
;
135 shm
->syscall
[childno
].a4
= so
.optval
;
136 shm
->syscall
[childno
].a5
= so
.optlen
;
139 struct syscallentry syscall_setsockopt
= {
140 .name
= "setsockopt",
145 .arg3name
= "optname",
146 .arg4name
= "optval",
147 .arg4type
= ARG_ADDRESS
,
148 .arg5name
= "optlen",
149 .sanitise
= sanitise_setsockopt
,