aboutsummaryrefslogtreecommitdiff
path: root/net/x25/x25_subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/x25/x25_subr.c')
-rw-r--r--net/x25/x25_subr.c96
1 files changed, 54 insertions, 42 deletions
diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c
index dc20cf12f39..6b5af65f491 100644
--- a/net/x25/x25_subr.c
+++ b/net/x25/x25_subr.c
@@ -23,6 +23,8 @@
* restriction on response.
*/
+#define pr_fmt(fmt) "X25: " fmt
+
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/string.h>
@@ -126,32 +128,30 @@ void x25_write_internal(struct sock *sk, int frametype)
* Adjust frame size.
*/
switch (frametype) {
- case X25_CALL_REQUEST:
- len += 1 + X25_ADDR_LEN + X25_MAX_FAC_LEN +
- X25_MAX_CUD_LEN;
- break;
- case X25_CALL_ACCEPTED: /* fast sel with no restr on resp */
- if(x25->facilities.reverse & 0x80) {
- len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
- } else {
- len += 1 + X25_MAX_FAC_LEN;
- }
- break;
- case X25_CLEAR_REQUEST:
- case X25_RESET_REQUEST:
- len += 2;
- break;
- case X25_RR:
- case X25_RNR:
- case X25_REJ:
- case X25_CLEAR_CONFIRMATION:
- case X25_INTERRUPT_CONFIRMATION:
- case X25_RESET_CONFIRMATION:
- break;
- default:
- printk(KERN_ERR "X.25: invalid frame type %02X\n",
- frametype);
- return;
+ case X25_CALL_REQUEST:
+ len += 1 + X25_ADDR_LEN + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
+ break;
+ case X25_CALL_ACCEPTED: /* fast sel with no restr on resp */
+ if (x25->facilities.reverse & 0x80) {
+ len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
+ } else {
+ len += 1 + X25_MAX_FAC_LEN;
+ }
+ break;
+ case X25_CLEAR_REQUEST:
+ case X25_RESET_REQUEST:
+ len += 2;
+ break;
+ case X25_RR:
+ case X25_RNR:
+ case X25_REJ:
+ case X25_CLEAR_CONFIRMATION:
+ case X25_INTERRUPT_CONFIRMATION:
+ case X25_RESET_CONFIRMATION:
+ break;
+ default:
+ pr_err("invalid frame type %02X\n", frametype);
+ return;
}
if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
@@ -271,31 +271,39 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
int *d, int *m)
{
struct x25_sock *x25 = x25_sk(sk);
- unsigned char *frame = skb->data;
+ unsigned char *frame;
+
+ if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
+ return X25_ILLEGAL;
+ frame = skb->data;
*ns = *nr = *q = *d = *m = 0;
switch (frame[2]) {
- case X25_CALL_REQUEST:
- case X25_CALL_ACCEPTED:
- case X25_CLEAR_REQUEST:
- case X25_CLEAR_CONFIRMATION:
- case X25_INTERRUPT:
- case X25_INTERRUPT_CONFIRMATION:
- case X25_RESET_REQUEST:
- case X25_RESET_CONFIRMATION:
- case X25_RESTART_REQUEST:
- case X25_RESTART_CONFIRMATION:
- case X25_REGISTRATION_REQUEST:
- case X25_REGISTRATION_CONFIRMATION:
- case X25_DIAGNOSTIC:
- return frame[2];
+ case X25_CALL_REQUEST:
+ case X25_CALL_ACCEPTED:
+ case X25_CLEAR_REQUEST:
+ case X25_CLEAR_CONFIRMATION:
+ case X25_INTERRUPT:
+ case X25_INTERRUPT_CONFIRMATION:
+ case X25_RESET_REQUEST:
+ case X25_RESET_CONFIRMATION:
+ case X25_RESTART_REQUEST:
+ case X25_RESTART_CONFIRMATION:
+ case X25_REGISTRATION_REQUEST:
+ case X25_REGISTRATION_CONFIRMATION:
+ case X25_DIAGNOSTIC:
+ return frame[2];
}
if (x25->neighbour->extended) {
if (frame[2] == X25_RR ||
frame[2] == X25_RNR ||
frame[2] == X25_REJ) {
+ if (!pskb_may_pull(skb, X25_EXT_MIN_LEN))
+ return X25_ILLEGAL;
+ frame = skb->data;
+
*nr = (frame[3] >> 1) & 0x7F;
return frame[2];
}
@@ -310,6 +318,10 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
if (x25->neighbour->extended) {
if ((frame[2] & 0x01) == X25_DATA) {
+ if (!pskb_may_pull(skb, X25_EXT_MIN_LEN))
+ return X25_ILLEGAL;
+ frame = skb->data;
+
*q = (frame[0] & X25_Q_BIT) == X25_Q_BIT;
*d = (frame[0] & X25_D_BIT) == X25_D_BIT;
*m = (frame[3] & X25_EXT_M_BIT) == X25_EXT_M_BIT;
@@ -328,7 +340,7 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
}
}
- printk(KERN_DEBUG "X.25: invalid PLP frame %02X %02X %02X\n",
+ pr_debug("invalid PLP frame %02X %02X %02X\n",
frame[0], frame[1], frame[2]);
return X25_ILLEGAL;