[IrDA patch] ir247_ias_fix_max.diff

From: Jean Tourrilhes (jt@bougret.hpl.hp.com)
Date: Thu Sep 13 2001 - 18:18:25 EST


ir247_ias_fix_max.diff :
----------------------
        o [CRITICA] Check overflow in string duplicate code in IAS/IAP
                - It was only done (more or less) if DEBUG was enabled
        o [CORRECT] Fix deadlock on legal large OCT_SEQ IAP replies
        o [CORRECT] Increase max IAS attribute size for IrDA compliance

diff -u -p linux/include/linux/irda.d8.h linux/include/linux/irda.h
--- linux/include/linux/irda.d8.h Thu Sep 13 11:35:56 2001
+++ linux/include/linux/irda.h Thu Sep 13 11:38:31 2001
@@ -92,10 +92,15 @@ enum {
 
 #define IRTTP_MAX_SDU_SIZE IRLMP_MAX_SDU_SIZE /* Compatibility */
 
-#define IAS_MAX_STRING 256
-#define IAS_MAX_OCTET_STRING 1024
-#define IAS_MAX_CLASSNAME 64
-#define IAS_MAX_ATTRIBNAME 256
+#define IAS_MAX_STRING 256 /* See IrLMP 1.1, 4.3.3.2 */
+#define IAS_MAX_OCTET_STRING 1024 /* See IrLMP 1.1, 4.3.3.2 */
+#define IAS_MAX_CLASSNAME 60 /* See IrLMP 1.1, 4.3.1 */
+#define IAS_MAX_ATTRIBNAME 60 /* See IrLMP 1.1, 4.3.3.1 */
+#define IAS_MAX_ATTRIBNUMBER 256 /* See IrLMP 1.1, 4.3.3.1 */
+/* For user space backward compatibility - may be fixed in kernel 2.5.X
+ * Note : need 60+1 ('\0'), make it 64 for alignement - Jean II */
+#define IAS_EXPORT_CLASSNAME 64
+#define IAS_EXPORT_ATTRIBNAME 256
 
 /* Attribute type needed for struct irda_ias_set */
 #define IAS_MISSING 0
@@ -126,8 +131,8 @@ struct irda_device_list {
 };
 
 struct irda_ias_set {
- char irda_class_name[IAS_MAX_CLASSNAME];
- char irda_attrib_name[IAS_MAX_ATTRIBNAME];
+ char irda_class_name[IAS_EXPORT_CLASSNAME];
+ char irda_attrib_name[IAS_EXPORT_ATTRIBNAME];
         unsigned int irda_attrib_type;
         union {
                 unsigned int irda_attrib_int;
diff -u -p linux/include/net/irda/irias_object.d8.h linux/include/net/irda/irias_object.h
--- linux/include/net/irda/irias_object.d8.h Thu Sep 13 11:36:24 2001
+++ linux/include/net/irda/irias_object.h Thu Sep 13 11:38:31 2001
@@ -78,7 +78,7 @@ struct ias_attrib {
         struct ias_value *value; /* Attribute value */
 };
 
-char *strdup(char *str);
+char *strndup(char *str, int max);
 
 struct ias_object *irias_new_object(char *name, int id);
 void irias_insert_object(struct ias_object *obj);
diff -u -p linux/net/irda/irias_object.d8.c linux/net/irda/irias_object.c
--- linux/net/irda/irias_object.d8.c Thu Sep 13 11:36:46 2001
+++ linux/net/irda/irias_object.c Thu Sep 13 11:38:31 2001
@@ -37,25 +37,35 @@ hashbin_t *objects = NULL;
 struct ias_value missing = { IAS_MISSING, 0, 0, 0, {0}};
 
 /*
- * Function strdup (str)
+ * Function strndup (str, max)
  *
- * My own kernel version of strdup!
+ * My own kernel version of strndup!
  *
+ * Faster, check boundary... Jean II
  */
-char *strdup(char *str)
+char *strndup(char *str, int max)
 {
         char *new_str;
+ int len;
         
+ /* Check string */
         if (str == NULL)
                 return NULL;
-
- ASSERT(strlen( str) < 64, return NULL;);
-
- new_str = kmalloc(strlen(str)+1, GFP_ATOMIC);
- if (new_str == NULL)
+ /* Check length, truncate */
+ len = strlen(str);
+ if(len > max)
+ len = max;
+
+ /* Allocate new string */
+ new_str = kmalloc(len + 1, GFP_ATOMIC);
+ if (new_str == NULL) {
+ WARNING(__FUNCTION__"(), Unable to kmalloc!\n");
                 return NULL;
-
- strcpy(new_str, str);
+ }
+
+ /* Copy and truncate */
+ memcpy(new_str, str, len);
+ new_str[len] = '\0';
         
         return new_str;
 }
@@ -81,7 +91,7 @@ struct ias_object *irias_new_object( cha
         memset(obj, 0, sizeof( struct ias_object));
 
         obj->magic = IAS_OBJECT_MAGIC;
- obj->name = strdup( name);
+ obj->name = strndup(name, IAS_MAX_CLASSNAME);
         obj->id = id;
 
         obj->attribs = hashbin_new(HB_LOCAL);
@@ -315,7 +325,7 @@ void irias_add_integer_attrib(struct ias
         memset(attrib, 0, sizeof( struct ias_attrib));
 
         attrib->magic = IAS_ATTRIB_MAGIC;
- attrib->name = strdup(name);
+ attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
 
         /* Insert value */
         attrib->value = irias_new_integer_value(value);
@@ -351,7 +361,7 @@ void irias_add_octseq_attrib(struct ias_
         memset(attrib, 0, sizeof( struct ias_attrib));
         
         attrib->magic = IAS_ATTRIB_MAGIC;
- attrib->name = strdup( name);
+ attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
         
         attrib->value = irias_new_octseq_value( octets, len);
         
@@ -384,7 +394,7 @@ void irias_add_string_attrib(struct ias_
         memset(attrib, 0, sizeof( struct ias_attrib));
 
         attrib->magic = IAS_ATTRIB_MAGIC;
- attrib->name = strdup(name);
+ attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
 
         attrib->value = irias_new_string_value(value);
 
@@ -420,10 +430,13 @@ struct ias_value *irias_new_integer_valu
  *
  * Create new IAS string value
  *
+ * Per IrLMP 1.1, 4.3.3.2, strings are up to 256 chars - Jean II
  */
 struct ias_value *irias_new_string_value(char *string)
 {
         struct ias_value *value;
+ int len;
+ char *new_str;
 
         value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
         if (value == NULL) {
@@ -434,8 +447,8 @@ struct ias_value *irias_new_string_value
 
         value->type = IAS_STRING;
         value->charset = CS_ASCII;
- value->len = strlen(string);
- value->t.string = strdup(string);
+ value->t.string = strndup(string, IAS_MAX_STRING);
+ value->len = strlen(value->t.string);
 
         return value;
 }
@@ -446,6 +459,7 @@ struct ias_value *irias_new_string_value
  *
  * Create new IAS octet-sequence value
  *
+ * Per IrLMP 1.1, 4.3.3.2, octet-sequence are up to 1024 bytes - Jean II
  */
 struct ias_value *irias_new_octseq_value(__u8 *octseq , int len)
 {
@@ -459,11 +473,15 @@ struct ias_value *irias_new_octseq_value
         memset(value, 0, sizeof(struct ias_value));
 
         value->type = IAS_OCT_SEQ;
+ /* Check length */
+ if(len > IAS_MAX_OCTET_STRING)
+ len = IAS_MAX_OCTET_STRING;
         value->len = len;
 
         value->t.oct_seq = kmalloc(len, GFP_ATOMIC);
         if (value->t.oct_seq == NULL){
                 WARNING(__FUNCTION__"(), Unable to kmalloc!\n");
+ kfree(value);
                 return NULL;
         }
         memcpy(value->t.oct_seq, octseq , len);
diff -u -p linux/net/irda/iriap.d8.c linux/net/irda/iriap.c
--- linux/net/irda/iriap.d8.c Thu Sep 13 11:37:13 2001
+++ linux/net/irda/iriap.c Thu Sep 13 11:38:31 2001
@@ -379,7 +379,7 @@ int iriap_getvaluebyclass_request(struct
                                   char *name, char *attr)
 {
         struct sk_buff *skb;
- int name_len, attr_len;
+ int name_len, attr_len, skb_len;
         __u8 *frame;
 
         ASSERT(self != NULL, return -1;);
@@ -400,13 +400,14 @@ int iriap_getvaluebyclass_request(struct
         /* Give ourselves 10 secs to finish this operation */
         iriap_start_watchdog_timer(self, 10*HZ);
         
- skb = dev_alloc_skb(64);
+ name_len = strlen(name); /* Up to IAS_MAX_CLASSNAME = 60 */
+ attr_len = strlen(attr); /* Up to IAS_MAX_ATTRIBNAME = 60 */
+
+ skb_len = self->max_header_size+2+name_len+1+attr_len+4;
+ skb = dev_alloc_skb(skb_len);
         if (!skb)
                 return -ENOMEM;
 
- name_len = strlen(name);
- attr_len = strlen(attr);
-
         /* Reserve space for MUX and LAP header */
          skb_reserve(skb, self->max_header_size);
         skb_put(skb, 3+name_len+attr_len);
@@ -500,20 +501,19 @@ void iriap_getvaluebyclass_confirm(struc
                 }
                 value_len = fp[n++];
                 IRDA_DEBUG(4, __FUNCTION__ "(), strlen=%d\n", value_len);
- ASSERT(value_len < 64, return;);
                 
                 /* Make sure the string is null-terminated */
                 fp[n+value_len] = 0x00;
-
                 IRDA_DEBUG(4, "Got string %s\n", fp+n);
+
+ /* Will truncate to IAS_MAX_STRING bytes */
                 value = irias_new_string_value(fp+n);
                 break;
         case IAS_OCT_SEQ:
                 value_len = be16_to_cpu(get_unaligned((__u16 *)(fp+n)));
                 n += 2;
                 
- ASSERT(value_len <= 55, return;);
-
+ /* Will truncate to IAS_MAX_OCTET_STRING bytes */
                 value = irias_new_octseq_value(fp+n, value_len);
                 break;
         default:
@@ -635,8 +635,8 @@ void iriap_getvaluebyclass_indication(st
         struct ias_attrib *attrib;
         int name_len;
         int attr_len;
- char name[64];
- char attr[64];
+ char name[IAS_MAX_CLASSNAME + 1]; /* 60 bytes */
+ char attr[IAS_MAX_ATTRIBNAME + 1]; /* 60 bytes */
         __u8 *fp;
         int n;
 
@@ -1013,7 +1013,7 @@ int irias_proc_read(char *buf, char **st
                                                attrib->value->t.string);
                                 break;
                         case IAS_OCT_SEQ:
- len += sprintf(buf+len, "octet sequence\n");
+ len += sprintf(buf+len, "octet sequence (%d bytes)\n", attrib->value->len);
                                 break;
                         case IAS_MISSING:
                                 len += sprintf(buf+len, "missing\n");
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sat Sep 15 2001 - 21:00:43 EST