Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFE: distinguish unknown syscalls #286

Open
srd424 opened this issue Aug 16, 2020 · 18 comments
Open

RFE: distinguish unknown syscalls #286

srd424 opened this issue Aug 16, 2020 · 18 comments

Comments

@srd424
Copy link

srd424 commented Aug 16, 2020

Triggered by a discussion (in June & Aug) on systemd-devel ..

systemd-nspawn chooses to return EPERM for non-whitelisted syscalls. However, this causes problems in cases like openat2, where libc checks for ENOSYS and falls back to a different implementation.

It seems to me a 'mostly right' solution could be to check if the syscall number falls within the range of defined syscalls that existed at the time seccomp was built. I'm sure there are corner cases (I know some archs do weird things), but if the tools that parse syscalls.csv etc could generate a simple #define for the max known syscall number that might be useful?

@pcmoore
Copy link
Member

pcmoore commented Aug 16, 2020

Hi @srd424. I want to make sure I understand what you are asking for in this issue ... it sounds to me that you would basically like to know if libseccomp "knows" about a given syscall, regardless of if that particular syscall is implemented on that arch/ABI, yes?

If so, I believe you should be able to use seccomp_syscall_resolve_name(...) to get the information you want. If the return value is __NR_SCMP_ERROR then the syscall is unknown to libseccomp, if it is positive then the syscall exists in the native arch/ABI, and if it is negative then the syscall does not exist on the native arch/ABI. Does that work for you?

@srd424
Copy link
Author

srd424 commented Aug 16, 2020

That might make the filters .. long-winded!

What I was hoping to do is to to have a filter rule compare the syscall number to the highest known, and if greater, return ENOSYS, otherwise return EPERM (Assuming that whitelisted syscalls have been handled by an earlier rule.)

However looking at the details for seccomp_rule_add, I'm not sure that is going to work .. the syscall number is treated specially. A raw bpf filter could presumably be constructed to do this, but that's going to mean some more invasive changes to libseccomp - probably above my pay grade!

@srd424
Copy link
Author

srd424 commented Aug 16, 2020

It might or might not be reasonable functionality to add to libseccomp as I guess the original problem may occur for multiple users of the library. It looks like it would (just?) be a question of generating a slightly more sophisticated default action..

@pcmoore
Copy link
Member

pcmoore commented Aug 17, 2020

That might make the filters .. long-winded!

I'm not quite sure what you mean here ... ? The call to seccomp_syscall_resolve_name(...) doesn't actually affect the filter, it just queries the internal libseccomp syscall db to do the syscall resolution. You can call it once, one thousand times, or never and your filter will be exactly the same :)

What I was hoping to do is to to have a filter rule compare the syscall number to the highest known, and if greater, return ENOSYS, otherwise return EPERM (Assuming that whitelisted syscalls have been handled by an earlier rule.)

Okay, I think I'm beginning to understand what you are asking for now. You want the filter itself, not the application code, to take a certain action (return ENOSYS in the example above) if the syscall is unknow to libseccomp? Is that basically it, or am I missing something again?

@drakenclimber
Copy link
Member

This comment in the second thread mentioned above made me smile 👍

I've tried to open a discussion about the ENOSYS handling in libseccomp at
#286, but I'm probably not
being very coherent..

After reading through the threads you mentioned, I think I'm on the same page.

If someone (libseccomp, nspawn, whoever) could return ENOSYS, then glibc will try to fallback from the newer syscall, e.g. openat2, to the older syscall, e.g. openat. Returning EPERM to glibc just makes glibc think that the call was not allowed, and glibc will give up. Is that a fair rewording of the initial comment in this issue?

I think the request is reasonable. I need to think some more if libseccomp can meet these needs, but I have no objections at this point. There are definitely opportunities to improve the end-user experience here.

Thanks for the RFE.

@srd424
Copy link
Author

srd424 commented Aug 17, 2020

If someone (libseccomp, nspawn, whoever) could return ENOSYS, then glibc will try to fallback from the newer syscall, e.g. openat2, to the older syscall, e.g. openat. Returning EPERM to glibc just makes glibc think that the call was not allowed, and glibc will give up. Is that a fair rewording of the initial comment in this issue?

Yes, that sounds right. The opinion of the systemd folks is that EPERM is reasonable most of time for denylisted syscalls, presumably as it conveys "not allowed" to end user / admin. Hence the idea to distinguish between "new" and "old" syscalls and do ENOSYS for anything unrecognised. I assume we don't want to enumerate and test every single syscall in the BPF for performance reasons, so tracking a high water mark for the known syscall numbers per-arch seemed like a "best effort" way to go.

Would be interesting to know what docker, podman, lxc etc. do with their seccomp filtering, to see if they would benefit. In the meantime I've PR'd a patch for nspawn that would allow logging of seccomp events, that would make debugging a little easier.

@srd424 srd424 changed the title RFE/RFD: expose supported syscall number range(s)? RFE/RFD: distinguish unknown new syscalls and return ENOSYS Aug 17, 2020
@pcmoore pcmoore removed the question label Aug 18, 2020
@pcmoore pcmoore changed the title RFE/RFD: distinguish unknown new syscalls and return ENOSYS RFE: distinguish unknown syscalls Aug 18, 2020
@pcmoore
Copy link
Member

pcmoore commented Aug 18, 2020

I think the request is reasonable. I need to think some more if libseccomp can meet these needs, but I have no objections at this point. There are definitely opportunities to improve the end-user experience here.

Thanks for the RFE.

I agree with @drakenclimber, this request sounds reasonable, I think I just need some more time to think about possible solutions :)

At a pretty basic level, this is similar to RFE #11, and in the end that may be the easiest way to implement this in a way that isn't terrible for applications: an application can specify a maximum supported kernel API version, e.g. v5.8 (obviously tokenized), as well as a given action for anything beyond and then libseccomp handles the rest. Would that work for you guys @srd424?

@keszybz
Copy link

keszybz commented Aug 19, 2020

Hi, this was discussed also in systemd/systemd#16739.

an application can specify a maximum supported kernel API version, e.g. v5.8 (obviously tokenized), as well as a given action for anything beyond and then libseccomp handles the rest.

This would work great. In systemd/systemd-nspawn we'd want to return custom errnos for any explicitly allow-listed and deny-listed syscalls, EPERM for any others in the "supported kernel API version", and ENOSYS for any new ones.

I think the implementation wouldn't be too complicated. For example for amd64, "known" syscalls can be expressed as n <= 181 || 186 <= n <= 235 || 237 <= n <= 334 || 424 <= n <= 439. And such expressions can be easily generated programatically from the syscall tables.

@topimiettinen
Copy link

#94 could be related too.

@srd424
Copy link
Author

srd424 commented Aug 19, 2020

I'm under-caffeinated this morning, but would having the ENOSYS handling then give us the possibility to turn large allowlists into small denylists for a possible performance win as well?

@pcmoore pcmoore added this to the v2.6.0 milestone Aug 19, 2020
@pcmoore
Copy link
Member

pcmoore commented Aug 19, 2020

I think the implementation wouldn't be too complicated. For example for amd64, "known" syscalls can be expressed as n <= 181 || 186 <= n <= 235 || 237 <= n <= 334 || 424 <= n <= 439. And such expressions can be easily generated programatically from the syscall tables.

As you allude to, the actual BPF is going to be both arch/ABI and kernel version specific. In the x86_64 example above the BPF isn't going to be too bad, but we not be that lucky for other arches/versions. Regardless, this is now two issue that are effectively requesting the same thing so I think it's something we will want to do ... I'm just not going to start jumping up and down about how easy it is going to be just yet ;)

#94 could be related too.

Sort of yes, sort of no. It involves ranges, but #94 is about caller specified argument ranges (which is still something I think we want to do, the PR just came in at a bad time and I think the API needs some tweaking) whereas what we are talking about are implicitly created syscall ranges which are generated by the library itself.

I'm under-caffeinated this morning, but would having the ENOSYS handling then give us the possibility to turn large allowlists into small denylists for a possible performance win as well?

From an application perspective, e.g. systemd, if you are trying to block "new" syscalls then yes ... assuming we're talking about the same thing :)

@srd424
Copy link
Author

srd424 commented Aug 19, 2020

To be more specific .. at the moment anyone trying to securely block certain syscalls effectively has to allowlist, because you can't be sure what syscalls a newer kernel might add. If we can request libseccomp to automatically block unknown syscalls, that means we can safely switch to a small denylist instead?

@drakenclimber
Copy link
Member

To be more specific .. at the moment anyone trying to securely block certain syscalls effectively has to allowlist, because you can't be sure what syscalls a newer kernel might add. If we can request libseccomp to automatically block unknown syscalls, that means we can safely switch to a small denylist instead?

I sincerely hope we can get there, as that would be an absolutely awesome feature. For example, Docker is currently employing an allowlist and their default list is now ~240 syscalls (and always growing).

The performance impact of such a large list can be prohibitive. Note that it can be somewhat mitigated by using the binary tree feature we added in v2.5.

@fweimer
Copy link

fweimer commented Aug 21, 2020

To be more specific .. at the moment anyone trying to securely block certain syscalls effectively has to allowlist, because you can't be sure what syscalls a newer kernel might add. If we can request libseccomp to automatically block unknown syscalls, that means we can safely switch to a small denylist instead?

I don't see how this could work. Unknown to libseccomp and unknown to the denylist author will usually mean different things. Which means that the conceptual issue won't go away even if libseccomp has a clearer picture of the supported system calls internally.

@srd424
Copy link
Author

srd424 commented Aug 21, 2020

Good point - I guess we'd need well defined sets tagged by kernel version for that to work, which does seem to be being discussed a bit.

@keszybz
Copy link

keszybz commented Aug 22, 2020

I think the implementation wouldn't be too complicated. For example for amd64, "known" syscalls can be expressed as n <= 181 || 186 <= n <= 235 || 237 <= n <= 334 || 424 <= n <= 439. And such expressions can be easily generated programatically from the syscall tables.

As you allude to, the actual BPF is going to be both arch/ABI and kernel version specific. In the x86_64 example above the BPF isn't going to be too bad, but we not be that lucky for other arches/versions. Regardless, this is now two issue that are effectively requesting the same thing so I think it's something we will want to do ... I'm just not going to start jumping up and down about how easy it is going to be just yet ;)

The tables are fairly continuous:

>>> l = {int(s[1]):s[0] for s in (s.split() for s in open('syscalls-x86_64').readlines()) if len(s)>1}; x = np.array(sorted(l.keys())); np.diff(x)
array([ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  5,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1, 90,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1])
>>> l = {int(s[1]):s[0] for s in (s.split() for s in open('syscalls-alpha').readlines()) if len(s)>1}; x = np.array(sorted(l.keys())); np.diff(x)
array([ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  3,  1,  2,  1,  1,
        1,  1,  1,  2,  1,  1,  1,  3, 12,  3,  3,  1, 11,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        2,  1,  1,  1,  1,  1,  1,  5,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1, 39,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  1,  1,  1,  1,  3,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        2,  1,  1,  1])
>>> l = {int(s[1]):s[0] for s in (s.split() for s in open('syscalls-arm').readlines()) if len(s)>1}; x = np.array(sorted(l.keys())); np.diff(x)
array([1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 3, 1, 1, 2, 1, 2, 3, 4,
       1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 2, 3, 1, 1,
       1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 3,
       1, 1, 1, 1, 1, 1, 2, 1, 3, 1, 1, 1, 1, 1, 3, 3, 1, 1, 2, 1, 1, 1,
       1, 2, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
>>> l = {int(s[1]):s[0] for s in (s.split() for s in open('syscalls-riscv64').readlines()) if len(s)>1}; x = np.array(sorted(l.keys())); np.diff(x)
array([  1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   2,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,  16,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1, 130,   1,   1,   1,   1,   1,   1,   1,
         1,   1,   1,   1,   1,   1,   1,   1])

I implemented a filter of "known" syscalls for systemd-nspawn in systemd/systemd#16819. systemd/systemd@158e30f has a dump of some libseccomp-generated programs. Those dumps are long, so I won't repeat them here, but SCMP_FLTATR_CTL_OPTIMIZE makes the program more efficient, but also longer. Things could be made ~50 times shorter by using range comparisons.

codonell added a commit to codonell/runtime-spec that referenced this issue Nov 17, 2020
On Linux the major C libraries expect that syscalls that are
blocked from running in the container runtime return ENOSYS
to allow fallbacks to be used. Returning EPERM by default is
not useful particularly for syscalls that would return EPERM
for actual access restrictions e.g. the new faccessat2.

The runtime-spec should set the standard and recommend ENOSYS
be returned just like a kernel would that doesn't support that
syscall. This allows C runtimes to fall back on other possible
implementations given the userspace policies.

Please see the upstream discussions:
https://lwn.net/Articles/738694/
- Discusses fragility of syscall filtering.
opencontainers/runc#2151
- glibc and musl request ENOSYS return for unknown syscalls.
systemd/systemd#16739
- Discusses systemd-nspawn breakage with faccessat2.
systemd/systemd#16819
- General policy for systemd-nspawn to return ENOSYS.
seccomp/libseccomp#286
- Block unknown syscalls and erturn ENOSYS.
codonell added a commit to codonell/runtime-spec that referenced this issue Nov 17, 2020
On Linux the major C libraries expect that syscalls that are
blocked from running in the container runtime return ENOSYS
to allow fallbacks to be used. Returning EPERM by default is
not useful particularly for syscalls that would return EPERM
for actual access restrictions e.g. the new faccessat2.

The runtime-spec should set the standard and recommend ENOSYS
be returned just like a kernel would that doesn't support that
syscall. This allows C runtimes to fall back on other possible
implementations given the userspace policies.

Please see the upstream discussions:
https://lwn.net/Articles/738694/
- Discusses fragility of syscall filtering.
opencontainers/runc#2151
- glibc and musl request ENOSYS return for unknown syscalls.
systemd/systemd#16739
- Discusses systemd-nspawn breakage with faccessat2.
systemd/systemd#16819
- General policy for systemd-nspawn to return ENOSYS.
seccomp/libseccomp#286
- Block unknown syscalls and return ENOSYS.
@cyphar
Copy link

cyphar commented Nov 27, 2020

I only just found this thread, just chiming in to say that I've been thinking on similar lines and this is definitely something Docker/runc would like to have solved as well. Doing it with a maximum kernel version is probably the nicest way of doing it, because it means profile writers (and container runtimes) don't need to track syscalls added out-of-order or what the newest syscall was at the time of writing the profile.

@pcmoore
Copy link
Member

pcmoore commented Dec 2, 2020

Based on the discussion above, it looks like most (all?) of the people here believe that issue #11 is the right way to solve this issue; does anyone have a problem with closing this issue in favor of moving future discussion to the original issue (#11)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants