@@ -1340,6 +1340,53 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
13401340 from_kuid (& init_user_ns , name -> fcap .rootid ));
13411341}
13421342
1343+ static void audit_log_time (struct audit_context * context , struct audit_buffer * * ab )
1344+ {
1345+ const struct audit_ntp_data * ntp = & context -> time .ntp_data ;
1346+ const struct timespec64 * tk = & context -> time .tk_injoffset ;
1347+ static const char * const ntp_name [] = {
1348+ "offset" ,
1349+ "freq" ,
1350+ "status" ,
1351+ "tai" ,
1352+ "tick" ,
1353+ "adjust" ,
1354+ };
1355+ int type ;
1356+
1357+ if (context -> type == AUDIT_TIME_ADJNTPVAL ) {
1358+ for (type = 0 ; type < AUDIT_NTP_NVALS ; type ++ ) {
1359+ if (ntp -> vals [type ].newval != ntp -> vals [type ].oldval ) {
1360+ if (!* ab ) {
1361+ * ab = audit_log_start (context ,
1362+ GFP_KERNEL ,
1363+ AUDIT_TIME_ADJNTPVAL );
1364+ if (!* ab )
1365+ return ;
1366+ }
1367+ audit_log_format (* ab , "op=%s old=%lli new=%lli" ,
1368+ ntp_name [type ],
1369+ ntp -> vals [type ].oldval ,
1370+ ntp -> vals [type ].newval );
1371+ audit_log_end (* ab );
1372+ * ab = NULL ;
1373+ }
1374+ }
1375+ }
1376+ if (tk -> tv_sec != 0 || tk -> tv_nsec != 0 ) {
1377+ if (!* ab ) {
1378+ * ab = audit_log_start (context , GFP_KERNEL ,
1379+ AUDIT_TIME_INJOFFSET );
1380+ if (!* ab )
1381+ return ;
1382+ }
1383+ audit_log_format (* ab , "sec=%lli nsec=%li" ,
1384+ (long long )tk -> tv_sec , tk -> tv_nsec );
1385+ audit_log_end (* ab );
1386+ * ab = NULL ;
1387+ }
1388+ }
1389+
13431390static void show_special (struct audit_context * context , int * call_panic )
13441391{
13451392 struct audit_buffer * ab ;
@@ -1454,6 +1501,11 @@ static void show_special(struct audit_context *context, int *call_panic)
14541501 audit_log_format (ab , "(null)" );
14551502
14561503 break ;
1504+ case AUDIT_TIME_ADJNTPVAL :
1505+ case AUDIT_TIME_INJOFFSET :
1506+ /* this call deviates from the rest, eating the buffer */
1507+ audit_log_time (context , & ab );
1508+ break ;
14571509 }
14581510 audit_log_end (ab );
14591511}
@@ -2849,31 +2901,26 @@ void __audit_fanotify(unsigned int response)
28492901
28502902void __audit_tk_injoffset (struct timespec64 offset )
28512903{
2852- audit_log (audit_context (), GFP_KERNEL , AUDIT_TIME_INJOFFSET ,
2853- "sec=%lli nsec=%li" ,
2854- (long long )offset .tv_sec , offset .tv_nsec );
2855- }
2856-
2857- static void audit_log_ntp_val (const struct audit_ntp_data * ad ,
2858- const char * op , enum audit_ntp_type type )
2859- {
2860- const struct audit_ntp_val * val = & ad -> vals [type ];
2861-
2862- if (val -> newval == val -> oldval )
2863- return ;
2904+ struct audit_context * context = audit_context ();
28642905
2865- audit_log (audit_context (), GFP_KERNEL , AUDIT_TIME_ADJNTPVAL ,
2866- "op=%s old=%lli new=%lli" , op , val -> oldval , val -> newval );
2906+ /* only set type if not already set by NTP */
2907+ if (!context -> type )
2908+ context -> type = AUDIT_TIME_INJOFFSET ;
2909+ memcpy (& context -> time .tk_injoffset , & offset , sizeof (offset ));
28672910}
28682911
28692912void __audit_ntp_log (const struct audit_ntp_data * ad )
28702913{
2871- audit_log_ntp_val (ad , "offset" , AUDIT_NTP_OFFSET );
2872- audit_log_ntp_val (ad , "freq" , AUDIT_NTP_FREQ );
2873- audit_log_ntp_val (ad , "status" , AUDIT_NTP_STATUS );
2874- audit_log_ntp_val (ad , "tai" , AUDIT_NTP_TAI );
2875- audit_log_ntp_val (ad , "tick" , AUDIT_NTP_TICK );
2876- audit_log_ntp_val (ad , "adjust" , AUDIT_NTP_ADJUST );
2914+ struct audit_context * context = audit_context ();
2915+ int type ;
2916+
2917+ for (type = 0 ; type < AUDIT_NTP_NVALS ; type ++ )
2918+ if (ad -> vals [type ].newval != ad -> vals [type ].oldval ) {
2919+ /* unconditionally set type, overwriting TK */
2920+ context -> type = AUDIT_TIME_ADJNTPVAL ;
2921+ memcpy (& context -> time .ntp_data , ad , sizeof (* ad ));
2922+ break ;
2923+ }
28772924}
28782925
28792926void __audit_log_nfcfg (const char * name , u8 af , unsigned int nentries ,
0 commit comments