diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index b214218..ad04252 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -19238,6 +19238,10 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
     present on the operating system are never removed by this function.)
    </para>
 
+   <para>
+    By default, use of this function is restricted to superusers, but access
+    can be given to other users via <command>GRANT</>.
+   </para>
   </sect2>
 
   <sect2 id="functions-admin-index">
@@ -19318,7 +19322,9 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
     database cluster directory and the <varname>log_directory</> can be
     accessed.  Use a relative path for files in the cluster directory,
     and a path matching the <varname>log_directory</> configuration setting
-    for log files.  Use of these functions is restricted to superusers.
+    for log files.  Use of these functions is restricted to superusers
+    by default but access may be granted to others using
+    <command>GRANT</command>.
    </para>
 
    <table id="functions-admin-genfile-table">
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 4dfedf8..2e31462 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1080,8 +1080,20 @@ REVOKE EXECUTE ON FUNCTION pg_xlog_replay_pause() FROM public;
 REVOKE EXECUTE ON FUNCTION pg_xlog_replay_resume() FROM public;
 REVOKE EXECUTE ON FUNCTION pg_rotate_logfile() FROM public;
 REVOKE EXECUTE ON FUNCTION pg_reload_conf() FROM public;
+REVOKE EXECUTE ON FUNCTION pg_import_system_collations(boolean, regnamespace) FROM public;
 
 REVOKE EXECUTE ON FUNCTION pg_stat_reset() FROM public;
 REVOKE EXECUTE ON FUNCTION pg_stat_reset_shared(text) FROM public;
 REVOKE EXECUTE ON FUNCTION pg_stat_reset_single_table_counters(oid) FROM public;
 REVOKE EXECUTE ON FUNCTION pg_stat_reset_single_function_counters(oid) FROM public;
+
+REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text, bigint, bigint) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text, bigint, bigint, boolean) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_read_file(text) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_read_file(text, bigint, bigint) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_read_file(text, bigint, bigint, boolean) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_stat_file(text) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_stat_file(text, boolean) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_ls_dir(text) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_ls_dir(text, boolean, boolean) FROM public;
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 8d4d5b7..a15ac16 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -218,7 +218,12 @@ normalize_locale_name(char *new, const char *old)
 	return changed;
 }
 
-
+/*
+ * Import operating system collations.
+ *
+ * Permission checking for this function is managed through the normal
+ * GRANT system.
+ */
 Datum
 pg_import_system_collations(PG_FUNCTION_ARGS)
 {
@@ -237,11 +242,6 @@ pg_import_system_collations(PG_FUNCTION_ARGS)
 			   *lce;
 #endif
 
-	if (!superuser())
-		ereport(ERROR,
-				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-				 (errmsg("must be superuser to import system collations"))));
-
 #if defined(HAVE_LOCALE_T) && !defined(WIN32)
 	locale_a_handle = OpenPipeStream("locale -a", "r");
 	if (locale_a_handle == NULL)
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index 1a127d9..4f1021e 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -183,6 +183,9 @@ read_text_file(const char *filename, int64 seek_offset, int64 bytes_to_read,
 
 /*
  * Read a section of a file, returning it as text
+ *
+ * Permission checking for this function is managed through the normal
+ * GRANT system.
  */
 Datum
 pg_read_file(PG_FUNCTION_ARGS)
@@ -194,11 +197,6 @@ pg_read_file(PG_FUNCTION_ARGS)
 	char	   *filename;
 	text	   *result;
 
-	if (!superuser())
-		ereport(ERROR,
-				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-				 (errmsg("must be superuser to read files"))));
-
 	/* handle optional arguments */
 	if (PG_NARGS() >= 3)
 	{
@@ -224,6 +222,9 @@ pg_read_file(PG_FUNCTION_ARGS)
 
 /*
  * Read a section of a file, returning it as bytea
+ *
+ * Permission checking for this function is managed through the normal
+ * GRANT system.
  */
 Datum
 pg_read_binary_file(PG_FUNCTION_ARGS)
@@ -235,11 +236,6 @@ pg_read_binary_file(PG_FUNCTION_ARGS)
 	char	   *filename;
 	bytea	   *result;
 
-	if (!superuser())
-		ereport(ERROR,
-				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-				 (errmsg("must be superuser to read files"))));
-
 	/* handle optional arguments */
 	if (PG_NARGS() >= 3)
 	{
@@ -299,6 +295,9 @@ pg_read_binary_file_all(PG_FUNCTION_ARGS)
 
 /*
  * stat a file
+ *
+ * Permission checking for this function is managed through the normal
+ * GRANT system.
  */
 Datum
 pg_stat_file(PG_FUNCTION_ARGS)
@@ -312,11 +311,6 @@ pg_stat_file(PG_FUNCTION_ARGS)
 	TupleDesc	tupdesc;
 	bool		missing_ok = false;
 
-	if (!superuser())
-		ereport(ERROR,
-				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-				 (errmsg("must be superuser to get file information"))));
-
 	/* check the optional argument */
 	if (PG_NARGS() == 2)
 		missing_ok = PG_GETARG_BOOL(1);
@@ -389,6 +383,9 @@ pg_stat_file_1arg(PG_FUNCTION_ARGS)
 
 /*
  * List a directory (returns the filenames only)
+ *
+ * Permission checking for this function is managed through the normal
+ * GRANT system.
  */
 Datum
 pg_ls_dir(PG_FUNCTION_ARGS)
@@ -398,11 +395,6 @@ pg_ls_dir(PG_FUNCTION_ARGS)
 	directory_fctx *fctx;
 	MemoryContext oldcontext;
 
-	if (!superuser())
-		ereport(ERROR,
-				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-				 (errmsg("must be superuser to get directory listings"))));
-
 	if (SRF_IS_FIRSTCALL())
 	{
 		bool		missing_ok = false;
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index f66b443..7da6826 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -582,6 +582,56 @@ SELECT testfunc1(5); -- ok
 
 DROP FUNCTION testfunc1(int); -- fail
 ERROR:  must be owner of function testfunc1
+-- try to use built-in functions that are superuser-only by default
+-- these should all fail with permissions errors
+SELECT pg_start_backup('regress', false, false);
+ERROR:  permission denied for function pg_start_backup
+SELECT pg_stop_backup();
+ERROR:  permission denied for function pg_stop_backup
+SELECT pg_stop_backup(false);
+ERROR:  permission denied for function pg_stop_backup
+SELECT pg_create_restore_point('regress');
+ERROR:  permission denied for function pg_create_restore_point
+SELECT pg_switch_xlog();
+ERROR:  permission denied for function pg_switch_xlog
+SELECT pg_xlog_replay_pause();
+ERROR:  permission denied for function pg_xlog_replay_pause
+SELECT pg_xlog_replay_resume();
+ERROR:  permission denied for function pg_xlog_replay_resume
+SELECT pg_rotate_logfile();
+ERROR:  permission denied for function pg_rotate_logfile
+SELECT pg_reload_conf();
+ERROR:  permission denied for function pg_reload_conf
+SELECT pg_import_system_collations(false, 'public'::regnamespace);
+ERROR:  permission denied for function pg_import_system_collations
+SELECT pg_stat_reset();
+ERROR:  permission denied for function pg_stat_reset
+SELECT pg_stat_reset_shared('regress');
+ERROR:  permission denied for function pg_stat_reset_shared
+SELECT pg_stat_reset_single_table_counters(0);
+ERROR:  permission denied for function pg_stat_reset_single_table_counters
+SELECT pg_stat_reset_single_function_counters(0);
+ERROR:  permission denied for function pg_stat_reset_single_function_counters
+SELECT pg_read_binary_file('regress');
+ERROR:  permission denied for function pg_read_binary_file
+SELECT pg_read_binary_file('regress', 0, 0);
+ERROR:  permission denied for function pg_read_binary_file
+SELECT pg_read_binary_file('regress', 0, 0, false);
+ERROR:  permission denied for function pg_read_binary_file
+SELECT pg_read_file('regress');
+ERROR:  permission denied for function pg_read_file
+SELECT pg_read_file('regress', 0, 0);
+ERROR:  permission denied for function pg_read_file
+SELECT pg_read_file('regress', 0, 0, false);
+ERROR:  permission denied for function pg_read_file
+SELECT pg_stat_file('regress');
+ERROR:  permission denied for function pg_stat_file
+SELECT pg_stat_file('regress', false);
+ERROR:  permission denied for function pg_stat_file
+SELECT pg_ls_dir('regress');
+ERROR:  permission denied for function pg_ls_dir
+SELECT pg_ls_dir('regress', false, false);
+ERROR:  permission denied for function pg_ls_dir
 \c -
 DROP FUNCTION testfunc1(int); -- ok
 -- restore to sanity
diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql
index 00dc7bd..a3011b9 100644
--- a/src/test/regress/sql/privileges.sql
+++ b/src/test/regress/sql/privileges.sql
@@ -392,6 +392,33 @@ SELECT testfunc1(5); -- ok
 
 DROP FUNCTION testfunc1(int); -- fail
 
+-- try to use built-in functions that are superuser-only by default
+-- these should all fail with permissions errors
+SELECT pg_start_backup('regress', false, false);
+SELECT pg_stop_backup();
+SELECT pg_stop_backup(false);
+SELECT pg_create_restore_point('regress');
+SELECT pg_switch_xlog();
+SELECT pg_xlog_replay_pause();
+SELECT pg_xlog_replay_resume();
+SELECT pg_rotate_logfile();
+SELECT pg_reload_conf();
+SELECT pg_import_system_collations(false, 'public'::regnamespace);
+SELECT pg_stat_reset();
+SELECT pg_stat_reset_shared('regress');
+SELECT pg_stat_reset_single_table_counters(0);
+SELECT pg_stat_reset_single_function_counters(0);
+SELECT pg_read_binary_file('regress');
+SELECT pg_read_binary_file('regress', 0, 0);
+SELECT pg_read_binary_file('regress', 0, 0, false);
+SELECT pg_read_file('regress');
+SELECT pg_read_file('regress', 0, 0);
+SELECT pg_read_file('regress', 0, 0, false);
+SELECT pg_stat_file('regress');
+SELECT pg_stat_file('regress', false);
+SELECT pg_ls_dir('regress');
+SELECT pg_ls_dir('regress', false, false);
+
 \c -
 
 DROP FUNCTION testfunc1(int); -- ok
