aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Stephani2020-12-14 21:25:11 +0100
committerPhilipp Stephani2021-04-10 20:37:29 +0200
commit8a84f97abed548e4a254a9b855c3f79dac8c3d5d (patch)
treeff11125ebe50e1772fbfb0336f156571aed0baef
parent15122b31040f8945d0998510abd52c7735b36bc7 (diff)
downloademacs-8a84f97abed548e4a254a9b855c3f79dac8c3d5d.tar.gz
emacs-8a84f97abed548e4a254a9b855c3f79dac8c3d5d.zip
Read file in a loop if necessary.
This allows for short reads from 'emacs_read'. * src/emacs.c (read_full): New helper function. (load_seccomp): Use it.
-rw-r--r--src/emacs.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/src/emacs.c b/src/emacs.c
index b956e9ca34b..8658b1886ed 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -967,6 +967,43 @@ emacs_seccomp (unsigned int operation, unsigned int flags, void *args)
967#endif 967#endif
968} 968}
969 969
970/* Read SIZE bytes into BUFFER. Return the number of bytes read, or
971 -1 if reading failed altogether. */
972
973static ptrdiff_t
974read_full (int fd, void *buffer, ptrdiff_t size)
975{
976 enum
977 {
978 /* See MAX_RW_COUNT in sysdep.c. */
979#ifdef MAX_RW_COUNT
980 max_size = MAX_RW_COUNT
981#else
982 max_size = INT_MAX >> 18 << 18
983#endif
984 };
985 if (PTRDIFF_MAX < size || max_size < size)
986 {
987 errno = EFBIG;
988 return -1;
989 }
990 char *ptr = buffer;
991 ptrdiff_t read = 0;
992 while (size != 0)
993 {
994 ptrdiff_t n = emacs_read (fd, ptr, size);
995 if (n < 0)
996 return -1;
997 if (n == 0)
998 break; /* Avoid infinite loop on encountering EOF. */
999 eassert (n <= size);
1000 size -= n;
1001 ptr += n;
1002 read += n;
1003 }
1004 return read;
1005}
1006
970/* Attempt to load Secure Computing filters from FILE. Return false 1007/* Attempt to load Secure Computing filters from FILE. Return false
971 if that doesn't work for some reason. */ 1008 if that doesn't work for some reason. */
972 1009
@@ -993,18 +1030,9 @@ load_seccomp (const char *file)
993 fprintf (stderr, "seccomp file %s is not regular\n", file); 1030 fprintf (stderr, "seccomp file %s is not regular\n", file);
994 goto out; 1031 goto out;
995 } 1032 }
996 enum
997 {
998 /* See MAX_RW_COUNT in sysdep.c. */
999#ifdef MAX_RW_COUNT
1000 max_read_size = MAX_RW_COUNT
1001#else
1002 max_read_size = INT_MAX >> 18 << 18
1003#endif
1004 };
1005 struct sock_fprog program; 1033 struct sock_fprog program;
1006 if (stat.st_size <= 0 || SIZE_MAX <= stat.st_size 1034 if (stat.st_size <= 0 || SIZE_MAX <= stat.st_size
1007 || PTRDIFF_MAX <= stat.st_size || max_read_size < stat.st_size 1035 || PTRDIFF_MAX <= stat.st_size
1008 || stat.st_size % sizeof *program.filter != 0) 1036 || stat.st_size % sizeof *program.filter != 0)
1009 { 1037 {
1010 fprintf (stderr, "seccomp filter %s has invalid size %ld\n", 1038 fprintf (stderr, "seccomp filter %s has invalid size %ld\n",
@@ -1026,7 +1054,7 @@ load_seccomp (const char *file)
1026 emacs_perror ("malloc"); 1054 emacs_perror ("malloc");
1027 goto out; 1055 goto out;
1028 } 1056 }
1029 ptrdiff_t read = emacs_read (fd, buffer, size + 1); 1057 ptrdiff_t read = read_full (fd, buffer, size + 1);
1030 if (read < 0) 1058 if (read < 0)
1031 { 1059 {
1032 emacs_perror ("read"); 1060 emacs_perror ("read");