diff options
Diffstat (limited to 'net/dccp/proto.c')
-rw-r--r-- | net/dccp/proto.c | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index f4da6561e40c..18a0e69c9dc7 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -205,23 +205,67 @@ int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
205 | int dccp_setsockopt(struct sock *sk, int level, int optname, | 205 | int dccp_setsockopt(struct sock *sk, int level, int optname, |
206 | char __user *optval, int optlen) | 206 | char __user *optval, int optlen) |
207 | { | 207 | { |
208 | dccp_pr_debug("entry\n"); | 208 | struct dccp_sock *dp; |
209 | int err; | ||
210 | int val; | ||
209 | 211 | ||
210 | if (level != SOL_DCCP) | 212 | if (level != SOL_DCCP) |
211 | return ip_setsockopt(sk, level, optname, optval, optlen); | 213 | return ip_setsockopt(sk, level, optname, optval, optlen); |
212 | 214 | ||
213 | return -EOPNOTSUPP; | 215 | if (optlen < sizeof(int)) |
216 | return -EINVAL; | ||
217 | |||
218 | if (get_user(val, (int __user *)optval)) | ||
219 | return -EFAULT; | ||
220 | |||
221 | lock_sock(sk); | ||
222 | |||
223 | dp = dccp_sk(sk); | ||
224 | err = 0; | ||
225 | |||
226 | switch (optname) { | ||
227 | case DCCP_SOCKOPT_PACKET_SIZE: | ||
228 | dp->dccps_packet_size = val; | ||
229 | break; | ||
230 | default: | ||
231 | err = -ENOPROTOOPT; | ||
232 | break; | ||
233 | } | ||
234 | |||
235 | release_sock(sk); | ||
236 | return err; | ||
214 | } | 237 | } |
215 | 238 | ||
216 | int dccp_getsockopt(struct sock *sk, int level, int optname, | 239 | int dccp_getsockopt(struct sock *sk, int level, int optname, |
217 | char __user *optval, int __user *optlen) | 240 | char __user *optval, int __user *optlen) |
218 | { | 241 | { |
219 | dccp_pr_debug("entry\n"); | 242 | struct dccp_sock *dp; |
243 | int val, len; | ||
220 | 244 | ||
221 | if (level != SOL_DCCP) | 245 | if (level != SOL_DCCP) |
222 | return ip_getsockopt(sk, level, optname, optval, optlen); | 246 | return ip_getsockopt(sk, level, optname, optval, optlen); |
223 | 247 | ||
224 | return -EOPNOTSUPP; | 248 | if (get_user(len, optlen)) |
249 | return -EFAULT; | ||
250 | |||
251 | len = min_t(unsigned int, len, sizeof(int)); | ||
252 | if (len < 0) | ||
253 | return -EINVAL; | ||
254 | |||
255 | dp = dccp_sk(sk); | ||
256 | |||
257 | switch (optname) { | ||
258 | case DCCP_SOCKOPT_PACKET_SIZE: | ||
259 | val = dp->dccps_packet_size; | ||
260 | break; | ||
261 | default: | ||
262 | return -ENOPROTOOPT; | ||
263 | } | ||
264 | |||
265 | if (put_user(len, optlen) || copy_to_user(optval, &val, len)) | ||
266 | return -EFAULT; | ||
267 | |||
268 | return 0; | ||
225 | } | 269 | } |
226 | 270 | ||
227 | int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | 271 | int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |