Download raw body.
use correct pipe ends on linux
On Tue, Jul 05, 2022 at 11:08:56PM +0200, Stefan Sperling wrote: > On Tue, Jul 05, 2022 at 10:53:34PM +0200, Stefan Sperling wrote: > > On Tue, Jul 05, 2022 at 10:16:13PM +0200, Stefan Sperling wrote: > > > On Tue, Jul 05, 2022 at 03:12:19PM -0400, Josh Rickmar wrote: > > > > ----------------------------------------------- > > > > commit 24b0007a1fd9c963f5e1e243919476e449b5c8dc (linux_pipe) > > > > from: Josh Rickmar <jrick@zettaport.com> > > > > date: Tue Jul 5 19:07:51 2022 UTC > > > > > > > > use correct pipe ends on linux > > > > > > > > Fixes fdopen errors opening the pipe fds to read ssh-keygen stdout. > > > > > > > > Reported by abieber@ > > > > > > This does not seem to fix the issue properly for me. > > > > > > While creation of a signed tag now apparently succeeds, 'got cat' shows > > > no signature on the tag object and verification with got tag -V fails. > > > I am testing on Ubuntu. > > > > > > > > > > The problem seems to be use of fdopen(3) on a pipe. > > > > With this patch signatures show up in tag objects signed on linux. > > The verification part also uses fdopen and must still be fixed in > > the same way: > > My previous patch had a bug where sig_len no longer accounted > for the terminating NUL byte of the signature string. Fixed here. > > Also, error out if the SSH signature has a zero length. thanks for investigating this and providing this patch. here is something based on your read loop, but i moved it to buf.c so it can be used for both the signing and verifing path. ----------------------------------------------- commit c0fab8bca2e573970da57c5beee134701e2947a1 (linux_pipe) from: Josh Rickmar <jrick@zettaport.com> date: Tue Jul 5 21:46:54 2022 UTC fix pipe usage for linux This uses the correct read and write ends of the fds returned by pipe(2) on linux. It also moves away from creating FILE* streams with fdopen and reading the stream with buf_load (which performs a fstat, and breaks due to a zero length file size on linux) by instead reading from the fd itself. Reported by abieber@, with assistance from stsp@ diff d89a2828a39d1ae3d6c68b2d325ce6a3d0ca768a c0fab8bca2e573970da57c5beee134701e2947a1 commit - d89a2828a39d1ae3d6c68b2d325ce6a3d0ca768a commit + c0fab8bca2e573970da57c5beee134701e2947a1 blob - 05d16ce90ea867ddc912cd1321d68b0262228307 blob + d1a34af84420a9843f584c18b992995b2399bc61 --- lib/buf.c +++ lib/buf.c @@ -126,6 +126,30 @@ out: return err; } +const struct got_error * +buf_load_fd(BUF **buf, int fd) +{ + const struct got_error *err = NULL; + unsigned char out[8192]; + ssize_t r; + size_t len; + + *buf = NULL; + + do { + r = read(fd, out, sizeof(out)); + if (r == -1) + return got_error_from_errno("read"); + if (r > 0) { + err = buf_append(&len, *buf, out, r); + if (err) + return err; + } + } while (r > 0); + + return NULL; +} + void buf_free(BUF *b) { blob - 354d7c4ea8684b77bc84fa0fcad6b6c8e2b2be80 blob + aff1492306e97d3fdd255c836d083eea96b30e19 --- lib/buf.h +++ lib/buf.h @@ -51,6 +51,7 @@ struct buf { const struct got_error *buf_alloc(BUF **, size_t); const struct got_error *buf_load(BUF **, FILE *); +const struct got_error *buf_load_fd(BUF **, int fd); void buf_free(BUF *); void *buf_release(BUF *); u_char buf_getc(BUF *, size_t); blob - 2e773fde3898b103364cc053c27f666b78abea2d blob + e7a5a2312e750051effc62220e0e5ca92cdd0a24 --- lib/object_create.c +++ lib/object_create.c @@ -688,7 +688,6 @@ got_object_tag_create(struct got_object_id **id, msg++; if (signer_id) { - FILE *out; pid_t pid; size_t len; int in_fd, out_fd; @@ -743,13 +742,8 @@ got_object_tag_create(struct got_object_id **id, goto done; } - out = fdopen(out_fd, "r"); - if (out == NULL) { - err = got_error_from_errno("fdopen"); - goto done; - } buf_empty(buf); - err = buf_load(&buf, out); + err = buf_load_fd(&buf, out_fd); if (err) goto done; sig_len = buf_len(buf) + 1; blob - ac1b2637f90cec3243da8a059be58205a4621203 blob + 7084c6ce1b92b634c964d90d3ef6e32ce922a786 --- lib/sigs.c +++ lib/sigs.c @@ -116,11 +116,11 @@ got_sigs_sign_tag_ssh(pid_t *newpid, int *in_fd, int * } else if (pid == 0) { if (close(in_pfd[1]) == -1) err(1, "close"); - if (close(out_pfd[1]) == -1) + if (close(out_pfd[0]) == -1) err(1, "close"); if (dup2(in_pfd[0], 0) == -1) err(1, "dup2"); - if (dup2(out_pfd[0], 1) == -1) + if (dup2(out_pfd[1], 1) == -1) err(1, "dup2"); if (execv(GOT_TAG_PATH_SSH_KEYGEN, (char **const)argv) == -1) err(1, "execv"); @@ -128,11 +128,11 @@ got_sigs_sign_tag_ssh(pid_t *newpid, int *in_fd, int * } if (close(in_pfd[0]) == -1) return got_error_from_errno("close"); - if (close(out_pfd[0]) == -1) + if (close(out_pfd[1]) == -1) return got_error_from_errno("close"); *newpid = pid; *in_fd = in_pfd[1]; - *out_fd = out_pfd[1]; + *out_fd = out_pfd[0]; return NULL; } @@ -267,7 +267,7 @@ got_sigs_verify_tag_ssh(char **msg, struct got_tag_obj char* parsed_identity = NULL; const char *identity; char* tmppath = NULL; - FILE *tmpsig, *out = NULL; + FILE *tmpsig = NULL; BUF *buf; int i = 0, j; @@ -342,11 +342,11 @@ got_sigs_verify_tag_ssh(char **msg, struct got_tag_obj } else if (pid == 0) { if (close(in_pfd[1]) == -1) err(1, "close"); - if (close(out_pfd[1]) == -1) + if (close(out_pfd[0]) == -1) err(1, "close"); if (dup2(in_pfd[0], 0) == -1) err(1, "dup2"); - if (dup2(out_pfd[0], 1) == -1) + if (dup2(out_pfd[1], 1) == -1) err(1, "dup2"); if (execv(GOT_TAG_PATH_SSH_KEYGEN, (char **const)argv) == -1) err(1, "execv"); @@ -356,7 +356,7 @@ got_sigs_verify_tag_ssh(char **msg, struct got_tag_obj error = got_error_from_errno("close"); goto done; } - if (close(out_pfd[0]) == -1) { + if (close(out_pfd[1]) == -1) { error = got_error_from_errno("close"); goto done; } @@ -377,22 +377,16 @@ got_sigs_verify_tag_ssh(char **msg, struct got_tag_obj goto done; } - out = fdopen(out_pfd[1], "r"); - if (out == NULL) { - error = got_error_from_errno("fdopen"); - goto done; - } - error = buf_load(&buf, out); + error = buf_load_fd(&buf, out_pfd[0]); if (error) goto done; error = buf_putc(buf, '\0'); if (error) goto done; - if (close(out_pfd[1]) == -1) { + if (close(out_pfd[0]) == -1) { error = got_error_from_errno("close"); goto done; } - out = NULL; *msg = buf_get(buf); if (WEXITSTATUS(status) != 0) error = got_error(GOT_ERR_BAD_TAG_SIGNATURE); @@ -400,9 +394,8 @@ got_sigs_verify_tag_ssh(char **msg, struct got_tag_obj done: free(parsed_identity); free(tmppath); + close(out_pfd[0]); if (tmpsig && fclose(tmpsig) == EOF && error == NULL) error = got_error_from_errno("fclose"); - if (out && fclose(out) == EOF && error == NULL) - error = got_error_from_errno("fclose"); return error; }
use correct pipe ends on linux