isdn: mISDN: correctly handle ph_info allocation failure in hfcsusb_ph_info
Modify return type of hfcusb_ph_info to int, so that we can pass error
value up the call stack when allocation of ph_info fails. Also change
three of four call sites to actually account for the memory failure.
The fourth, in ph_state_nt, is infeasible to change as it is in turn
called by ph_state which is used as a function pointer argument to
mISDN_initdchannel, which would necessitate changing its signature
and updating all the places where it is used (too many).
Fixes original flawed commit (38d2265980
) from the University of
Minnesota.
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Phillip Potter <phil@philpotter.co.uk>
Link: https://lore.kernel.org/r/20210503115736.2104747-48-gregkh@linuxfoundation.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
36a2c87f7e
Коммит
5265db2ccc
|
@ -46,7 +46,7 @@ static void hfcsusb_start_endpoint(struct hfcsusb *hw, int channel);
|
||||||
static void hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel);
|
static void hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel);
|
||||||
static int hfcsusb_setup_bch(struct bchannel *bch, int protocol);
|
static int hfcsusb_setup_bch(struct bchannel *bch, int protocol);
|
||||||
static void deactivate_bchannel(struct bchannel *bch);
|
static void deactivate_bchannel(struct bchannel *bch);
|
||||||
static void hfcsusb_ph_info(struct hfcsusb *hw);
|
static int hfcsusb_ph_info(struct hfcsusb *hw);
|
||||||
|
|
||||||
/* start next background transfer for control channel */
|
/* start next background transfer for control channel */
|
||||||
static void
|
static void
|
||||||
|
@ -241,7 +241,7 @@ hfcusb_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
|
||||||
* send full D/B channel status information
|
* send full D/B channel status information
|
||||||
* as MPH_INFORMATION_IND
|
* as MPH_INFORMATION_IND
|
||||||
*/
|
*/
|
||||||
static void
|
static int
|
||||||
hfcsusb_ph_info(struct hfcsusb *hw)
|
hfcsusb_ph_info(struct hfcsusb *hw)
|
||||||
{
|
{
|
||||||
struct ph_info *phi;
|
struct ph_info *phi;
|
||||||
|
@ -249,6 +249,9 @@ hfcsusb_ph_info(struct hfcsusb *hw)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
phi = kzalloc(struct_size(phi, bch, dch->dev.nrbchan), GFP_ATOMIC);
|
phi = kzalloc(struct_size(phi, bch, dch->dev.nrbchan), GFP_ATOMIC);
|
||||||
|
if (!phi)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
phi->dch.ch.protocol = hw->protocol;
|
phi->dch.ch.protocol = hw->protocol;
|
||||||
phi->dch.ch.Flags = dch->Flags;
|
phi->dch.ch.Flags = dch->Flags;
|
||||||
phi->dch.state = dch->state;
|
phi->dch.state = dch->state;
|
||||||
|
@ -260,6 +263,8 @@ hfcsusb_ph_info(struct hfcsusb *hw)
|
||||||
_queue_data(&dch->dev.D, MPH_INFORMATION_IND, MISDN_ID_ANY,
|
_queue_data(&dch->dev.D, MPH_INFORMATION_IND, MISDN_ID_ANY,
|
||||||
struct_size(phi, bch, dch->dev.nrbchan), phi, GFP_ATOMIC);
|
struct_size(phi, bch, dch->dev.nrbchan), phi, GFP_ATOMIC);
|
||||||
kfree(phi);
|
kfree(phi);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -344,8 +349,7 @@ hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
|
||||||
ret = l1_event(dch->l1, hh->prim);
|
ret = l1_event(dch->l1, hh->prim);
|
||||||
break;
|
break;
|
||||||
case MPH_INFORMATION_REQ:
|
case MPH_INFORMATION_REQ:
|
||||||
hfcsusb_ph_info(hw);
|
ret = hfcsusb_ph_info(hw);
|
||||||
ret = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,8 +404,7 @@ hfc_l1callback(struct dchannel *dch, u_int cmd)
|
||||||
hw->name, __func__, cmd);
|
hw->name, __func__, cmd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
hfcsusb_ph_info(hw);
|
return hfcsusb_ph_info(hw);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -743,8 +746,7 @@ hfcsusb_setup_bch(struct bchannel *bch, int protocol)
|
||||||
handle_led(hw, (bch->nr == 1) ? LED_B1_OFF :
|
handle_led(hw, (bch->nr == 1) ? LED_B1_OFF :
|
||||||
LED_B2_OFF);
|
LED_B2_OFF);
|
||||||
}
|
}
|
||||||
hfcsusb_ph_info(hw);
|
return hfcsusb_ph_info(hw);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Загрузка…
Ссылка в новой задаче