@@ -1101,13 +1101,11 @@ static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature
11011101 audit_log_end (ab );
11021102}
11031103
1104- static int audit_set_feature (struct sk_buff * skb )
1104+ static int audit_set_feature (struct audit_features * uaf )
11051105{
1106- struct audit_features * uaf ;
11071106 int i ;
11081107
11091108 BUILD_BUG_ON (AUDIT_LAST_FEATURE + 1 > ARRAY_SIZE (audit_feature_names ));
1110- uaf = nlmsg_data (nlmsg_hdr (skb ));
11111109
11121110 /* if there is ever a version 2 we should handle that here */
11131111
@@ -1175,6 +1173,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
11751173{
11761174 u32 seq ;
11771175 void * data ;
1176+ int data_len ;
11781177 int err ;
11791178 struct audit_buffer * ab ;
11801179 u16 msg_type = nlh -> nlmsg_type ;
@@ -1188,6 +1187,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
11881187
11891188 seq = nlh -> nlmsg_seq ;
11901189 data = nlmsg_data (nlh );
1190+ data_len = nlmsg_len (nlh );
11911191
11921192 switch (msg_type ) {
11931193 case AUDIT_GET : {
@@ -1211,7 +1211,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
12111211 struct audit_status s ;
12121212 memset (& s , 0 , sizeof (s ));
12131213 /* 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 ));
12151215 if (s .mask & AUDIT_STATUS_ENABLED ) {
12161216 err = audit_set_enabled (s .enabled );
12171217 if (err < 0 )
@@ -1315,7 +1315,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
13151315 return err ;
13161316 break ;
13171317 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 );
13191321 if (err )
13201322 return err ;
13211323 break ;
@@ -1327,33 +1329,33 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
13271329
13281330 err = audit_filter (msg_type , AUDIT_FILTER_USER );
13291331 if (err == 1 ) { /* match or error */
1332+ char * str = data ;
1333+
13301334 err = 0 ;
13311335 if (msg_type == AUDIT_USER_TTY ) {
13321336 err = tty_audit_push ();
13331337 if (err )
13341338 break ;
13351339 }
13361340 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' ;
13381344 audit_log_format (ab , " msg='%.*s'" ,
13391345 AUDIT_MESSAGE_TEXT_MAX ,
1340- (char * )data );
1341- else {
1342- int size ;
1343-
1346+ str );
1347+ } else {
13441348 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 );
13501352 }
13511353 audit_log_end (ab );
13521354 }
13531355 break ;
13541356 case AUDIT_ADD_RULE :
13551357 case AUDIT_DEL_RULE :
1356- if (nlmsg_len ( nlh ) < sizeof (struct audit_rule_data ))
1358+ if (data_len < sizeof (struct audit_rule_data ))
13571359 return - EINVAL ;
13581360 if (audit_enabled == AUDIT_LOCKED ) {
13591361 audit_log_common_recv_msg (audit_context (), & ab ,
@@ -1365,7 +1367,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
13651367 audit_log_end (ab );
13661368 return - EPERM ;
13671369 }
1368- err = audit_rule_change (msg_type , seq , data , nlmsg_len ( nlh ) );
1370+ err = audit_rule_change (msg_type , seq , data , data_len );
13691371 break ;
13701372 case AUDIT_LIST_RULES :
13711373 err = audit_list_rules_send (skb , seq );
@@ -1380,7 +1382,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
13801382 case AUDIT_MAKE_EQUIV : {
13811383 void * bufp = data ;
13821384 u32 sizes [2 ];
1383- size_t msglen = nlmsg_len ( nlh ) ;
1385+ size_t msglen = data_len ;
13841386 char * old , * new ;
13851387
13861388 err = - EINVAL ;
@@ -1456,7 +1458,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
14561458
14571459 memset (& s , 0 , sizeof (s ));
14581460 /* 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 ));
14601462 /* check if new data is valid */
14611463 if ((s .enabled != 0 && s .enabled != 1 ) ||
14621464 (s .log_passwd != 0 && s .log_passwd != 1 ))
0 commit comments