aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/mISDN/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/mISDN/socket.c')
-rw-r--r--drivers/isdn/mISDN/socket.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index 508945d1b9c1..c36f52137456 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -209,7 +209,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
209 209
210 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { 210 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
211 err = -EFAULT; 211 err = -EFAULT;
212 goto drop; 212 goto done;
213 } 213 }
214 214
215 memcpy(mISDN_HEAD_P(skb), skb->data, MISDN_HEADER_LEN); 215 memcpy(mISDN_HEAD_P(skb), skb->data, MISDN_HEADER_LEN);
@@ -222,7 +222,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
222 } else { /* use default for L2 messages */ 222 } else { /* use default for L2 messages */
223 if ((sk->sk_protocol == ISDN_P_LAPD_TE) || 223 if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
224 (sk->sk_protocol == ISDN_P_LAPD_NT)) 224 (sk->sk_protocol == ISDN_P_LAPD_NT))
225 mISDN_HEAD_ID(skb) = _pms(sk)->ch.nr; 225 mISDN_HEAD_ID(skb) = _pms(sk)->ch.nr;
226 } 226 }
227 227
228 if (*debug & DEBUG_SOCKET) 228 if (*debug & DEBUG_SOCKET)
@@ -230,19 +230,21 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
230 __func__, mISDN_HEAD_ID(skb)); 230 __func__, mISDN_HEAD_ID(skb));
231 231
232 err = -ENODEV; 232 err = -ENODEV;
233 if (!_pms(sk)->ch.peer || 233 if (!_pms(sk)->ch.peer)
234 (err = _pms(sk)->ch.recv(_pms(sk)->ch.peer, skb))) 234 goto done;
235 goto drop; 235 err = _pms(sk)->ch.recv(_pms(sk)->ch.peer, skb);
236 236 if (err)
237 err = len; 237 goto done;
238 else {
239 skb = NULL;
240 err = len;
241 }
238 242
239done: 243done:
244 if (skb)
245 kfree_skb(skb);
240 release_sock(sk); 246 release_sock(sk);
241 return err; 247 return err;
242
243drop:
244 kfree_skb(skb);
245 goto done;
246} 248}
247 249
248static int 250static int
@@ -292,7 +294,7 @@ static int
292data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p) 294data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
293{ 295{
294 struct mISDN_ctrl_req cq; 296 struct mISDN_ctrl_req cq;
295 int err = -EINVAL, val; 297 int err = -EINVAL, val[2];
296 struct mISDNchannel *bchan, *next; 298 struct mISDNchannel *bchan, *next;
297 299
298 lock_sock(sk); 300 lock_sock(sk);
@@ -328,12 +330,27 @@ data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
328 err = -EINVAL; 330 err = -EINVAL;
329 break; 331 break;
330 } 332 }
331 if (get_user(val, (int __user *)p)) { 333 val[0] = cmd;
334 if (get_user(val[1], (int __user *)p)) {
335 err = -EFAULT;
336 break;
337 }
338 err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
339 CONTROL_CHANNEL, val);
340 break;
341 case IMHOLD_L1:
342 if (sk->sk_protocol != ISDN_P_LAPD_NT
343 && sk->sk_protocol != ISDN_P_LAPD_TE) {
344 err = -EINVAL;
345 break;
346 }
347 val[0] = cmd;
348 if (get_user(val[1], (int __user *)p)) {
332 err = -EFAULT; 349 err = -EFAULT;
333 break; 350 break;
334 } 351 }
335 err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr, 352 err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
336 CONTROL_CHANNEL, &val); 353 CONTROL_CHANNEL, val);
337 break; 354 break;
338 default: 355 default:
339 err = -EINVAL; 356 err = -EINVAL;