Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2b74b0a

Browse files
brookebasilegregkh
authored andcommitted
USB: gadget: f_ncm: add bounds checks to ncm_unwrap_ntb()
Some values extracted by ncm_unwrap_ntb() could possibly lead to severaldifferent out of bounds reads of memory. Specifically the values passedto netdev_alloc_skb_ip_align() need to be checked so that memory is notoverflowed.Resolve this by applying bounds checking to a number of differentindexes and lengths of the structure parsing logic.Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>Signed-off-by: Brooke Basile <brookebasile@gmail.com>Acked-by: Felipe Balbi <balbi@kernel.org>Cc: stable <stable@kernel.org>Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parentb1cd1b6 commit2b74b0a

File tree

1 file changed

+69
-12
lines changed

1 file changed

+69
-12
lines changed

‎drivers/usb/gadget/function/f_ncm.c‎

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,12 +1181,15 @@ static int ncm_unwrap_ntb(struct gether *port,
11811181
intndp_index;
11821182
unsigneddg_len,dg_len2;
11831183
unsignedndp_len;
1184+
unsignedblock_len;
11841185
structsk_buff*skb2;
11851186
intret=-EINVAL;
1186-
unsignedmax_size=le32_to_cpu(ntb_parameters.dwNtbOutMaxSize);
1187+
unsignedntb_max=le32_to_cpu(ntb_parameters.dwNtbOutMaxSize);
1188+
unsignedframe_max=le16_to_cpu(ecm_desc.wMaxSegmentSize);
11871189
conststructndp_parser_opts*opts=ncm->parser_opts;
11881190
unsignedcrc_len=ncm->is_crc ?sizeof(uint32_t) :0;
11891191
intdgram_counter;
1192+
boolndp_after_header;
11901193

11911194
/* dwSignature */
11921195
if (get_unaligned_le32(tmp)!=opts->nth_sign) {
@@ -1205,25 +1208,37 @@ static int ncm_unwrap_ntb(struct gether *port,
12051208
}
12061209
tmp++;/* skip wSequence */
12071210

1211+
block_len=get_ncm(&tmp,opts->block_length);
12081212
/* (d)wBlockLength */
1209-
if (get_ncm(&tmp,opts->block_length)>max_size) {
1213+
if (block_len>ntb_max) {
12101214
INFO(port->func.config->cdev,"OUT size exceeded\n");
12111215
gotoerr;
12121216
}
12131217

12141218
ndp_index=get_ncm(&tmp,opts->ndp_index);
1219+
ndp_after_header= false;
12151220

12161221
/* Run through all the NDP's in the NTB */
12171222
do {
1218-
/* NCM 3.2 */
1219-
if (((ndp_index %4)!=0)&&
1220-
(ndp_index<opts->nth_size)) {
1223+
/*
1224+
* NCM 3.2
1225+
* dwNdpIndex
1226+
*/
1227+
if (((ndp_index %4)!=0)||
1228+
(ndp_index<opts->nth_size)||
1229+
(ndp_index> (block_len-
1230+
opts->ndp_size))) {
12211231
INFO(port->func.config->cdev,"Bad index: %#X\n",
12221232
ndp_index);
12231233
gotoerr;
12241234
}
1235+
if (ndp_index==opts->nth_size)
1236+
ndp_after_header= true;
12251237

1226-
/* walk through NDP */
1238+
/*
1239+
* walk through NDP
1240+
* dwSignature
1241+
*/
12271242
tmp= (void*)(skb->data+ndp_index);
12281243
if (get_unaligned_le32(tmp)!=ncm->ndp_sign) {
12291244
INFO(port->func.config->cdev,"Wrong NDP SIGN\n");
@@ -1234,14 +1249,15 @@ static int ncm_unwrap_ntb(struct gether *port,
12341249
ndp_len=get_unaligned_le16(tmp++);
12351250
/*
12361251
* NCM 3.3.1
1252+
* wLength
12371253
* entry is 2 items
12381254
* item size is 16/32 bits, opts->dgram_item_len * 2 bytes
12391255
* minimal: struct usb_cdc_ncm_ndpX + normal entry + zero entry
12401256
* Each entry is a dgram index and a dgram length.
12411257
*/
12421258
if ((ndp_len<opts->ndp_size
1243-
+2*2* (opts->dgram_item_len*2))
1244-
||(ndp_len %opts->ndplen_align!=0)) {
1259+
+2*2* (opts->dgram_item_len*2))||
1260+
(ndp_len %opts->ndplen_align!=0)) {
12451261
INFO(port->func.config->cdev,"Bad NDP length: %#X\n",
12461262
ndp_len);
12471263
gotoerr;
@@ -1258,8 +1274,21 @@ static int ncm_unwrap_ntb(struct gether *port,
12581274

12591275
do {
12601276
index=index2;
1277+
/* wDatagramIndex[0] */
1278+
if ((index<opts->nth_size)||
1279+
(index>block_len-opts->dpe_size)) {
1280+
INFO(port->func.config->cdev,
1281+
"Bad index: %#X\n",index);
1282+
gotoerr;
1283+
}
1284+
12611285
dg_len=dg_len2;
1262-
if (dg_len<14+crc_len) {/* ethernet hdr + crc */
1286+
/*
1287+
* wDatagramLength[0]
1288+
* ethernet hdr + crc or larger than max frame size
1289+
*/
1290+
if ((dg_len<14+crc_len)||
1291+
(dg_len>frame_max)) {
12631292
INFO(port->func.config->cdev,
12641293
"Bad dgram length: %#X\n",dg_len);
12651294
gotoerr;
@@ -1283,6 +1312,37 @@ static int ncm_unwrap_ntb(struct gether *port,
12831312
index2=get_ncm(&tmp,opts->dgram_item_len);
12841313
dg_len2=get_ncm(&tmp,opts->dgram_item_len);
12851314

1315+
if (index2==0||dg_len2==0)
1316+
break;
1317+
1318+
/* wDatagramIndex[1] */
1319+
if (ndp_after_header) {
1320+
if (index2<opts->nth_size+opts->ndp_size) {
1321+
INFO(port->func.config->cdev,
1322+
"Bad index: %#X\n",index2);
1323+
gotoerr;
1324+
}
1325+
}else {
1326+
if (index2<opts->nth_size+opts->dpe_size) {
1327+
INFO(port->func.config->cdev,
1328+
"Bad index: %#X\n",index2);
1329+
gotoerr;
1330+
}
1331+
}
1332+
if (index2>block_len-opts->dpe_size) {
1333+
INFO(port->func.config->cdev,
1334+
"Bad index: %#X\n",index2);
1335+
gotoerr;
1336+
}
1337+
1338+
/* wDatagramLength[1] */
1339+
if ((dg_len2<14+crc_len)||
1340+
(dg_len2>frame_max)) {
1341+
INFO(port->func.config->cdev,
1342+
"Bad dgram length: %#X\n",dg_len);
1343+
gotoerr;
1344+
}
1345+
12861346
/*
12871347
* Copy the data into a new skb.
12881348
* This ensures the truesize is correct
@@ -1299,9 +1359,6 @@ static int ncm_unwrap_ntb(struct gether *port,
12991359
ndp_len-=2* (opts->dgram_item_len*2);
13001360

13011361
dgram_counter++;
1302-
1303-
if (index2==0||dg_len2==0)
1304-
break;
13051362
}while (ndp_len>2* (opts->dgram_item_len*2));
13061363
}while (ndp_index);
13071364

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp