Re: Put non-NULL pledge abort in the man page
On Thu, Nov 25, 2021 at 5:17 AM Claudio Jeker wrote: > On Thu, Nov 25, 2021 at 04:55:23AM -0600, Luke Small wrote: > > I ran ktrace. Kdump said the last thing it did was try to load > > /usr/libexec/ld.so > > > > To main(), before the unveil pledge is dropped, I added: > > > > if (unveil("/usr/libexec/", "rx") == -1) > > err(1, "unveil, line: % d", __LINE__); > > > > After running it again, it spits out an error message: > > > > ld.so: pkg_ping: can't load library 'libc.so.96.1' > > > > So I put in: > > > > if (unveil("usr/lib/", "rx") == -1) > > err(1, "unveil, line: %d", __LINE__); > > > > Now it successfully execv()s into the new process space! > > Now in the newly created program, which hasn’t set new pledge > execpromises, > > it won’t successfully run ftp(1) because it wasn’t granted the inet > > execpromise. > > > > execpromises seems to have carried over! > > Don't use execpromises. That feature is not working and no tool in OpenBSD > uses it. > > -- > :wq Claudio Okay! It’s kinda weird that the pledge man page (even in -current according to: https://man.openbsd.org/pledge.2 ) doesn’t even have a bug section which mentions that then. > -- -Luke
Re: Put non-NULL pledge abort in the man page
There seems to be a lot of pledge calls in your program. A quick glance through the source tree and the only program I could find with more is smtpd. I also didn't see anywhere you were calling pledge with a non null execpromises. You could also try adding the `error' promise so that it won't sigabort and maybe you can find where the problem is easier. Edgar On 11/25/21 4:55 AM, Luke Small wrote: I ran ktrace. Kdump said the last thing it did was try to load /usr/libexec/ld.so To main(), before the unveil pledge is dropped, I added: if (unveil("/usr/libexec/", "rx") == -1) err(1, "unveil, line: % d", __LINE__); After running it again, it spits out an error message: ld.so: pkg_ping: can't load library 'libc.so.96.1' So I put in: if (unveil("usr/lib/", "rx") == -1) err(1, "unveil, line: %d", __LINE__); Now it successfully execv()s into the new process space! Now in the newly created program, which hasn’t set new pledge execpromises, it won’t successfully run ftp(1) because it wasn’t granted the inet execpromise. execpromises seems to have carried over! On Thu, Nov 25, 2021 at 2:24 AM Sebastien Marie wrote: On Thu, Nov 25, 2021 at 01:52:31AM -0600, Luke Small wrote: The attachment is a version of the c file at: https://github.com/lukensmall/pkg_ping the version is the repository doesn't have your changes. Thanks for the attached version. After it does a fork-exec to ftp(1) to pipe in ftplist from a random hard-coded mirror, I short circuit it (for debugging) at the line that says: “if (n || array_length == 0 || loop == 20)” by putting in “loop == 20” which is the default loop value, where it is decremented in further iterations of calling pkg_ping in the restart function which only occurs in rare download errors. If it succeeds with the execv in the restart function, it should work normally. Just to be clear: I will not run random code (as normal user or as root). Could you run (as user): $ ktrace -di ./pkg_ping whatever-to-reproduce-the-problem and share the output of `kdump` ? Beware that the file might be large (so gzip it) and could contains sensitive information (so better to review it). Seeing a gdb backtrace might be useful too. Thanks. -- Sebastien Marie
Re: Put non-NULL pledge abort in the man page
On Thu, Nov 25, 2021 at 04:55:23AM -0600, Luke Small wrote: > I ran ktrace. Kdump said the last thing it did was try to load > /usr/libexec/ld.so > > To main(), before the unveil pledge is dropped, I added: > > if (unveil("/usr/libexec/", "rx") == -1) > err(1, "unveil, line: % d", __LINE__); > > After running it again, it spits out an error message: > > ld.so: pkg_ping: can't load library 'libc.so.96.1' > > So I put in: > > if (unveil("usr/lib/", "rx") == -1) > err(1, "unveil, line: %d", __LINE__); > > Now it successfully execv()s into the new process space! > Now in the newly created program, which hasn’t set new pledge execpromises, > it won’t successfully run ftp(1) because it wasn’t granted the inet > execpromise. > > execpromises seems to have carried over! Don't use execpromises. That feature is not working and no tool in OpenBSD uses it. -- :wq Claudio
Re: Put non-NULL pledge abort in the man page
I ran ktrace. Kdump said the last thing it did was try to load /usr/libexec/ld.so To main(), before the unveil pledge is dropped, I added: if (unveil("/usr/libexec/", "rx") == -1) err(1, "unveil, line: % d", __LINE__); After running it again, it spits out an error message: ld.so: pkg_ping: can't load library 'libc.so.96.1' So I put in: if (unveil("usr/lib/", "rx") == -1) err(1, "unveil, line: %d", __LINE__); Now it successfully execv()s into the new process space! Now in the newly created program, which hasn’t set new pledge execpromises, it won’t successfully run ftp(1) because it wasn’t granted the inet execpromise. execpromises seems to have carried over! On Thu, Nov 25, 2021 at 2:24 AM Sebastien Marie wrote: > On Thu, Nov 25, 2021 at 01:52:31AM -0600, Luke Small wrote: > > The attachment is a version of the c file at: > > https://github.com/lukensmall/pkg_ping > > the version is the repository doesn't have your changes. Thanks for > the attached version. > > > After it does a fork-exec to ftp(1) to pipe in ftplist from a random > > hard-coded mirror, I short circuit it (for debugging) at the line that > says: > > “if (n || array_length == 0 || loop == 20)” > > by putting in “loop == 20” which is the default loop value, where it is > > decremented in further iterations of calling pkg_ping in the restart > > function which only occurs in rare download errors. If it succeeds with > the > > execv in the restart function, it should work normally. > > Just to be clear: I will not run random code (as normal user or as root). > > Could you run (as user): > > $ ktrace -di ./pkg_ping whatever-to-reproduce-the-problem > > and share the output of `kdump` ? > > Beware that the file might be large (so gzip it) and could contains > sensitive information (so better to review it). > > Seeing a gdb backtrace might be useful too. > > Thanks. > -- > Sebastien Marie > -- -Luke
Re: Put non-NULL pledge abort in the man page
Sebastien Marie wrote: > If the code you are using is restricted and can't be showed, please at > least show a ktrace output of the program run. At this point I am > still unsure that it is execve(2) which is causing pledge violation. actually I want to know where garbage code like this runs to make sure it hurts fewer people
Re: Put non-NULL pledge abort in the man page
On Wed, Nov 24, 2021 at 10:55:56PM -0600, Luke Small wrote: > I took a hard look at it again…with more printf()s. > > It is killed at the execv which calls the calling executable to get > different random number generated values with a slightly different argv set > to prevent an indefinite loop. > > I put the following in before the execv: > > int i = pledge("stdio exec rpath”, > "stdio exec proc rpath cpath wpath dns id unveil tty error"); > if (i == -1) > err(1, "pledge, line: %d", __LINE__); > > After doing this it would dmesg rpath. I had to unveil(argv[0], “rx”); > argv[0] which is “./pkg_ping” or “/full/path/to/pkg_ping” instead of having > it as merely unveil(argv[0], “x”); which worked before. > > Now it gets shot in the head and leaves nothing in dmesg > > Does that mean that if execpromises is set, that it will get killed at > every execve() series call? Does pledge/unveil not accept directly > execv()ing back into the same program? Is it trying to read another file > which unveil is still affecting? if it is killed at execve(2), execpromises as nothing to do here (but without seeing the whole code it is hard to be sure). >From the small code you show, it seems that "proc" promise is missing from your promises (first pledge(2) argument). You are unable to call fork(2) without it, and the program will be killed. If the code you are using is restricted and can't be showed, please at least show a ktrace output of the program run. At this point I am still unsure that it is execve(2) which is causing pledge violation. -- Sebastien Marie
Re: Put non-NULL pledge abort in the man page
I took a hard look at it again…with more printf()s. It is killed at the execv which calls the calling executable to get different random number generated values with a slightly different argv set to prevent an indefinite loop. I put the following in before the execv: int i = pledge("stdio exec rpath”, "stdio exec proc rpath cpath wpath dns id unveil tty error"); if (i == -1) err(1, "pledge, line: %d", __LINE__); After doing this it would dmesg rpath. I had to unveil(argv[0], “rx”); argv[0] which is “./pkg_ping” or “/full/path/to/pkg_ping” instead of having it as merely unveil(argv[0], “x”); which worked before. Now it gets shot in the head and leaves nothing in dmesg Does that mean that if execpromises is set, that it will get killed at every execve() series call? Does pledge/unveil not accept directly execv()ing back into the same program? Is it trying to read another file which unveil is still affecting? >> >> Luke Small wrote: >> >> > I have a program which runs fork() a couple times with pledges: “stdio >> > cpath wpath” for writing to disk and “stdio dns” for a dns caching >> process >> > after accepting command-line input. Is the execpromises, permitted to >> > increase/change to accommodate the different fork()s from the parent? If >> > so, why isn’t all of this discussed in the manpage. >> > >> > I’m running 7.0 and it immediately is killed when I run pledge with a >> > non-NULL execpromise. >> > >> > No error, just a sigabort. And nothing in the man page (even for >> -current: >> > on the web) which explains anything. >> > >> > https://github.com/lukensmall/pkg_ping >> > >> > This a command-line program is used to make manually choosing a >> responsive >> > mirror or automatically writing the most responsive OpenBSD mirror to >> > /etc/installurl very easy. >> > >> > On Wed, Nov 24, 2021 at 11:50 AM Luke Small >> wrote: >> > >> > > I tried calling pledge with a non-NULL execpromise and noticed that >> it was >> > > killed. That’d be convenient if that behavior was noted in the man >> page!-- >> > > -Luke >> > > >> > -- >> > -Luke >> > -- > -Luke > -- -Luke
Re: Put non-NULL pledge abort in the man page
It kills your secret program because it is broken. >From the manual page: A process which attempts a restricted operation is killed with an uncatchable SIGABRT, delivering a core file if possible. You are so incapable of reading and learning. I am asking you to leave this list. Luke Small wrote: > It works great, up until the time that pledge() ITSELF gets shot in the head, > which > seems would be impossible! It’s supposed to only throw errors! Or did I miss > the memo > that there’s a “pledge” pledge? > > On Wed, Nov 24, 2021 at 8:19 PM Theo de Raadt wrote: > > You have a secret program and you want people on the internet to help > you debug what you have done wrong in this secret program. > > You obviously don't know what you are doing, and I think you don't > deserve help. > > Luke Small wrote: > > > I have a program which runs fork() a couple times with pledges: “stdio > > cpath wpath” for writing to disk and “stdio dns” for a dns caching process > > after accepting command-line input. Is the execpromises, permitted to > > increase/change to accommodate the different fork()s from the parent? If > > so, why isn’t all of this discussed in the manpage. > > > > I’m running 7.0 and it immediately is killed when I run pledge with a > > non-NULL execpromise. > > > > No error, just a sigabort. And nothing in the man page (even for -current: > > on the web) which explains anything. > > > > https://github.com/lukensmall/pkg_ping > > > > This a command-line program is used to make manually choosing a responsive > > mirror or automatically writing the most responsive OpenBSD mirror to > > /etc/installurl very easy. > > > > On Wed, Nov 24, 2021 at 11:50 AM Luke Small wrote: > > > > > I tried calling pledge with a non-NULL execpromise and noticed that it > was > > > killed. That’d be convenient if that behavior was noted in the man > page!-- > > > -Luke > > > > > -- > > -Luke > > -- > -Luke >
Re: Put non-NULL pledge abort in the man page
It works great, up until the time that pledge() ITSELF gets shot in the head, which seems would be impossible! It’s supposed to only throw errors! Or did I miss the memo that there’s a “pledge” pledge? On Wed, Nov 24, 2021 at 8:19 PM Theo de Raadt wrote: > You have a secret program and you want people on the internet to help > you debug what you have done wrong in this secret program. > > You obviously don't know what you are doing, and I think you don't > deserve help. > > > Luke Small wrote: > > > I have a program which runs fork() a couple times with pledges: “stdio > > cpath wpath” for writing to disk and “stdio dns” for a dns caching > process > > after accepting command-line input. Is the execpromises, permitted to > > increase/change to accommodate the different fork()s from the parent? If > > so, why isn’t all of this discussed in the manpage. > > > > I’m running 7.0 and it immediately is killed when I run pledge with a > > non-NULL execpromise. > > > > No error, just a sigabort. And nothing in the man page (even for > -current: > > on the web) which explains anything. > > > > https://github.com/lukensmall/pkg_ping > > > > This a command-line program is used to make manually choosing a > responsive > > mirror or automatically writing the most responsive OpenBSD mirror to > > /etc/installurl very easy. > > > > On Wed, Nov 24, 2021 at 11:50 AM Luke Small > wrote: > > > > > I tried calling pledge with a non-NULL execpromise and noticed that it > was > > > killed. That’d be convenient if that behavior was noted in the man > page!-- > > > -Luke > > > > > -- > > -Luke > -- -Luke
Re: Put non-NULL pledge abort in the man page
You have a secret program and you want people on the internet to help you debug what you have done wrong in this secret program. You obviously don't know what you are doing, and I think you don't deserve help. Luke Small wrote: > I have a program which runs fork() a couple times with pledges: “stdio > cpath wpath” for writing to disk and “stdio dns” for a dns caching process > after accepting command-line input. Is the execpromises, permitted to > increase/change to accommodate the different fork()s from the parent? If > so, why isn’t all of this discussed in the manpage. > > I’m running 7.0 and it immediately is killed when I run pledge with a > non-NULL execpromise. > > No error, just a sigabort. And nothing in the man page (even for -current: > on the web) which explains anything. > > https://github.com/lukensmall/pkg_ping > > This a command-line program is used to make manually choosing a responsive > mirror or automatically writing the most responsive OpenBSD mirror to > /etc/installurl very easy. > > On Wed, Nov 24, 2021 at 11:50 AM Luke Small wrote: > > > I tried calling pledge with a non-NULL execpromise and noticed that it was > > killed. That’d be convenient if that behavior was noted in the man page!-- > > -Luke > > > -- > -Luke
Re: Put non-NULL pledge abort in the man page
I have a program which runs fork() a couple times with pledges: “stdio cpath wpath” for writing to disk and “stdio dns” for a dns caching process after accepting command-line input. Is the execpromises, permitted to increase/change to accommodate the different fork()s from the parent? If so, why isn’t all of this discussed in the manpage. I’m running 7.0 and it immediately is killed when I run pledge with a non-NULL execpromise. No error, just a sigabort. And nothing in the man page (even for -current: on the web) which explains anything. https://github.com/lukensmall/pkg_ping This a command-line program is used to make manually choosing a responsive mirror or automatically writing the most responsive OpenBSD mirror to /etc/installurl very easy. On Wed, Nov 24, 2021 at 11:50 AM Luke Small wrote: > I tried calling pledge with a non-NULL execpromise and noticed that it was > killed. That’d be convenient if that behavior was noted in the man page!-- > -Luke > -- -Luke
Re: Put non-NULL pledge abort in the man page
On 11/24/21 11:50 AM, Luke Small wrote: I tried calling pledge with a non-NULL execpromise and noticed that it was killed. That’d be convenient if that behavior was noted in the man page!-- -Luke You want to look at the "exec" portion of the manual. execpromises are for setting up pledge for a forked child. #include #include #include #include #include int main(int argc, char **argv) { pid_t pid; const char *promises = "stdio proc exec"; const char *execpromises = "stdio"; int status; if (pledge(promises, execpromises) != 0) err(1, "pledge"); switch (pid = fork()) { case -1: err(1, "fork"); break; case 0: for (;;) { sleep(10); printf("i'm the child\n"); /* this will kill the child because execpromises lacks rpath */ if (chdir("/") != 0) err(1, "chdir"); } exit(1); default: break; } printf("I'm the parent\n"); wait(); printf("child exited with status: %d\n", status); return 0; } bsd$ ./pledge I'm the parent i'm the child child exited with status: 134 Nov 24 12:35:17 bsd /bsd: pledge[6216]: pledge "rpath", syscall 12
Put non-NULL pledge abort in the man page
I tried calling pledge with a non-NULL execpromise and noticed that it was killed. That’d be convenient if that behavior was noted in the man page!-- -Luke