summaryrefslogtreecommitdiff
path: root/perlio.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2014-05-29 12:36:28 -0400
committerJarkko Hietaniemi <jhi@iki.fi>2014-05-29 12:37:38 -0400
commit375ed12a42c6092b1af1d8e395bf3dadd9a66e48 (patch)
tree2719822ab13ccf099d01e8818f6e6e36a9e67cb5 /perlio.c
parent316ebaf2966c5b6fd47a9d1dc6fb64fcbd262379 (diff)
downloadperl-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.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/perlio.c b/perlio.c
index 2ce8ac162c..29c4bf771e 100644
--- a/perlio.c
+++ b/perlio.c
@@ -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);