Hi deraadt,
I know you know I don't code well, but in order to show you what's on my
mind I had to write code, I took the bsearch() from the ieee80211 code, so
perhaps there is a better way (like always) perhaps to unify the function
between these two areas.
The reason I did this is to save on cpu cycles when you look at X amount
of processes all pledging...one time'd process won't show much difference.
below's diff:
-peter
? pledge.diff
Index: kern/kern_pledge.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_pledge.c,v
retrieving revision 1.90
diff -u -p -u -r1.90 kern_pledge.c
--- kern/kern_pledge.c 28 Oct 2015 17:38:52 -0000 1.90
+++ kern/kern_pledge.c 29 Oct 2015 16:23:04 -0000
@@ -58,6 +58,32 @@
int canonpath(const char *input, char *buf, size_t bufsize);
int substrcmp(const char *p1, size_t s1, const char *p2, size_t s2);
+int pledge_cmp(const void *pi, const void *ph);
+
+/* taken from net80211/ieee80211_regdomain.c */
+const void *pledge_bsearch(const void *, const void *, size_t, size_t,
+ int (*)(const void *, const void *));
+
+const void *
+pledge_bsearch(const void *key, const void *base0, size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *))
+{
+ const char *base = base0;
+ int lim, cmp;
+ const void *p;
+
+ for (lim = nmemb; lim != 0; lim >>= 1) {
+ p = base + (lim >> 1) * size;
+ cmp = (*compar)(key, p);
+ if (cmp == 0)
+ return ((const void *)p);
+ if (cmp > 0) { /* key > p: move right */
+ base = (const char *)p + size;
+ lim--;
+ } /* else move left */
+ }
+ return (NULL);
+}
const u_int pledge_syscalls[SYS_MAXSYSCALL] = {
[SYS_exit] = 0xffffffff,
@@ -256,40 +282,42 @@ const u_int pledge_syscalls[SYS_MAXSYSCA
[SYS_swapctl] = PLEDGE_VMINFO, /* XXX should limit to "get" operations
*/
};
-static const struct {
+/* MUST be sorted! */
+static const struct PR {
char *name;
int flags;
} pledgereq[] = {
- { "stdio", PLEDGE_STDIO },
- { "rpath", PLEDGE_RPATH },
- { "wpath", PLEDGE_WPATH },
- { "tmppath", PLEDGE_TMPPATH },
- { "inet", PLEDGE_INET },
- { "unix", PLEDGE_UNIX },
+ { "abort", 0 }, /* XXX reserve for later */
+ { "cpath", PLEDGE_CPATH },
{ "dns", PLEDGE_DNS },
+ { "exec", PLEDGE_EXEC },
+ { "fattr", PLEDGE_FATTR },
+ { "flock", PLEDGE_FLOCK },
{ "getpw", PLEDGE_GETPW },
- { "sendfd", PLEDGE_SENDFD },
- { "recvfd", PLEDGE_RECVFD },
- { "ioctl", PLEDGE_IOCTL },
{ "id", PLEDGE_ID },
- { "route", PLEDGE_ROUTE },
+ { "inet", PLEDGE_INET },
+ { "ioctl", PLEDGE_IOCTL },
{ "mcast", PLEDGE_MCAST },
- { "tty", PLEDGE_TTY },
{ "proc", PLEDGE_PROC },
- { "exec", PLEDGE_EXEC },
- { "cpath", PLEDGE_CPATH },
- { "fattr", PLEDGE_FATTR },
{ "prot_exec", PLEDGE_PROTEXEC },
- { "flock", PLEDGE_FLOCK },
{ "ps", PLEDGE_PS },
- { "vminfo", PLEDGE_VMINFO },
+ { "recvfd", PLEDGE_RECVFD },
+ { "route", PLEDGE_ROUTE },
+ { "rpath", PLEDGE_RPATH },
+ { "sendfd", PLEDGE_SENDFD },
{ "settime", PLEDGE_SETTIME },
- { "abort", 0 }, /* XXX reserve for later */
+ { "stdio", PLEDGE_STDIO },
+ { "tmppath", PLEDGE_TMPPATH },
+ { "tty", PLEDGE_TTY },
+ { "unix", PLEDGE_UNIX },
+ { "vminfo", PLEDGE_VMINFO },
+ { "wpath", PLEDGE_WPATH },
};
int
sys_pledge(struct proc *p, void *v, register_t *retval)
{
+ struct PR *pr = NULL;
struct sys_pledge_args /* {
syscallarg(const char *)request;
syscallarg(const char **)paths;
@@ -300,7 +328,7 @@ sys_pledge(struct proc *p, void *v, regi
if (SCARG(uap, request)) {
size_t rbuflen;
char *rbuf, *rp, *pn;
- int f, i;
+ int f;
rbuf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
error = copyinstr(SCARG(uap, request), rbuf, MAXPATHLEN,
@@ -321,16 +349,15 @@ sys_pledge(struct proc *p, void *v, regi
*pn++ = '\0';
}
- for (f = i = 0; i < nitems(pledgereq); i++) {
- if (strcmp(rp, pledgereq[i].name) == 0) {
- f = pledgereq[i].flags;
- break;
- }
- }
- if (f == 0) {
- free(rbuf, M_TEMP, MAXPATHLEN);
- return (EINVAL);
+ if ((pr = (struct PR *)pledge_bsearch(rp, &pledgereq,
+ nitems(pledgereq), sizeof(struct PR),
+ pledge_cmp)) == NULL) {
+ free(rbuf, M_TEMP, MAXPATHLEN);
+ return (EINVAL);
}
+
+ f = pr->flags;
+
flags |= f;
}
free(rbuf, M_TEMP, MAXPATHLEN);
@@ -1377,4 +1404,10 @@ substrcmp(const char *p1, size_t s1, con
return (2); /* string2 is a subpath of string1 */
else
return (0); /* no subpath */
+}
+
+int
+pledge_cmp(const void *pi, const void *ph)
+{
+ return(strcmp((const char *)pi, ((const struct PR *)ph)->name));
}