@@ -1101,13 +1101,11 @@ static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature
1101
1101
audit_log_end (ab );
1102
1102
}
1103
1103
1104
- static int audit_set_feature (struct sk_buff * skb )
1104
+ static int audit_set_feature (struct audit_features * uaf )
1105
1105
{
1106
- struct audit_features * uaf ;
1107
1106
int i ;
1108
1107
1109
1108
BUILD_BUG_ON (AUDIT_LAST_FEATURE + 1 > ARRAY_SIZE (audit_feature_names ));
1110
- uaf = nlmsg_data (nlmsg_hdr (skb ));
1111
1109
1112
1110
/* if there is ever a version 2 we should handle that here */
1113
1111
@@ -1175,6 +1173,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1175
1173
{
1176
1174
u32 seq ;
1177
1175
void * data ;
1176
+ int data_len ;
1178
1177
int err ;
1179
1178
struct audit_buffer * ab ;
1180
1179
u16 msg_type = nlh -> nlmsg_type ;
@@ -1188,6 +1187,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1188
1187
1189
1188
seq = nlh -> nlmsg_seq ;
1190
1189
data = nlmsg_data (nlh );
1190
+ data_len = nlmsg_len (nlh );
1191
1191
1192
1192
switch (msg_type ) {
1193
1193
case AUDIT_GET : {
@@ -1211,7 +1211,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1211
1211
struct audit_status s ;
1212
1212
memset (& s , 0 , sizeof (s ));
1213
1213
/* guard against past and future API changes */
1214
- memcpy (& s , data , min_t (size_t , sizeof (s ), nlmsg_len ( nlh ) ));
1214
+ memcpy (& s , data , min_t (size_t , sizeof (s ), data_len ));
1215
1215
if (s .mask & AUDIT_STATUS_ENABLED ) {
1216
1216
err = audit_set_enabled (s .enabled );
1217
1217
if (err < 0 )
@@ -1315,7 +1315,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1315
1315
return err ;
1316
1316
break ;
1317
1317
case AUDIT_SET_FEATURE :
1318
- err = audit_set_feature (skb );
1318
+ if (data_len < sizeof (struct audit_features ))
1319
+ return - EINVAL ;
1320
+ err = audit_set_feature (data );
1319
1321
if (err )
1320
1322
return err ;
1321
1323
break ;
@@ -1327,33 +1329,33 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1327
1329
1328
1330
err = audit_filter (msg_type , AUDIT_FILTER_USER );
1329
1331
if (err == 1 ) { /* match or error */
1332
+ char * str = data ;
1333
+
1330
1334
err = 0 ;
1331
1335
if (msg_type == AUDIT_USER_TTY ) {
1332
1336
err = tty_audit_push ();
1333
1337
if (err )
1334
1338
break ;
1335
1339
}
1336
1340
audit_log_user_recv_msg (& ab , msg_type );
1337
- if (msg_type != AUDIT_USER_TTY )
1341
+ if (msg_type != AUDIT_USER_TTY ) {
1342
+ /* ensure NULL termination */
1343
+ str [data_len - 1 ] = '\0' ;
1338
1344
audit_log_format (ab , " msg='%.*s'" ,
1339
1345
AUDIT_MESSAGE_TEXT_MAX ,
1340
- (char * )data );
1341
- else {
1342
- int size ;
1343
-
1346
+ str );
1347
+ } else {
1344
1348
audit_log_format (ab , " data=" );
1345
- size = nlmsg_len (nlh );
1346
- if (size > 0 &&
1347
- ((unsigned char * )data )[size - 1 ] == '\0' )
1348
- size -- ;
1349
- audit_log_n_untrustedstring (ab , data , size );
1349
+ if (data_len > 0 && str [data_len - 1 ] == '\0' )
1350
+ data_len -- ;
1351
+ audit_log_n_untrustedstring (ab , str , data_len );
1350
1352
}
1351
1353
audit_log_end (ab );
1352
1354
}
1353
1355
break ;
1354
1356
case AUDIT_ADD_RULE :
1355
1357
case AUDIT_DEL_RULE :
1356
- if (nlmsg_len ( nlh ) < sizeof (struct audit_rule_data ))
1358
+ if (data_len < sizeof (struct audit_rule_data ))
1357
1359
return - EINVAL ;
1358
1360
if (audit_enabled == AUDIT_LOCKED ) {
1359
1361
audit_log_common_recv_msg (audit_context (), & ab ,
@@ -1365,7 +1367,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1365
1367
audit_log_end (ab );
1366
1368
return - EPERM ;
1367
1369
}
1368
- err = audit_rule_change (msg_type , seq , data , nlmsg_len ( nlh ) );
1370
+ err = audit_rule_change (msg_type , seq , data , data_len );
1369
1371
break ;
1370
1372
case AUDIT_LIST_RULES :
1371
1373
err = audit_list_rules_send (skb , seq );
@@ -1380,7 +1382,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1380
1382
case AUDIT_MAKE_EQUIV : {
1381
1383
void * bufp = data ;
1382
1384
u32 sizes [2 ];
1383
- size_t msglen = nlmsg_len ( nlh ) ;
1385
+ size_t msglen = data_len ;
1384
1386
char * old , * new ;
1385
1387
1386
1388
err = - EINVAL ;
@@ -1456,7 +1458,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1456
1458
1457
1459
memset (& s , 0 , sizeof (s ));
1458
1460
/* guard against past and future API changes */
1459
- memcpy (& s , data , min_t (size_t , sizeof (s ), nlmsg_len ( nlh ) ));
1461
+ memcpy (& s , data , min_t (size_t , sizeof (s ), data_len ));
1460
1462
/* check if new data is valid */
1461
1463
if ((s .enabled != 0 && s .enabled != 1 ) ||
1462
1464
(s .log_passwd != 0 && s .log_passwd != 1 ))
0 commit comments