Commit 54d6055b authored by Jean Tourrilhes's avatar Jean Tourrilhes Committed by Linus Torvalds

[irda] init failure cleanups

		<Patch from Guennadi Liakhovetski>
	o [FEATURE] Don't leak stuff in various failure paths
	o [FEATURE] Properly initialise self->max_header_size in IrIAP
parent 349f5838
...@@ -94,6 +94,7 @@ int __init irda_device_init( void) ...@@ -94,6 +94,7 @@ int __init irda_device_init( void)
tasks = hashbin_new(HB_LOCK); tasks = hashbin_new(HB_LOCK);
if (tasks == NULL) { if (tasks == NULL) {
printk(KERN_WARNING "IrDA: Can't allocate tasks hashbin!\n"); printk(KERN_WARNING "IrDA: Can't allocate tasks hashbin!\n");
hashbin_delete(dongles, NULL);
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -100,6 +100,7 @@ int __init iriap_init(void) ...@@ -100,6 +100,7 @@ int __init iriap_init(void)
if (!irias_objects) { if (!irias_objects) {
WARNING("%s: Can't allocate irias_objects hashbin!\n", WARNING("%s: Can't allocate irias_objects hashbin!\n",
__FUNCTION__); __FUNCTION__);
hashbin_delete(iriap, NULL);
return -ENOMEM; return -ENOMEM;
} }
...@@ -182,6 +183,10 @@ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv, ...@@ -182,6 +183,10 @@ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv,
self->confirm = callback; self->confirm = callback;
self->priv = priv; self->priv = priv;
/* iriap_getvaluebyclass_request() will construct packets before
* we connect, so this must have a sane value... Jean II */
self->max_header_size = LMP_MAX_HEADER;
init_timer(&self->watchdog_timer); init_timer(&self->watchdog_timer);
hashbin_insert(iriap, (irda_queue_t *) self, (long) self, NULL); hashbin_insert(iriap, (irda_queue_t *) self, (long) self, NULL);
......
...@@ -84,8 +84,8 @@ struct ias_object *irias_new_object( char *name, int id) ...@@ -84,8 +84,8 @@ struct ias_object *irias_new_object( char *name, int id)
obj = (struct ias_object *) kmalloc(sizeof(struct ias_object), obj = (struct ias_object *) kmalloc(sizeof(struct ias_object),
GFP_ATOMIC); GFP_ATOMIC);
if (obj == NULL) { if (obj == NULL) {
IRDA_DEBUG(0, "%s(), Unable to allocate object!\n", WARNING("%s(), Unable to allocate object!\n",
__FUNCTION__); __FUNCTION__);
return NULL; return NULL;
} }
memset(obj, 0, sizeof( struct ias_object)); memset(obj, 0, sizeof( struct ias_object));
...@@ -99,6 +99,12 @@ struct ias_object *irias_new_object( char *name, int id) ...@@ -99,6 +99,12 @@ struct ias_object *irias_new_object( char *name, int id)
* while holding any attrib spinlock (risk of deadlock). Jean II */ * while holding any attrib spinlock (risk of deadlock). Jean II */
obj->attribs = hashbin_new(HB_LOCK); obj->attribs = hashbin_new(HB_LOCK);
if (obj->attribs == NULL) {
WARNING("%s(), Unable to allocate attribs!\n", __FUNCTION__);
kfree(obj);
return NULL;
}
return obj; return obj;
} }
......
...@@ -540,7 +540,13 @@ void irlap_discovery_request(struct irlap_cb *self, discovery_t *discovery) ...@@ -540,7 +540,13 @@ void irlap_discovery_request(struct irlap_cb *self, discovery_t *discovery)
} }
/* All operations will occur at predictable time, no need to lock */ /* All operations will occur at predictable time, no need to lock */
self->discovery_log= hashbin_new(HB_NOLOCK); self->discovery_log = hashbin_new(HB_NOLOCK);
if (self->discovery_log == NULL) {
WARNING("%s(), Unable to allocate discovery log!\n",
__FUNCTION__);
return;
}
info.S = discovery->nslots; /* Number of slots */ info.S = discovery->nslots; /* Number of slots */
info.s = 0; /* Current slot */ info.s = 0; /* Current slot */
......
...@@ -89,6 +89,15 @@ int __init irlmp_init(void) ...@@ -89,6 +89,15 @@ int __init irlmp_init(void)
irlmp->links = hashbin_new(HB_LOCK); irlmp->links = hashbin_new(HB_LOCK);
irlmp->unconnected_lsaps = hashbin_new(HB_LOCK); irlmp->unconnected_lsaps = hashbin_new(HB_LOCK);
irlmp->cachelog = hashbin_new(HB_NOLOCK); irlmp->cachelog = hashbin_new(HB_NOLOCK);
if ((irlmp->clients == NULL) ||
(irlmp->services == NULL) ||
(irlmp->links == NULL) ||
(irlmp->unconnected_lsaps == NULL) ||
(irlmp->cachelog == NULL)) {
return -ENOMEM;
}
spin_lock_init(&irlmp->cachelog->hb_spinlock); spin_lock_init(&irlmp->cachelog->hb_spinlock);
irlmp->free_lsap_sel = 0x10; /* Reserved 0x00-0x0f */ irlmp->free_lsap_sel = 0x10; /* Reserved 0x00-0x0f */
...@@ -287,10 +296,15 @@ void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify) ...@@ -287,10 +296,15 @@ void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify)
lap->magic = LMP_LAP_MAGIC; lap->magic = LMP_LAP_MAGIC;
lap->saddr = saddr; lap->saddr = saddr;
lap->daddr = DEV_ADDR_ANY; lap->daddr = DEV_ADDR_ANY;
lap->lsaps = hashbin_new(HB_LOCK);
#ifdef CONFIG_IRDA_CACHE_LAST_LSAP #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
lap->cache.valid = FALSE; lap->cache.valid = FALSE;
#endif #endif
lap->lsaps = hashbin_new(HB_LOCK);
if (lap->lsaps == NULL) {
WARNING("%s(), unable to kmalloc lsaps\n", __FUNCTION__);
kfree(lap);
return;
}
lap->lap_state = LAP_STANDBY; lap->lap_state = LAP_STANDBY;
......
...@@ -320,6 +320,8 @@ irnet_discover_next_daddr(irnet_socket * self) ...@@ -320,6 +320,8 @@ irnet_discover_next_daddr(irnet_socket * self)
/* Create a new IAP instance */ /* Create a new IAP instance */
self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self, self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
irnet_discovervalue_confirm); irnet_discovervalue_confirm);
if(self->iriap == NULL)
return -ENOMEM;
/* Next discovery - before the call to avoid races */ /* Next discovery - before the call to avoid races */
self->disco_index++; self->disco_index++;
...@@ -394,7 +396,8 @@ irnet_discover_daddr_and_lsap_sel(irnet_socket * self) ...@@ -394,7 +396,8 @@ irnet_discover_daddr_and_lsap_sel(irnet_socket * self)
if(ret) if(ret)
{ {
/* Close IAP */ /* Close IAP */
iriap_close(self->iriap); if(self->iriap)
iriap_close(self->iriap);
self->iriap = NULL; self->iriap = NULL;
/* Cleanup our copy of the discovery log */ /* Cleanup our copy of the discovery log */
......
...@@ -1095,7 +1095,7 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel, ...@@ -1095,7 +1095,7 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
* headers * headers
*/ */
ASSERT(skb_headroom(userdata) >= TTP_MAX_HEADER, ASSERT(skb_headroom(userdata) >= TTP_MAX_HEADER,
{ dev_kfree_skb(tx_skb); return -1; } ); { dev_kfree_skb(userdata); return -1; } );
} }
/* Initialize connection parameters */ /* Initialize connection parameters */
...@@ -1341,7 +1341,8 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, ...@@ -1341,7 +1341,8 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
* Check that the client has reserved enough space for * Check that the client has reserved enough space for
* headers * headers
*/ */
ASSERT(skb_headroom(tx_skb) >= TTP_MAX_HEADER, return -1;); ASSERT(skb_headroom(userdata) >= TTP_MAX_HEADER,
{ dev_kfree_skb(userdata); return -1; } );
} }
self->avail_credit = 0; self->avail_credit = 0;
...@@ -1363,8 +1364,8 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, ...@@ -1363,8 +1364,8 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
/* SAR enabled? */ /* SAR enabled? */
if (max_sdu_size > 0) { if (max_sdu_size > 0) {
ASSERT(skb_headroom(tx_skb) >= (TTP_MAX_HEADER+TTP_SAR_HEADER), ASSERT(skb_headroom(tx_skb) >= (TTP_MAX_HEADER + TTP_SAR_HEADER),
return -1;); { dev_kfree_skb(tx_skb); return -1; } );
/* Insert TTP header with SAR parameters */ /* Insert TTP header with SAR parameters */
frame = skb_push(tx_skb, TTP_HEADER+TTP_SAR_HEADER); frame = skb_push(tx_skb, TTP_HEADER+TTP_SAR_HEADER);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment