diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2014-05-29 12:36:28 -0400 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2014-05-29 12:37:38 -0400 |
commit | 375ed12a42c6092b1af1d8e395bf3dadd9a66e48 (patch) | |
tree | 2719822ab13ccf099d01e8818f6e6e36a9e67cb5 /perlio.c | |
parent | 316ebaf2966c5b6fd47a9d1dc6fb64fcbd262379 (diff) | |
download | perl-375ed12a42c6092b1af1d8e395bf3dadd9a66e48.tar.gz |
fcntl receiving -1 from fileno, fcntl failing.
(Also very few spots of negative numgroups for getgroups(),
and fgetc() return, but almost all checking is for fcntl.)
(merged fix for perl #121743 and perl #121745: hopefully
picked up all the fixes-to-fixes from the ticket...)
Fix for Coverity perl5 CIDs 28990..29003,29005..29011,29013,
45354,45363,49926:
Argument cannot be negative (NEGATIVE_RETURNS) fd is
passed to a parameter that cannot be negative.
and CIDs 29004, 29012:
Argument cannot be negative (NEGATIVE_RETURNS)
num_groups is passed to a parameter that cannot be negative
and because of CIDs 29005 and 29006 also CID 28924.
In the first set of issues a fd is retrieved from PerlIO_fileno, and
that is then used in places like fstat(), fchown(), dup(), etc.,
without checking whether the fd is valid (>=0).
In the second set of issues a potentially negative
number is potentially passed to getgroups().
The CIDs 29005 and 29006 were a bit messy: fixing them needed also
resolving CID 28924 where the return value of fstat() was ignored,
and for completeness adding two croak calls (with perldiag updates):
a bit of a waste since it's suidperl code.
Diffstat (limited to 'perlio.c')
-rw-r--r-- | perlio.c | 20 |
1 files changed, 16 insertions, 4 deletions
@@ -2928,6 +2928,10 @@ PerlIO_importFILE(FILE *stdio, const char *mode) PerlIO *f = NULL; if (stdio) { PerlIOStdio *s; + int fd0 = fileno(stdio); + if (fd0 < 0) { + return NULL; + } if (!mode || !*mode) { /* We need to probe to see how we can open the stream so start with read/write and then try write and read @@ -2936,8 +2940,12 @@ PerlIO_importFILE(FILE *stdio, const char *mode) Note that the errno value set by a failing fdopen varies between stdio implementations. */ - const int fd = PerlLIO_dup(fileno(stdio)); - FILE *f2 = PerlSIO_fdopen(fd, (mode = "r+")); + const int fd = PerlLIO_dup(fd0); + FILE *f2; + if (fd < 0) { + return f; + } + f2 = PerlSIO_fdopen(fd, (mode = "r+")); if (!f2) { f2 = PerlSIO_fdopen(fd, (mode = "w")); } @@ -3357,8 +3365,8 @@ PerlIOStdio_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count) } if ((STDCHAR*)PerlSIO_get_ptr(s) != --eptr || ((*eptr & 0xFF) != ch)) { /* Did not change pointer as expected */ - fgetc(s); /* get char back again */ - break; + if (fgetc(s) != EOF) /* get char back again */ + break; } /* It worked ! */ count--; @@ -3674,6 +3682,10 @@ PerlIO_exportFILE(PerlIO * f, const char *mode) FILE *stdio = NULL; if (PerlIOValid(f)) { char buf[8]; + int fd = PerlIO_fileno(f); + if (fd < 0) { + return NULL; + } PerlIO_flush(f); if (!mode || !*mode) { mode = PerlIO_modestr(f, buf); |