On Tuesday, January 3, 2017 at 6:16:56 AM UTC+8, Paul Moore wrote: > On Sun, Jan 1, 2017 at 8:53 AM, An Xiao <xxx> wrote: > > Hi all, > > I'd like to forbid evil(or unexpected) application behaviour by limiting > > the arguments of system calls. Seems libseccomp could help me to do this. > > However, libseccomp did not work as I expected. For instance, I tried to > > prevent programs from writing something into any file except for STDOUT and > > STDERR, and then I had to forbid the syscall 'write' unless its first > > argument was equal to '1' or '2', I supposed. > > To implement this, I tried two ways to add seccomp filter rules: > > > > --- > > > > 1. > > scmp_filter_ctx ctx; > > ctx = seccomp_init(SCMP_ACT_KILL); > > seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 2, > > SCMP_A0(SCMP_CMP_LE, 2), > > SCMP_A0(SCMP_CMP_GE, 1) > > ); > > ... > > write(2, buf, sizeof(buf)); > > > > 2. > > scmp_filter_ctx ctx; > > ctx = seccomp_init(SCMP_ACT_KILL); > > seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, > > SCMP_A0(SCMP_CMP_LE, 2) > > ); > > seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, > > SCMP_A0(SCMP_CMP_GE, 1) > > ); > > ... > > write(2, buf, sizeof(buf)); > > > > --- > > > > The formmer did not work because the syscall 'write' was still > > forbidden. WHY? > > > > The latter seemed to be working fine that the content of buffer was > > written to STDERR successfully. However, I found 'write' would not be > > forbidden though we change the first argument from 2 to 3 or even larger. I > > guess this problem arose because the relationship between those two rules > > is OR instead of AND. Any file descriptor >= 1 or <= 2 is accepted, in > > other way, a file descriptor with any value is accepted. I was wondering, > > is there any way to set seccomp filter rules, so that a syscall is allowed > > only when both rules are satisfied. > > Hello, > > With respect to your example in #1, please try it again and check the > return value from seccomp_rule_add(); I think you will find there to > be an error. It is recommended to always check the return value for > any libseccomp functions that return a value. > > As far as your second example is concerned, you created filters that > allow write() to write to file descriptors that are less than or equal > to 2 (SCMP_A0(SCMP_CMP_LE, 2)) as well as file descriptors that > greater than or equal to 1 (SCMP_A0(SCMP_CMP_GE, 1)); the union of > these two conditions is *all* file descriptor values. If you want to > limit write to only STDOUT and STDERR I would suggest something like > the following: > > rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, > SCMP_A0(SCMP_CMP_EQ,1)); > ... > rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, > SCMP_A0(SCMP_CMP_EQ,2)); > ... > > Good luck! > > -- > paul moore > www.paul-moore.com
Thanks for your reply! I checked my first example, and it did return -22(-EINVAL). Sorry for my carelessness. I found this error event was emitted when the program checked `chain[arg_num].valid == 0` in `db_col_rule_add()`. So, Is that mean we can never set two or more rules for one argument at the same time? As for my second example, your suggestion is perfect in that case. But I want much more. I'm desirous to limit multiple arguments of one syscall, so that the syscall is allowed only when all of its arguments are legal(logical AND). However, the current situation is that, the syscall will be accepted if any of the rules is satisfied(logical OR). I wonder if `seccomp` does not support logical AND natively. Seems that all rules of one syscall is added to a chain, and seccomp checks those rules one by one at runtime, stops when one rule is satisfied. -- You received this message because you are subscribed to the Google Groups "libseccomp" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
