@@ -252,7 +252,8 @@ static inline int audit_to_inode(struct audit_krule *krule,
252
252
struct audit_field * f )
253
253
{
254
254
if (krule -> listnr != AUDIT_FILTER_EXIT ||
255
- krule -> watch || krule -> inode_f || krule -> tree )
255
+ krule -> watch || krule -> inode_f || krule -> tree ||
256
+ (f -> op != Audit_equal && f -> op != Audit_not_equal ))
256
257
return - EINVAL ;
257
258
258
259
krule -> inode_f = f ;
@@ -270,7 +271,7 @@ static int audit_to_watch(struct audit_krule *krule, char *path, int len,
270
271
271
272
if (path [0 ] != '/' || path [len - 1 ] == '/' ||
272
273
krule -> listnr != AUDIT_FILTER_EXIT ||
273
- op & ~ AUDIT_EQUAL ||
274
+ op != Audit_equal ||
274
275
krule -> inode_f || krule -> watch || krule -> tree )
275
276
return - EINVAL ;
276
277
@@ -420,12 +421,32 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
420
421
return ERR_PTR (err );
421
422
}
422
423
424
+ static u32 audit_ops [] =
425
+ {
426
+ [Audit_equal ] = AUDIT_EQUAL ,
427
+ [Audit_not_equal ] = AUDIT_NOT_EQUAL ,
428
+ [Audit_bitmask ] = AUDIT_BIT_MASK ,
429
+ [Audit_bittest ] = AUDIT_BIT_TEST ,
430
+ [Audit_lt ] = AUDIT_LESS_THAN ,
431
+ [Audit_gt ] = AUDIT_GREATER_THAN ,
432
+ [Audit_le ] = AUDIT_LESS_THAN_OR_EQUAL ,
433
+ [Audit_ge ] = AUDIT_GREATER_THAN_OR_EQUAL ,
434
+ };
435
+
436
+ static u32 audit_to_op (u32 op )
437
+ {
438
+ u32 n ;
439
+ for (n = Audit_equal ; n < Audit_bad && audit_ops [n ] != op ; n ++ )
440
+ ;
441
+ return n ;
442
+ }
443
+
444
+
423
445
/* Translate struct audit_rule to kernel's rule respresentation.
424
446
* Exists for backward compatibility with userspace. */
425
447
static struct audit_entry * audit_rule_to_entry (struct audit_rule * rule )
426
448
{
427
449
struct audit_entry * entry ;
428
- struct audit_field * ino_f ;
429
450
int err = 0 ;
430
451
int i ;
431
452
@@ -435,12 +456,28 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
435
456
436
457
for (i = 0 ; i < rule -> field_count ; i ++ ) {
437
458
struct audit_field * f = & entry -> rule .fields [i ];
459
+ u32 n ;
460
+
461
+ n = rule -> fields [i ] & (AUDIT_NEGATE |AUDIT_OPERATORS );
462
+
463
+ /* Support for legacy operators where
464
+ * AUDIT_NEGATE bit signifies != and otherwise assumes == */
465
+ if (n & AUDIT_NEGATE )
466
+ f -> op = Audit_not_equal ;
467
+ else if (!n )
468
+ f -> op = Audit_equal ;
469
+ else
470
+ f -> op = audit_to_op (n );
471
+
472
+ entry -> rule .vers_ops = (n & AUDIT_OPERATORS ) ? 2 : 1 ;
438
473
439
- f -> op = rule -> fields [i ] & (AUDIT_NEGATE |AUDIT_OPERATORS );
440
474
f -> type = rule -> fields [i ] & ~(AUDIT_NEGATE |AUDIT_OPERATORS );
441
475
f -> val = rule -> values [i ];
442
476
443
477
err = - EINVAL ;
478
+ if (f -> op == Audit_bad )
479
+ goto exit_free ;
480
+
444
481
switch (f -> type ) {
445
482
default :
446
483
goto exit_free ;
@@ -462,11 +499,8 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
462
499
case AUDIT_EXIT :
463
500
case AUDIT_SUCCESS :
464
501
/* bit ops are only useful on syscall args */
465
- if (f -> op == AUDIT_BIT_MASK ||
466
- f -> op == AUDIT_BIT_TEST ) {
467
- err = - EINVAL ;
502
+ if (f -> op == Audit_bitmask || f -> op == Audit_bittest )
468
503
goto exit_free ;
469
- }
470
504
break ;
471
505
case AUDIT_ARG0 :
472
506
case AUDIT_ARG1 :
@@ -475,11 +509,8 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
475
509
break ;
476
510
/* arch is only allowed to be = or != */
477
511
case AUDIT_ARCH :
478
- if ((f -> op != AUDIT_NOT_EQUAL ) && (f -> op != AUDIT_EQUAL )
479
- && (f -> op != AUDIT_NEGATE ) && (f -> op )) {
480
- err = - EINVAL ;
512
+ if (f -> op != Audit_not_equal && f -> op != Audit_equal )
481
513
goto exit_free ;
482
- }
483
514
entry -> rule .arch_f = f ;
484
515
break ;
485
516
case AUDIT_PERM :
@@ -496,33 +527,10 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
496
527
goto exit_free ;
497
528
break ;
498
529
}
499
-
500
- entry -> rule .vers_ops = (f -> op & AUDIT_OPERATORS ) ? 2 : 1 ;
501
-
502
- /* Support for legacy operators where
503
- * AUDIT_NEGATE bit signifies != and otherwise assumes == */
504
- if (f -> op & AUDIT_NEGATE )
505
- f -> op = AUDIT_NOT_EQUAL ;
506
- else if (!f -> op )
507
- f -> op = AUDIT_EQUAL ;
508
- else if (f -> op == AUDIT_OPERATORS ) {
509
- err = - EINVAL ;
510
- goto exit_free ;
511
- }
512
530
}
513
531
514
- ino_f = entry -> rule .inode_f ;
515
- if (ino_f ) {
516
- switch (ino_f -> op ) {
517
- case AUDIT_NOT_EQUAL :
518
- entry -> rule .inode_f = NULL ;
519
- case AUDIT_EQUAL :
520
- break ;
521
- default :
522
- err = - EINVAL ;
523
- goto exit_free ;
524
- }
525
- }
532
+ if (entry -> rule .inode_f && entry -> rule .inode_f -> op == Audit_not_equal )
533
+ entry -> rule .inode_f = NULL ;
526
534
527
535
exit_nofree :
528
536
return entry ;
@@ -538,7 +546,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
538
546
{
539
547
int err = 0 ;
540
548
struct audit_entry * entry ;
541
- struct audit_field * ino_f ;
542
549
void * bufp ;
543
550
size_t remain = datasz - sizeof (struct audit_rule_data );
544
551
int i ;
@@ -554,11 +561,11 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
554
561
struct audit_field * f = & entry -> rule .fields [i ];
555
562
556
563
err = - EINVAL ;
557
- if (!(data -> fieldflags [i ] & AUDIT_OPERATORS ) ||
558
- data -> fieldflags [i ] & ~AUDIT_OPERATORS )
564
+
565
+ f -> op = audit_to_op (data -> fieldflags [i ]);
566
+ if (f -> op == Audit_bad )
559
567
goto exit_free ;
560
568
561
- f -> op = data -> fieldflags [i ] & AUDIT_OPERATORS ;
562
569
f -> type = data -> fields [i ];
563
570
f -> val = data -> values [i ];
564
571
f -> lsm_str = NULL ;
@@ -670,18 +677,8 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
670
677
}
671
678
}
672
679
673
- ino_f = entry -> rule .inode_f ;
674
- if (ino_f ) {
675
- switch (ino_f -> op ) {
676
- case AUDIT_NOT_EQUAL :
677
- entry -> rule .inode_f = NULL ;
678
- case AUDIT_EQUAL :
679
- break ;
680
- default :
681
- err = - EINVAL ;
682
- goto exit_free ;
683
- }
684
- }
680
+ if (entry -> rule .inode_f && entry -> rule .inode_f -> op == Audit_not_equal )
681
+ entry -> rule .inode_f = NULL ;
685
682
686
683
exit_nofree :
687
684
return entry ;
@@ -721,10 +718,10 @@ static struct audit_rule *audit_krule_to_rule(struct audit_krule *krule)
721
718
rule -> fields [i ] = krule -> fields [i ].type ;
722
719
723
720
if (krule -> vers_ops == 1 ) {
724
- if (krule -> fields [i ].op & AUDIT_NOT_EQUAL )
721
+ if (krule -> fields [i ].op == Audit_not_equal )
725
722
rule -> fields [i ] |= AUDIT_NEGATE ;
726
723
} else {
727
- rule -> fields [i ] |= krule -> fields [i ].op ;
724
+ rule -> fields [i ] |= audit_ops [ krule -> fields [i ].op ] ;
728
725
}
729
726
}
730
727
for (i = 0 ; i < AUDIT_BITMASK_SIZE ; i ++ ) rule -> mask [i ] = krule -> mask [i ];
@@ -752,7 +749,7 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
752
749
struct audit_field * f = & krule -> fields [i ];
753
750
754
751
data -> fields [i ] = f -> type ;
755
- data -> fieldflags [i ] = f -> op ;
752
+ data -> fieldflags [i ] = audit_ops [ f -> op ] ;
756
753
switch (f -> type ) {
757
754
case AUDIT_SUBJ_USER :
758
755
case AUDIT_SUBJ_ROLE :
@@ -1626,28 +1623,29 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
1626
1623
return err ;
1627
1624
}
1628
1625
1629
- int audit_comparator (const u32 left , const u32 op , const u32 right )
1626
+ int audit_comparator (u32 left , u32 op , u32 right )
1630
1627
{
1631
1628
switch (op ) {
1632
- case AUDIT_EQUAL :
1629
+ case Audit_equal :
1633
1630
return (left == right );
1634
- case AUDIT_NOT_EQUAL :
1631
+ case Audit_not_equal :
1635
1632
return (left != right );
1636
- case AUDIT_LESS_THAN :
1633
+ case Audit_lt :
1637
1634
return (left < right );
1638
- case AUDIT_LESS_THAN_OR_EQUAL :
1635
+ case Audit_le :
1639
1636
return (left <= right );
1640
- case AUDIT_GREATER_THAN :
1637
+ case Audit_gt :
1641
1638
return (left > right );
1642
- case AUDIT_GREATER_THAN_OR_EQUAL :
1639
+ case Audit_ge :
1643
1640
return (left >= right );
1644
- case AUDIT_BIT_MASK :
1641
+ case Audit_bitmask :
1645
1642
return (left & right );
1646
- case AUDIT_BIT_TEST :
1643
+ case Audit_bittest :
1647
1644
return ((left & right ) == right );
1645
+ default :
1646
+ BUG ();
1647
+ return 0 ;
1648
1648
}
1649
- BUG ();
1650
- return 0 ;
1651
1649
}
1652
1650
1653
1651
/* Compare given dentry name with last component in given path,
0 commit comments