aboutsummaryrefslogtreecommitdiffstats
path: root/net/x25
diff options
context:
space:
mode:
Diffstat (limited to 'net/x25')
-rw-r--r--net/x25/af_x25.c511
-rw-r--r--net/x25/x25_dev.c50
-rw-r--r--net/x25/x25_facilities.c10
-rw-r--r--net/x25/x25_in.c151
-rw-r--r--net/x25/x25_link.c84
-rw-r--r--net/x25/x25_subr.c92
6 files changed, 486 insertions, 412 deletions
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 4680b1e4c79..5f03e4ea65b 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -91,7 +91,7 @@ int x25_parse_address_block(struct sk_buff *skb,
91 int needed; 91 int needed;
92 int rc; 92 int rc;
93 93
94 if (skb->len < 1) { 94 if (!pskb_may_pull(skb, 1)) {
95 /* packet has no address block */ 95 /* packet has no address block */
96 rc = 0; 96 rc = 0;
97 goto empty; 97 goto empty;
@@ -100,7 +100,7 @@ int x25_parse_address_block(struct sk_buff *skb,
100 len = *skb->data; 100 len = *skb->data;
101 needed = 1 + (len >> 4) + (len & 0x0f); 101 needed = 1 + (len >> 4) + (len & 0x0f);
102 102
103 if (skb->len < needed) { 103 if (!pskb_may_pull(skb, needed)) {
104 /* packet is too short to hold the addresses it claims 104 /* packet is too short to hold the addresses it claims
105 to hold */ 105 to hold */
106 rc = -1; 106 rc = -1;
@@ -237,21 +237,21 @@ static int x25_device_event(struct notifier_block *this, unsigned long event,
237#endif 237#endif
238 ) { 238 ) {
239 switch (event) { 239 switch (event) {
240 case NETDEV_UP: 240 case NETDEV_UP:
241 x25_link_device_up(dev); 241 x25_link_device_up(dev);
242 break; 242 break;
243 case NETDEV_GOING_DOWN: 243 case NETDEV_GOING_DOWN:
244 nb = x25_get_neigh(dev); 244 nb = x25_get_neigh(dev);
245 if (nb) { 245 if (nb) {
246 x25_terminate_link(nb); 246 x25_terminate_link(nb);
247 x25_neigh_put(nb); 247 x25_neigh_put(nb);
248 } 248 }
249 break; 249 break;
250 case NETDEV_DOWN: 250 case NETDEV_DOWN:
251 x25_kill_by_device(dev); 251 x25_kill_by_device(dev);
252 x25_route_device_down(dev); 252 x25_route_device_down(dev);
253 x25_link_device_down(dev); 253 x25_link_device_down(dev);
254 break; 254 break;
255 } 255 }
256 } 256 }
257 257
@@ -295,7 +295,8 @@ static struct sock *x25_find_listener(struct x25_address *addr,
295 * Found a listening socket, now check the incoming 295 * Found a listening socket, now check the incoming
296 * call user data vs this sockets call user data 296 * call user data vs this sockets call user data
297 */ 297 */
298 if(skb->len > 0 && x25_sk(s)->cudmatchlength > 0) { 298 if (x25_sk(s)->cudmatchlength > 0 &&
299 skb->len >= x25_sk(s)->cudmatchlength) {
299 if((memcmp(x25_sk(s)->calluserdata.cuddata, 300 if((memcmp(x25_sk(s)->calluserdata.cuddata,
300 skb->data, 301 skb->data,
301 x25_sk(s)->cudmatchlength)) == 0) { 302 x25_sk(s)->cudmatchlength)) == 0) {
@@ -951,14 +952,27 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
951 * 952 *
952 * Facilities length is mandatory in call request packets 953 * Facilities length is mandatory in call request packets
953 */ 954 */
954 if (skb->len < 1) 955 if (!pskb_may_pull(skb, 1))
955 goto out_clear_request; 956 goto out_clear_request;
956 len = skb->data[0] + 1; 957 len = skb->data[0] + 1;
957 if (skb->len < len) 958 if (!pskb_may_pull(skb, len))
958 goto out_clear_request; 959 goto out_clear_request;
959 skb_pull(skb,len); 960 skb_pull(skb,len);
960 961
961 /* 962 /*
963 * Ensure that the amount of call user data is valid.
964 */
965 if (skb->len > X25_MAX_CUD_LEN)
966 goto out_clear_request;
967
968 /*
969 * Get all the call user data so it can be used in
970 * x25_find_listener and skb_copy_from_linear_data up ahead.
971 */
972 if (!pskb_may_pull(skb, skb->len))
973 goto out_clear_request;
974
975 /*
962 * Find a listener for the particular address/cud pair. 976 * Find a listener for the particular address/cud pair.
963 */ 977 */
964 sk = x25_find_listener(&source_addr,skb); 978 sk = x25_find_listener(&source_addr,skb);
@@ -1166,6 +1180,9 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
1166 * byte of the user data is the logical value of the Q Bit. 1180 * byte of the user data is the logical value of the Q Bit.
1167 */ 1181 */
1168 if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) { 1182 if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) {
1183 if (!pskb_may_pull(skb, 1))
1184 goto out_kfree_skb;
1185
1169 qbit = skb->data[0]; 1186 qbit = skb->data[0];
1170 skb_pull(skb, 1); 1187 skb_pull(skb, 1);
1171 } 1188 }
@@ -1244,7 +1261,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
1244 struct x25_sock *x25 = x25_sk(sk); 1261 struct x25_sock *x25 = x25_sk(sk);
1245 struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)msg->msg_name; 1262 struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)msg->msg_name;
1246 size_t copied; 1263 size_t copied;
1247 int qbit; 1264 int qbit, header_len = x25->neighbour->extended ?
1265 X25_EXT_MIN_LEN : X25_STD_MIN_LEN;
1266
1248 struct sk_buff *skb; 1267 struct sk_buff *skb;
1249 unsigned char *asmptr; 1268 unsigned char *asmptr;
1250 int rc = -ENOTCONN; 1269 int rc = -ENOTCONN;
@@ -1265,6 +1284,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
1265 1284
1266 skb = skb_dequeue(&x25->interrupt_in_queue); 1285 skb = skb_dequeue(&x25->interrupt_in_queue);
1267 1286
1287 if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
1288 goto out_free_dgram;
1289
1268 skb_pull(skb, X25_STD_MIN_LEN); 1290 skb_pull(skb, X25_STD_MIN_LEN);
1269 1291
1270 /* 1292 /*
@@ -1285,10 +1307,12 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
1285 if (!skb) 1307 if (!skb)
1286 goto out; 1308 goto out;
1287 1309
1310 if (!pskb_may_pull(skb, header_len))
1311 goto out_free_dgram;
1312
1288 qbit = (skb->data[0] & X25_Q_BIT) == X25_Q_BIT; 1313 qbit = (skb->data[0] & X25_Q_BIT) == X25_Q_BIT;
1289 1314
1290 skb_pull(skb, x25->neighbour->extended ? 1315 skb_pull(skb, header_len);
1291 X25_EXT_MIN_LEN : X25_STD_MIN_LEN);
1292 1316
1293 if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) { 1317 if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) {
1294 asmptr = skb_push(skb, 1); 1318 asmptr = skb_push(skb, 1);
@@ -1336,256 +1360,253 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1336 int rc; 1360 int rc;
1337 1361
1338 switch (cmd) { 1362 switch (cmd) {
1339 case TIOCOUTQ: { 1363 case TIOCOUTQ: {
1340 int amount; 1364 int amount;
1341 1365
1342 amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); 1366 amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
1343 if (amount < 0) 1367 if (amount < 0)
1344 amount = 0; 1368 amount = 0;
1345 rc = put_user(amount, (unsigned int __user *)argp); 1369 rc = put_user(amount, (unsigned int __user *)argp);
1346 break; 1370 break;
1347 } 1371 }
1348 1372
1349 case TIOCINQ: { 1373 case TIOCINQ: {
1350 struct sk_buff *skb; 1374 struct sk_buff *skb;
1351 int amount = 0; 1375 int amount = 0;
1352 /* 1376 /*
1353 * These two are safe on a single CPU system as 1377 * These two are safe on a single CPU system as
1354 * only user tasks fiddle here 1378 * only user tasks fiddle here
1355 */ 1379 */
1356 lock_sock(sk); 1380 lock_sock(sk);
1357 if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) 1381 if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
1358 amount = skb->len; 1382 amount = skb->len;
1359 release_sock(sk); 1383 release_sock(sk);
1360 rc = put_user(amount, (unsigned int __user *)argp); 1384 rc = put_user(amount, (unsigned int __user *)argp);
1361 break; 1385 break;
1362 } 1386 }
1363 1387
1364 case SIOCGSTAMP: 1388 case SIOCGSTAMP:
1365 rc = -EINVAL; 1389 rc = -EINVAL;
1366 if (sk) 1390 if (sk)
1367 rc = sock_get_timestamp(sk, 1391 rc = sock_get_timestamp(sk,
1368 (struct timeval __user *)argp); 1392 (struct timeval __user *)argp);
1393 break;
1394 case SIOCGSTAMPNS:
1395 rc = -EINVAL;
1396 if (sk)
1397 rc = sock_get_timestampns(sk,
1398 (struct timespec __user *)argp);
1399 break;
1400 case SIOCGIFADDR:
1401 case SIOCSIFADDR:
1402 case SIOCGIFDSTADDR:
1403 case SIOCSIFDSTADDR:
1404 case SIOCGIFBRDADDR:
1405 case SIOCSIFBRDADDR:
1406 case SIOCGIFNETMASK:
1407 case SIOCSIFNETMASK:
1408 case SIOCGIFMETRIC:
1409 case SIOCSIFMETRIC:
1410 rc = -EINVAL;
1411 break;
1412 case SIOCADDRT:
1413 case SIOCDELRT:
1414 rc = -EPERM;
1415 if (!capable(CAP_NET_ADMIN))
1369 break; 1416 break;
1370 case SIOCGSTAMPNS: 1417 rc = x25_route_ioctl(cmd, argp);
1371 rc = -EINVAL; 1418 break;
1372 if (sk) 1419 case SIOCX25GSUBSCRIP:
1373 rc = sock_get_timestampns(sk, 1420 rc = x25_subscr_ioctl(cmd, argp);
1374 (struct timespec __user *)argp); 1421 break;
1375 break; 1422 case SIOCX25SSUBSCRIP:
1376 case SIOCGIFADDR: 1423 rc = -EPERM;
1377 case SIOCSIFADDR: 1424 if (!capable(CAP_NET_ADMIN))
1378 case SIOCGIFDSTADDR:
1379 case SIOCSIFDSTADDR:
1380 case SIOCGIFBRDADDR:
1381 case SIOCSIFBRDADDR:
1382 case SIOCGIFNETMASK:
1383 case SIOCSIFNETMASK:
1384 case SIOCGIFMETRIC:
1385 case SIOCSIFMETRIC:
1386 rc = -EINVAL;
1387 break;
1388 case SIOCADDRT:
1389 case SIOCDELRT:
1390 rc = -EPERM;
1391 if (!capable(CAP_NET_ADMIN))
1392 break;
1393 rc = x25_route_ioctl(cmd, argp);
1394 break;
1395 case SIOCX25GSUBSCRIP:
1396 rc = x25_subscr_ioctl(cmd, argp);
1397 break;
1398 case SIOCX25SSUBSCRIP:
1399 rc = -EPERM;
1400 if (!capable(CAP_NET_ADMIN))
1401 break;
1402 rc = x25_subscr_ioctl(cmd, argp);
1403 break;
1404 case SIOCX25GFACILITIES: {
1405 lock_sock(sk);
1406 rc = copy_to_user(argp, &x25->facilities,
1407 sizeof(x25->facilities))
1408 ? -EFAULT : 0;
1409 release_sock(sk);
1410 break; 1425 break;
1411 } 1426 rc = x25_subscr_ioctl(cmd, argp);
1427 break;
1428 case SIOCX25GFACILITIES: {
1429 lock_sock(sk);
1430 rc = copy_to_user(argp, &x25->facilities,
1431 sizeof(x25->facilities))
1432 ? -EFAULT : 0;
1433 release_sock(sk);
1434 break;
1435 }
1412 1436
1413 case SIOCX25SFACILITIES: { 1437 case SIOCX25SFACILITIES: {
1414 struct x25_facilities facilities; 1438 struct x25_facilities facilities;
1415 rc = -EFAULT; 1439 rc = -EFAULT;
1416 if (copy_from_user(&facilities, argp, 1440 if (copy_from_user(&facilities, argp, sizeof(facilities)))
1417 sizeof(facilities))) 1441 break;
1418 break; 1442 rc = -EINVAL;
1419 rc = -EINVAL; 1443 lock_sock(sk);
1420 lock_sock(sk); 1444 if (sk->sk_state != TCP_LISTEN &&
1421 if (sk->sk_state != TCP_LISTEN && 1445 sk->sk_state != TCP_CLOSE)
1422 sk->sk_state != TCP_CLOSE) 1446 goto out_fac_release;
1423 goto out_fac_release; 1447 if (facilities.pacsize_in < X25_PS16 ||
1424 if (facilities.pacsize_in < X25_PS16 || 1448 facilities.pacsize_in > X25_PS4096)
1425 facilities.pacsize_in > X25_PS4096) 1449 goto out_fac_release;
1426 goto out_fac_release; 1450 if (facilities.pacsize_out < X25_PS16 ||
1427 if (facilities.pacsize_out < X25_PS16 || 1451 facilities.pacsize_out > X25_PS4096)
1428 facilities.pacsize_out > X25_PS4096) 1452 goto out_fac_release;
1429 goto out_fac_release; 1453 if (facilities.winsize_in < 1 ||
1430 if (facilities.winsize_in < 1 || 1454 facilities.winsize_in > 127)
1431 facilities.winsize_in > 127) 1455 goto out_fac_release;
1456 if (facilities.throughput) {
1457 int out = facilities.throughput & 0xf0;
1458 int in = facilities.throughput & 0x0f;
1459 if (!out)
1460 facilities.throughput |=
1461 X25_DEFAULT_THROUGHPUT << 4;
1462 else if (out < 0x30 || out > 0xD0)
1432 goto out_fac_release; 1463 goto out_fac_release;
1433 if (facilities.throughput) { 1464 if (!in)
1434 int out = facilities.throughput & 0xf0; 1465 facilities.throughput |=
1435 int in = facilities.throughput & 0x0f; 1466 X25_DEFAULT_THROUGHPUT;
1436 if (!out) 1467 else if (in < 0x03 || in > 0x0D)
1437 facilities.throughput |=
1438 X25_DEFAULT_THROUGHPUT << 4;
1439 else if (out < 0x30 || out > 0xD0)
1440 goto out_fac_release;
1441 if (!in)
1442 facilities.throughput |=
1443 X25_DEFAULT_THROUGHPUT;
1444 else if (in < 0x03 || in > 0x0D)
1445 goto out_fac_release;
1446 }
1447 if (facilities.reverse &&
1448 (facilities.reverse & 0x81) != 0x81)
1449 goto out_fac_release; 1468 goto out_fac_release;
1450 x25->facilities = facilities;
1451 rc = 0;
1452out_fac_release:
1453 release_sock(sk);
1454 break;
1455 }
1456
1457 case SIOCX25GDTEFACILITIES: {
1458 lock_sock(sk);
1459 rc = copy_to_user(argp, &x25->dte_facilities,
1460 sizeof(x25->dte_facilities));
1461 release_sock(sk);
1462 if (rc)
1463 rc = -EFAULT;
1464 break;
1465 } 1469 }
1470 if (facilities.reverse &&
1471 (facilities.reverse & 0x81) != 0x81)
1472 goto out_fac_release;
1473 x25->facilities = facilities;
1474 rc = 0;
1475out_fac_release:
1476 release_sock(sk);
1477 break;
1478 }
1466 1479
1467 case SIOCX25SDTEFACILITIES: { 1480 case SIOCX25GDTEFACILITIES: {
1468 struct x25_dte_facilities dtefacs; 1481 lock_sock(sk);
1482 rc = copy_to_user(argp, &x25->dte_facilities,
1483 sizeof(x25->dte_facilities));
1484 release_sock(sk);
1485 if (rc)
1469 rc = -EFAULT; 1486 rc = -EFAULT;
1470 if (copy_from_user(&dtefacs, argp, sizeof(dtefacs))) 1487 break;
1471 break; 1488 }
1472 rc = -EINVAL;
1473 lock_sock(sk);
1474 if (sk->sk_state != TCP_LISTEN &&
1475 sk->sk_state != TCP_CLOSE)
1476 goto out_dtefac_release;
1477 if (dtefacs.calling_len > X25_MAX_AE_LEN)
1478 goto out_dtefac_release;
1479 if (dtefacs.calling_ae == NULL)
1480 goto out_dtefac_release;
1481 if (dtefacs.called_len > X25_MAX_AE_LEN)
1482 goto out_dtefac_release;
1483 if (dtefacs.called_ae == NULL)
1484 goto out_dtefac_release;
1485 x25->dte_facilities = dtefacs;
1486 rc = 0;
1487out_dtefac_release:
1488 release_sock(sk);
1489 break;
1490 }
1491 1489
1492 case SIOCX25GCALLUSERDATA: { 1490 case SIOCX25SDTEFACILITIES: {
1493 lock_sock(sk); 1491 struct x25_dte_facilities dtefacs;
1494 rc = copy_to_user(argp, &x25->calluserdata, 1492 rc = -EFAULT;
1495 sizeof(x25->calluserdata)) 1493 if (copy_from_user(&dtefacs, argp, sizeof(dtefacs)))
1496 ? -EFAULT : 0;
1497 release_sock(sk);
1498 break; 1494 break;
1499 } 1495 rc = -EINVAL;
1496 lock_sock(sk);
1497 if (sk->sk_state != TCP_LISTEN &&
1498 sk->sk_state != TCP_CLOSE)
1499 goto out_dtefac_release;
1500 if (dtefacs.calling_len > X25_MAX_AE_LEN)
1501 goto out_dtefac_release;
1502 if (dtefacs.calling_ae == NULL)
1503 goto out_dtefac_release;
1504 if (dtefacs.called_len > X25_MAX_AE_LEN)
1505 goto out_dtefac_release;
1506 if (dtefacs.called_ae == NULL)
1507 goto out_dtefac_release;
1508 x25->dte_facilities = dtefacs;
1509 rc = 0;
1510out_dtefac_release:
1511 release_sock(sk);
1512 break;
1513 }
1500 1514
1501 case SIOCX25SCALLUSERDATA: { 1515 case SIOCX25GCALLUSERDATA: {
1502 struct x25_calluserdata calluserdata; 1516 lock_sock(sk);
1517 rc = copy_to_user(argp, &x25->calluserdata,
1518 sizeof(x25->calluserdata))
1519 ? -EFAULT : 0;
1520 release_sock(sk);
1521 break;
1522 }
1503 1523
1504 rc = -EFAULT; 1524 case SIOCX25SCALLUSERDATA: {
1505 if (copy_from_user(&calluserdata, argp, 1525 struct x25_calluserdata calluserdata;
1506 sizeof(calluserdata)))
1507 break;
1508 rc = -EINVAL;
1509 if (calluserdata.cudlength > X25_MAX_CUD_LEN)
1510 break;
1511 lock_sock(sk);
1512 x25->calluserdata = calluserdata;
1513 release_sock(sk);
1514 rc = 0;
1515 break;
1516 }
1517 1526
1518 case SIOCX25GCAUSEDIAG: { 1527 rc = -EFAULT;
1519 lock_sock(sk); 1528 if (copy_from_user(&calluserdata, argp, sizeof(calluserdata)))
1520 rc = copy_to_user(argp, &x25->causediag,
1521 sizeof(x25->causediag))
1522 ? -EFAULT : 0;
1523 release_sock(sk);
1524 break; 1529 break;
1525 } 1530 rc = -EINVAL;
1531 if (calluserdata.cudlength > X25_MAX_CUD_LEN)
1532 break;
1533 lock_sock(sk);
1534 x25->calluserdata = calluserdata;
1535 release_sock(sk);
1536 rc = 0;
1537 break;
1538 }
1526 1539
1527 case SIOCX25SCAUSEDIAG: { 1540 case SIOCX25GCAUSEDIAG: {
1528 struct x25_causediag causediag; 1541 lock_sock(sk);
1529 rc = -EFAULT; 1542 rc = copy_to_user(argp, &x25->causediag, sizeof(x25->causediag))
1530 if (copy_from_user(&causediag, argp, sizeof(causediag))) 1543 ? -EFAULT : 0;
1531 break; 1544 release_sock(sk);
1532 lock_sock(sk); 1545 break;
1533 x25->causediag = causediag; 1546 }
1534 release_sock(sk); 1547
1535 rc = 0; 1548 case SIOCX25SCAUSEDIAG: {
1549 struct x25_causediag causediag;
1550 rc = -EFAULT;
1551 if (copy_from_user(&causediag, argp, sizeof(causediag)))
1536 break; 1552 break;
1553 lock_sock(sk);
1554 x25->causediag = causediag;
1555 release_sock(sk);
1556 rc = 0;
1557 break;
1537 1558
1538 } 1559 }
1539 1560
1540 case SIOCX25SCUDMATCHLEN: { 1561 case SIOCX25SCUDMATCHLEN: {
1541 struct x25_subaddr sub_addr; 1562 struct x25_subaddr sub_addr;
1542 rc = -EINVAL; 1563 rc = -EINVAL;
1543 lock_sock(sk); 1564 lock_sock(sk);
1544 if(sk->sk_state != TCP_CLOSE) 1565 if(sk->sk_state != TCP_CLOSE)
1545 goto out_cud_release; 1566 goto out_cud_release;
1546 rc = -EFAULT; 1567 rc = -EFAULT;
1547 if (copy_from_user(&sub_addr, argp, 1568 if (copy_from_user(&sub_addr, argp,
1548 sizeof(sub_addr))) 1569 sizeof(sub_addr)))
1549 goto out_cud_release; 1570 goto out_cud_release;
1550 rc = -EINVAL; 1571 rc = -EINVAL;
1551 if(sub_addr.cudmatchlength > X25_MAX_CUD_LEN) 1572 if (sub_addr.cudmatchlength > X25_MAX_CUD_LEN)
1552 goto out_cud_release; 1573 goto out_cud_release;
1553 x25->cudmatchlength = sub_addr.cudmatchlength; 1574 x25->cudmatchlength = sub_addr.cudmatchlength;
1554 rc = 0; 1575 rc = 0;
1555out_cud_release: 1576out_cud_release:
1556 release_sock(sk); 1577 release_sock(sk);
1557 break; 1578 break;
1558 } 1579 }
1559 1580
1560 case SIOCX25CALLACCPTAPPRV: { 1581 case SIOCX25CALLACCPTAPPRV: {
1561 rc = -EINVAL; 1582 rc = -EINVAL;
1562 lock_sock(sk); 1583 lock_sock(sk);
1563 if (sk->sk_state != TCP_CLOSE) 1584 if (sk->sk_state != TCP_CLOSE)
1564 break;
1565 clear_bit(X25_ACCPT_APPRV_FLAG, &x25->flags);
1566 release_sock(sk);
1567 rc = 0;
1568 break; 1585 break;
1569 } 1586 clear_bit(X25_ACCPT_APPRV_FLAG, &x25->flags);
1587 release_sock(sk);
1588 rc = 0;
1589 break;
1590 }
1570 1591
1571 case SIOCX25SENDCALLACCPT: { 1592 case SIOCX25SENDCALLACCPT: {
1572 rc = -EINVAL; 1593 rc = -EINVAL;
1573 lock_sock(sk); 1594 lock_sock(sk);
1574 if (sk->sk_state != TCP_ESTABLISHED) 1595 if (sk->sk_state != TCP_ESTABLISHED)
1575 break;
1576 /* must call accptapprv above */
1577 if (test_bit(X25_ACCPT_APPRV_FLAG, &x25->flags))
1578 break;
1579 x25_write_internal(sk, X25_CALL_ACCEPTED);
1580 x25->state = X25_STATE_3;
1581 release_sock(sk);
1582 rc = 0;
1583 break; 1596 break;
1584 } 1597 /* must call accptapprv above */
1585 1598 if (test_bit(X25_ACCPT_APPRV_FLAG, &x25->flags))
1586 default:
1587 rc = -ENOIOCTLCMD;
1588 break; 1599 break;
1600 x25_write_internal(sk, X25_CALL_ACCEPTED);
1601 x25->state = X25_STATE_3;
1602 release_sock(sk);
1603 rc = 0;
1604 break;
1605 }
1606
1607 default:
1608 rc = -ENOIOCTLCMD;
1609 break;
1589 } 1610 }
1590 1611
1591 return rc; 1612 return rc;
diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c
index 9005f6daeab..fa2b41888bd 100644
--- a/net/x25/x25_dev.c
+++ b/net/x25/x25_dev.c
@@ -32,6 +32,9 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb)
32 unsigned short frametype; 32 unsigned short frametype;
33 unsigned int lci; 33 unsigned int lci;
34 34
35 if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
36 return 0;
37
35 frametype = skb->data[2]; 38 frametype = skb->data[2];
36 lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); 39 lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
37 40
@@ -115,6 +118,9 @@ int x25_lapb_receive_frame(struct sk_buff *skb, struct net_device *dev,
115 goto drop; 118 goto drop;
116 } 119 }
117 120
121 if (!pskb_may_pull(skb, 1))
122 return 0;
123
118 switch (skb->data[0]) { 124 switch (skb->data[0]) {
119 125
120 case X25_IFACE_DATA: 126 case X25_IFACE_DATA:
@@ -146,21 +152,21 @@ void x25_establish_link(struct x25_neigh *nb)
146 unsigned char *ptr; 152 unsigned char *ptr;
147 153
148 switch (nb->dev->type) { 154 switch (nb->dev->type) {
149 case ARPHRD_X25: 155 case ARPHRD_X25:
150 if ((skb = alloc_skb(1, GFP_ATOMIC)) == NULL) { 156 if ((skb = alloc_skb(1, GFP_ATOMIC)) == NULL) {
151 printk(KERN_ERR "x25_dev: out of memory\n"); 157 printk(KERN_ERR "x25_dev: out of memory\n");
152 return; 158 return;
153 } 159 }
154 ptr = skb_put(skb, 1); 160 ptr = skb_put(skb, 1);
155 *ptr = X25_IFACE_CONNECT; 161 *ptr = X25_IFACE_CONNECT;
156 break; 162 break;
157 163
158#if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE) 164#if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
159 case ARPHRD_ETHER: 165 case ARPHRD_ETHER:
160 return; 166 return;
161#endif 167#endif
162 default: 168 default:
163 return; 169 return;
164 } 170 }
165 171
166 skb->protocol = htons(ETH_P_X25); 172 skb->protocol = htons(ETH_P_X25);
@@ -202,19 +208,19 @@ void x25_send_frame(struct sk_buff *skb, struct x25_neigh *nb)
202 skb_reset_network_header(skb); 208 skb_reset_network_header(skb);
203 209
204 switch (nb->dev->type) { 210 switch (nb->dev->type) {
205 case ARPHRD_X25: 211 case ARPHRD_X25:
206 dptr = skb_push(skb, 1); 212 dptr = skb_push(skb, 1);
207 *dptr = X25_IFACE_DATA; 213 *dptr = X25_IFACE_DATA;
208 break; 214 break;
209 215
210#if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE) 216#if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
211 case ARPHRD_ETHER: 217 case ARPHRD_ETHER:
212 kfree_skb(skb); 218 kfree_skb(skb);
213 return; 219 return;
214#endif 220#endif
215 default: 221 default:
216 kfree_skb(skb); 222 kfree_skb(skb);
217 return; 223 return;
218 } 224 }
219 225
220 skb->protocol = htons(ETH_P_X25); 226 skb->protocol = htons(ETH_P_X25);
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c
index f77e4e75f91..36384a1fa9f 100644
--- a/net/x25/x25_facilities.c
+++ b/net/x25/x25_facilities.c
@@ -44,7 +44,7 @@
44int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, 44int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
45 struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask) 45 struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask)
46{ 46{
47 unsigned char *p = skb->data; 47 unsigned char *p;
48 unsigned int len; 48 unsigned int len;
49 49
50 *vc_fac_mask = 0; 50 *vc_fac_mask = 0;
@@ -60,14 +60,16 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
60 memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae)); 60 memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae));
61 memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae)); 61 memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae));
62 62
63 if (skb->len < 1) 63 if (!pskb_may_pull(skb, 1))
64 return 0; 64 return 0;
65 65
66 len = *p++; 66 len = skb->data[0];
67 67
68 if (len >= skb->len) 68 if (!pskb_may_pull(skb, 1 + len))
69 return -1; 69 return -1;
70 70
71 p = skb->data + 1;
72
71 while (len > 0) { 73 while (len > 0) {
72 switch (*p & X25_FAC_CLASS_MASK) { 74 switch (*p & X25_FAC_CLASS_MASK) {
73 case X25_FAC_CLASS_A: 75 case X25_FAC_CLASS_A:
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c
index 15de65f0471..a49cd4ec551 100644
--- a/net/x25/x25_in.c
+++ b/net/x25/x25_in.c
@@ -94,55 +94,62 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
94 struct x25_sock *x25 = x25_sk(sk); 94 struct x25_sock *x25 = x25_sk(sk);
95 95
96 switch (frametype) { 96 switch (frametype) {
97 case X25_CALL_ACCEPTED: { 97 case X25_CALL_ACCEPTED: {
98 98
99 x25_stop_timer(sk); 99 x25_stop_timer(sk);
100 x25->condition = 0x00; 100 x25->condition = 0x00;
101 x25->vs = 0; 101 x25->vs = 0;
102 x25->va = 0; 102 x25->va = 0;
103 x25->vr = 0; 103 x25->vr = 0;
104 x25->vl = 0; 104 x25->vl = 0;
105 x25->state = X25_STATE_3; 105 x25->state = X25_STATE_3;
106 sk->sk_state = TCP_ESTABLISHED; 106 sk->sk_state = TCP_ESTABLISHED;
107 /* 107 /*
108 * Parse the data in the frame. 108 * Parse the data in the frame.
109 */ 109 */
110 skb_pull(skb, X25_STD_MIN_LEN); 110 if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
111 111 goto out_clear;
112 len = x25_parse_address_block(skb, &source_addr, 112 skb_pull(skb, X25_STD_MIN_LEN);
113 &dest_addr); 113
114 if (len > 0) 114 len = x25_parse_address_block(skb, &source_addr,
115 skb_pull(skb, len); 115 &dest_addr);
116 else if (len < 0) 116 if (len > 0)
117 skb_pull(skb, len);
118 else if (len < 0)
119 goto out_clear;
120
121 len = x25_parse_facilities(skb, &x25->facilities,
122 &x25->dte_facilities,
123 &x25->vc_facil_mask);
124 if (len > 0)
125 skb_pull(skb, len);
126 else if (len < 0)
127 goto out_clear;
128 /*
129 * Copy any Call User Data.
130 */
131 if (skb->len > 0) {
132 if (skb->len > X25_MAX_CUD_LEN)
117 goto out_clear; 133 goto out_clear;
118 134
119 len = x25_parse_facilities(skb, &x25->facilities, 135 skb_copy_bits(skb, 0, x25->calluserdata.cuddata,
120 &x25->dte_facilities, 136 skb->len);
121 &x25->vc_facil_mask); 137 x25->calluserdata.cudlength = skb->len;
122 if (len > 0)
123 skb_pull(skb, len);
124 else if (len < 0)
125 goto out_clear;
126 /*
127 * Copy any Call User Data.
128 */
129 if (skb->len > 0) {
130 skb_copy_from_linear_data(skb,
131 x25->calluserdata.cuddata,
132 skb->len);
133 x25->calluserdata.cudlength = skb->len;
134 }
135 if (!sock_flag(sk, SOCK_DEAD))
136 sk->sk_state_change(sk);
137 break;
138 } 138 }
139 case X25_CLEAR_REQUEST: 139 if (!sock_flag(sk, SOCK_DEAD))
140 x25_write_internal(sk, X25_CLEAR_CONFIRMATION); 140 sk->sk_state_change(sk);
141 x25_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]); 141 break;
142 break; 142 }
143 case X25_CLEAR_REQUEST:
144 if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
145 goto out_clear;
143 146
144 default: 147 x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
145 break; 148 x25_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
149 break;
150
151 default:
152 break;
146 } 153 }
147 154
148 return 0; 155 return 0;
@@ -164,6 +171,9 @@ static int x25_state2_machine(struct sock *sk, struct sk_buff *skb, int frametyp
164 switch (frametype) { 171 switch (frametype) {
165 172
166 case X25_CLEAR_REQUEST: 173 case X25_CLEAR_REQUEST:
174 if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
175 goto out_clear;
176
167 x25_write_internal(sk, X25_CLEAR_CONFIRMATION); 177 x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
168 x25_disconnect(sk, 0, skb->data[3], skb->data[4]); 178 x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
169 break; 179 break;
@@ -177,6 +187,11 @@ static int x25_state2_machine(struct sock *sk, struct sk_buff *skb, int frametyp
177 } 187 }
178 188
179 return 0; 189 return 0;
190
191out_clear:
192 x25_write_internal(sk, X25_CLEAR_REQUEST);
193 x25_start_t23timer(sk);
194 return 0;
180} 195}
181 196
182/* 197/*
@@ -206,6 +221,9 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
206 break; 221 break;
207 222
208 case X25_CLEAR_REQUEST: 223 case X25_CLEAR_REQUEST:
224 if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
225 goto out_clear;
226
209 x25_write_internal(sk, X25_CLEAR_CONFIRMATION); 227 x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
210 x25_disconnect(sk, 0, skb->data[3], skb->data[4]); 228 x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
211 break; 229 break;
@@ -304,6 +322,12 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
304 } 322 }
305 323
306 return queued; 324 return queued;
325
326out_clear:
327 x25_write_internal(sk, X25_CLEAR_REQUEST);
328 x25->state = X25_STATE_2;
329 x25_start_t23timer(sk);
330 return 0;
307} 331}
308 332
309/* 333/*
@@ -313,13 +337,13 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
313 */ 337 */
314static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype) 338static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype)
315{ 339{
340 struct x25_sock *x25 = x25_sk(sk);
341
316 switch (frametype) { 342 switch (frametype) {
317 343
318 case X25_RESET_REQUEST: 344 case X25_RESET_REQUEST:
319 x25_write_internal(sk, X25_RESET_CONFIRMATION); 345 x25_write_internal(sk, X25_RESET_CONFIRMATION);
320 case X25_RESET_CONFIRMATION: { 346 case X25_RESET_CONFIRMATION: {
321 struct x25_sock *x25 = x25_sk(sk);
322
323 x25_stop_timer(sk); 347 x25_stop_timer(sk);
324 x25->condition = 0x00; 348 x25->condition = 0x00;
325 x25->va = 0; 349 x25->va = 0;
@@ -331,6 +355,9 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp
331 break; 355 break;
332 } 356 }
333 case X25_CLEAR_REQUEST: 357 case X25_CLEAR_REQUEST:
358 if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
359 goto out_clear;
360
334 x25_write_internal(sk, X25_CLEAR_CONFIRMATION); 361 x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
335 x25_disconnect(sk, 0, skb->data[3], skb->data[4]); 362 x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
336 break; 363 break;
@@ -340,6 +367,12 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp
340 } 367 }
341 368
342 return 0; 369 return 0;
370
371out_clear:
372 x25_write_internal(sk, X25_CLEAR_REQUEST);
373 x25->state = X25_STATE_2;
374 x25_start_t23timer(sk);
375 return 0;
343} 376}
344 377
345/* Higher level upcall for a LAPB frame */ 378/* Higher level upcall for a LAPB frame */
@@ -354,18 +387,18 @@ int x25_process_rx_frame(struct sock *sk, struct sk_buff *skb)
354 frametype = x25_decode(sk, skb, &ns, &nr, &q, &d, &m); 387 frametype = x25_decode(sk, skb, &ns, &nr, &q, &d, &m);
355 388
356 switch (x25->state) { 389 switch (x25->state) {
357 case X25_STATE_1: 390 case X25_STATE_1:
358 queued = x25_state1_machine(sk, skb, frametype); 391 queued = x25_state1_machine(sk, skb, frametype);
359 break; 392 break;
360 case X25_STATE_2: 393 case X25_STATE_2:
361 queued = x25_state2_machine(sk, skb, frametype); 394 queued = x25_state2_machine(sk, skb, frametype);
362 break; 395 break;
363 case X25_STATE_3: 396 case X25_STATE_3:
364 queued = x25_state3_machine(sk, skb, frametype, ns, nr, q, d, m); 397 queued = x25_state3_machine(sk, skb, frametype, ns, nr, q, d, m);
365 break; 398 break;
366 case X25_STATE_4: 399 case X25_STATE_4:
367 queued = x25_state4_machine(sk, skb, frametype); 400 queued = x25_state4_machine(sk, skb, frametype);
368 break; 401 break;
369 } 402 }
370 403
371 x25_kick(sk); 404 x25_kick(sk);
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c
index 21306928d47..4acacf3c661 100644
--- a/net/x25/x25_link.c
+++ b/net/x25/x25_link.c
@@ -76,30 +76,32 @@ void x25_link_control(struct sk_buff *skb, struct x25_neigh *nb,
76 int confirm; 76 int confirm;
77 77
78 switch (frametype) { 78 switch (frametype) {
79 case X25_RESTART_REQUEST: 79 case X25_RESTART_REQUEST:
80 confirm = !x25_t20timer_pending(nb); 80 confirm = !x25_t20timer_pending(nb);
81 x25_stop_t20timer(nb); 81 x25_stop_t20timer(nb);
82 nb->state = X25_LINK_STATE_3; 82 nb->state = X25_LINK_STATE_3;
83 if (confirm) 83 if (confirm)
84 x25_transmit_restart_confirmation(nb); 84 x25_transmit_restart_confirmation(nb);
85 break;
86
87 case X25_RESTART_CONFIRMATION:
88 x25_stop_t20timer(nb);
89 nb->state = X25_LINK_STATE_3;
90 break;
91
92 case X25_DIAGNOSTIC:
93 if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 4))
85 break; 94 break;
86 95
87 case X25_RESTART_CONFIRMATION: 96 printk(KERN_WARNING "x25: diagnostic #%d - %02X %02X %02X\n",
88 x25_stop_t20timer(nb); 97 skb->data[3], skb->data[4],
89 nb->state = X25_LINK_STATE_3; 98 skb->data[5], skb->data[6]);
90 break; 99 break;
91
92 case X25_DIAGNOSTIC:
93 printk(KERN_WARNING "x25: diagnostic #%d - "
94 "%02X %02X %02X\n",
95 skb->data[3], skb->data[4],
96 skb->data[5], skb->data[6]);
97 break;
98 100
99 default: 101 default:
100 printk(KERN_WARNING "x25: received unknown %02X " 102 printk(KERN_WARNING "x25: received unknown %02X with LCI 000\n",
101 "with LCI 000\n", frametype); 103 frametype);
102 break; 104 break;
103 } 105 }
104 106
105 if (nb->state == X25_LINK_STATE_3) 107 if (nb->state == X25_LINK_STATE_3)
@@ -193,18 +195,18 @@ void x25_transmit_clear_request(struct x25_neigh *nb, unsigned int lci,
193void x25_transmit_link(struct sk_buff *skb, struct x25_neigh *nb) 195void x25_transmit_link(struct sk_buff *skb, struct x25_neigh *nb)
194{ 196{
195 switch (nb->state) { 197 switch (nb->state) {
196 case X25_LINK_STATE_0: 198 case X25_LINK_STATE_0:
197 skb_queue_tail(&nb->queue, skb); 199 skb_queue_tail(&nb->queue, skb);
198 nb->state = X25_LINK_STATE_1; 200 nb->state = X25_LINK_STATE_1;
199 x25_establish_link(nb); 201 x25_establish_link(nb);
200 break; 202 break;
201 case X25_LINK_STATE_1: 203 case X25_LINK_STATE_1:
202 case X25_LINK_STATE_2: 204 case X25_LINK_STATE_2:
203 skb_queue_tail(&nb->queue, skb); 205 skb_queue_tail(&nb->queue, skb);
204 break; 206 break;
205 case X25_LINK_STATE_3: 207 case X25_LINK_STATE_3:
206 x25_send_frame(skb, nb); 208 x25_send_frame(skb, nb);
207 break; 209 break;
208 } 210 }
209} 211}
210 212
@@ -214,14 +216,14 @@ void x25_transmit_link(struct sk_buff *skb, struct x25_neigh *nb)
214void x25_link_established(struct x25_neigh *nb) 216void x25_link_established(struct x25_neigh *nb)
215{ 217{
216 switch (nb->state) { 218 switch (nb->state) {
217 case X25_LINK_STATE_0: 219 case X25_LINK_STATE_0:
218 nb->state = X25_LINK_STATE_2; 220 nb->state = X25_LINK_STATE_2;
219 break; 221 break;
220 case X25_LINK_STATE_1: 222 case X25_LINK_STATE_1:
221 x25_transmit_restart_request(nb); 223 x25_transmit_restart_request(nb);
222 nb->state = X25_LINK_STATE_2; 224 nb->state = X25_LINK_STATE_2;
223 x25_start_t20timer(nb); 225 x25_start_t20timer(nb);
224 break; 226 break;
225 } 227 }
226} 228}
227 229
diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c
index dc20cf12f39..5170d52bfd9 100644
--- a/net/x25/x25_subr.c
+++ b/net/x25/x25_subr.c
@@ -126,32 +126,30 @@ void x25_write_internal(struct sock *sk, int frametype)
126 * Adjust frame size. 126 * Adjust frame size.
127 */ 127 */
128 switch (frametype) { 128 switch (frametype) {
129 case X25_CALL_REQUEST: 129 case X25_CALL_REQUEST:
130 len += 1 + X25_ADDR_LEN + X25_MAX_FAC_LEN + 130 len += 1 + X25_ADDR_LEN + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
131 X25_MAX_CUD_LEN; 131 break;
132 break; 132 case X25_CALL_ACCEPTED: /* fast sel with no restr on resp */
133 case X25_CALL_ACCEPTED: /* fast sel with no restr on resp */ 133 if (x25->facilities.reverse & 0x80) {
134 if(x25->facilities.reverse & 0x80) { 134 len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
135 len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN; 135 } else {
136 } else { 136 len += 1 + X25_MAX_FAC_LEN;
137 len += 1 + X25_MAX_FAC_LEN; 137 }
138 } 138 break;
139 break; 139 case X25_CLEAR_REQUEST:
140 case X25_CLEAR_REQUEST: 140 case X25_RESET_REQUEST:
141 case X25_RESET_REQUEST: 141 len += 2;
142 len += 2; 142 break;
143 break; 143 case X25_RR:
144 case X25_RR: 144 case X25_RNR:
145 case X25_RNR: 145 case X25_REJ:
146 case X25_REJ: 146 case X25_CLEAR_CONFIRMATION:
147 case X25_CLEAR_CONFIRMATION: 147 case X25_INTERRUPT_CONFIRMATION:
148 case X25_INTERRUPT_CONFIRMATION: 148 case X25_RESET_CONFIRMATION:
149 case X25_RESET_CONFIRMATION: 149 break;
150 break; 150 default:
151 default: 151 printk(KERN_ERR "X.25: invalid frame type %02X\n", frametype);
152 printk(KERN_ERR "X.25: invalid frame type %02X\n", 152 return;
153 frametype);
154 return;
155 } 153 }
156 154
157 if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL) 155 if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
@@ -271,31 +269,39 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
271 int *d, int *m) 269 int *d, int *m)
272{ 270{
273 struct x25_sock *x25 = x25_sk(sk); 271 struct x25_sock *x25 = x25_sk(sk);
274 unsigned char *frame = skb->data; 272 unsigned char *frame;
273
274 if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
275 return X25_ILLEGAL;
276 frame = skb->data;
275 277
276 *ns = *nr = *q = *d = *m = 0; 278 *ns = *nr = *q = *d = *m = 0;
277 279
278 switch (frame[2]) { 280 switch (frame[2]) {
279 case X25_CALL_REQUEST: 281 case X25_CALL_REQUEST:
280 case X25_CALL_ACCEPTED: 282 case X25_CALL_ACCEPTED:
281 case X25_CLEAR_REQUEST: 283 case X25_CLEAR_REQUEST:
282 case X25_CLEAR_CONFIRMATION: 284 case X25_CLEAR_CONFIRMATION:
283 case X25_INTERRUPT: 285 case X25_INTERRUPT:
284 case X25_INTERRUPT_CONFIRMATION: 286 case X25_INTERRUPT_CONFIRMATION:
285 case X25_RESET_REQUEST: 287 case X25_RESET_REQUEST:
286 case X25_RESET_CONFIRMATION: 288 case X25_RESET_CONFIRMATION:
287 case X25_RESTART_REQUEST: 289 case X25_RESTART_REQUEST:
288 case X25_RESTART_CONFIRMATION: 290 case X25_RESTART_CONFIRMATION:
289 case X25_REGISTRATION_REQUEST: 291 case X25_REGISTRATION_REQUEST:
290 case X25_REGISTRATION_CONFIRMATION: 292 case X25_REGISTRATION_CONFIRMATION:
291 case X25_DIAGNOSTIC: 293 case X25_DIAGNOSTIC:
292 return frame[2]; 294 return frame[2];
293 } 295 }
294 296
295 if (x25->neighbour->extended) { 297 if (x25->neighbour->extended) {
296 if (frame[2] == X25_RR || 298 if (frame[2] == X25_RR ||
297 frame[2] == X25_RNR || 299 frame[2] == X25_RNR ||
298 frame[2] == X25_REJ) { 300 frame[2] == X25_REJ) {
301 if (!pskb_may_pull(skb, X25_EXT_MIN_LEN))
302 return X25_ILLEGAL;
303 frame = skb->data;
304
299 *nr = (frame[3] >> 1) & 0x7F; 305 *nr = (frame[3] >> 1) & 0x7F;
300 return frame[2]; 306 return frame[2];
301 } 307 }
@@ -310,6 +316,10 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
310 316
311 if (x25->neighbour->extended) { 317 if (x25->neighbour->extended) {
312 if ((frame[2] & 0x01) == X25_DATA) { 318 if ((frame[2] & 0x01) == X25_DATA) {
319 if (!pskb_may_pull(skb, X25_EXT_MIN_LEN))
320 return X25_ILLEGAL;
321 frame = skb->data;
322
313 *q = (frame[0] & X25_Q_BIT) == X25_Q_BIT; 323 *q = (frame[0] & X25_Q_BIT) == X25_Q_BIT;
314 *d = (frame[0] & X25_D_BIT) == X25_D_BIT; 324 *d = (frame[0] & X25_D_BIT) == X25_D_BIT;
315 *m = (frame[3] & X25_EXT_M_BIT) == X25_EXT_M_BIT; 325 *m = (frame[3] & X25_EXT_M_BIT) == X25_EXT_M_BIT;