Since pg11 pg_read_file() and friends can be used with absolute paths as long as the user is superuser or explicitly granted the role pg_read_server_files.
I noticed that when trying to read a virtual file, e.g.: SELECT pg_read_file('/proc/self/status'); the returned result is a zero length string. However this works fine: SELECT pg_read_file('/proc/self/status', 127, 128); The reason for that is pg_read_file_v2() sets bytes_to_read=-1 if no offset and length are supplied as arguments when it is called. It passes bytes_to_read down to read_binary_file(). When the latter function sees bytes_to_read < 0 it tries to read the entire file by getting the file size via stat, which returns 0 for a virtual file size. The attached patch fixes this for me. I think it ought to be backpatched through pg11. Comments? Joe -- Crunchy Data - http://crunchydata.com PostgreSQL Support for Secure Enterprises Consulting, Training, & Open Source Development
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index ceaa618..101df3a 100644 *** a/src/backend/utils/adt/genfile.c --- b/src/backend/utils/adt/genfile.c *************** *** 36,41 **** --- 36,42 ---- #include "utils/syscache.h" #include "utils/timestamp.h" + #define READBUF_SIZE 4096 /* * Convert a "text" filename argument to C string, and check it's allowable. *************** read_binary_file(const char *filename, i *** 106,112 **** bool missing_ok) { bytea *buf; ! size_t nbytes; FILE *file; if (bytes_to_read < 0) --- 107,113 ---- bool missing_ok) { bytea *buf; ! size_t nbytes = 0; FILE *file; if (bytes_to_read < 0) *************** read_binary_file(const char *filename, i *** 154,162 **** (errcode_for_file_access(), errmsg("could not seek in file \"%s\": %m", filename))); ! buf = (bytea *) palloc((Size) bytes_to_read + VARHDRSZ); ! nbytes = fread(VARDATA(buf), 1, (size_t) bytes_to_read, file); if (ferror(file)) ereport(ERROR, --- 155,187 ---- (errcode_for_file_access(), errmsg("could not seek in file \"%s\": %m", filename))); ! if (bytes_to_read > 0) ! { ! buf = (bytea *) palloc((Size) bytes_to_read + VARHDRSZ); ! nbytes = fread(VARDATA(buf), 1, (size_t) bytes_to_read, file); ! } ! else ! { ! /* bytes_to_read can be <= zero if the file is a virtual file */ ! StringInfoData sbuf; ! size_t rbytes = 0; ! char rbuf[READBUF_SIZE]; ! ! initStringInfo(&sbuf); ! while (!feof(file)) ! { ! memset(rbuf, '\0', READBUF_SIZE); ! rbytes = fread(rbuf, 1, (size_t) READBUF_SIZE, file); ! nbytes += rbytes; ! ! appendStringInfoString(&sbuf, rbuf); ! } ! ! Assert(nbytes == sbuf.len); ! buf = (bytea *) palloc((Size) nbytes + VARHDRSZ); ! memcpy(VARDATA(buf), sbuf.data, nbytes); ! } if (ferror(file)) ereport(ERROR,
signature.asc
Description: OpenPGP digital signature