]> git.eshelyaron.com Git - emacs.git/commitdiff
System-dependent integer overflow fixes.
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 24 Aug 2013 02:23:34 +0000 (19:23 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 24 Aug 2013 02:23:34 +0000 (19:23 -0700)
* process.c (Fset_process_window_size): Signal an error if
the window size is outside the range supported by the lower level.
* sysdep.c (set_window_size): Return negative on error,
nonnegative on success, rather than -1, 0, 1 on not in system,
failure, success.  This is simpler.  Caller changed.
(serial_configure): Remove unnecessary initialization of local.
(procfs_get_total_memory) [GNU_LINUX]: Don't assume system memory
size fits in unsigned long; this isn't true on some 32-bit hosts.
Avoid buffer overrun if some future version of /proc/meminfo has a
variable name longer than 20 bytes.
(system_process_attributes) [__FreeBSD__]:
Don't assume hw.availpages fits in 'int'.

src/ChangeLog
src/process.c
src/sysdep.c

index 73fdb0221ce1f69dc26524d3baf740c9fe6bcc35..3eccf6ff5573194f06253c476f40c06e78cbf085 100644 (file)
@@ -1,3 +1,19 @@
+2013-08-24  Paul Eggert  <eggert@cs.ucla.edu>
+
+       System-dependent integer overflow fixes.
+       * process.c (Fset_process_window_size): Signal an error if
+       the window size is outside the range supported by the lower level.
+       * sysdep.c (set_window_size): Return negative on error,
+       nonnegative on success, rather than -1, 0, 1 on not in system,
+       failure, success.  This is simpler.  Caller changed.
+       (serial_configure): Remove unnecessary initialization of local.
+       (procfs_get_total_memory) [GNU_LINUX]: Don't assume system memory
+       size fits in unsigned long; this isn't true on some 32-bit hosts.
+       Avoid buffer overrun if some future version of /proc/meminfo has a
+       variable name longer than 20 bytes.
+       (system_process_attributes) [__FreeBSD__]:
+       Don't assume hw.availpages fits in 'int'.
+
 2013-08-23  Paul Eggert  <eggert@cs.ucla.edu>
 
        Don't let very long directory names overrun the stack.
index ea1129ffbb886dba97c36103044e80dbdd525eb8..c5e691bf602ff28d4879c3f21f9bcf1255120499 100644 (file)
@@ -1140,15 +1140,18 @@ See `set-process-sentinel' for more info on sentinels.  */)
 DEFUN ("set-process-window-size", Fset_process_window_size,
        Sset_process_window_size, 3, 3, 0,
        doc: /* Tell PROCESS that it has logical window size HEIGHT and WIDTH.  */)
-  (register Lisp_Object process, Lisp_Object height, Lisp_Object width)
+  (Lisp_Object process, Lisp_Object height, Lisp_Object width)
 {
   CHECK_PROCESS (process);
-  CHECK_RANGED_INTEGER (height, 0, INT_MAX);
-  CHECK_RANGED_INTEGER (width, 0, INT_MAX);
+
+  /* All known platforms store window sizes as 'unsigned short'.  */
+  CHECK_RANGED_INTEGER (height, 0, USHRT_MAX);
+  CHECK_RANGED_INTEGER (width, 0, USHRT_MAX);
 
   if (XPROCESS (process)->infd < 0
-      || set_window_size (XPROCESS (process)->infd,
-                         XINT (height), XINT (width)) <= 0)
+      || (set_window_size (XPROCESS (process)->infd,
+                          XINT (height), XINT (width))
+         < 0))
     return Qnil;
   else
     return Qt;
index c6d5f9942ab56430631bfeff26821110f519e744..0d7325265287001dd158ce338021e51b8210827e 100644 (file)
@@ -1170,7 +1170,8 @@ get_tty_size (int fd, int *widthp, int *heightp)
 }
 
 /* Set the logical window size associated with descriptor FD
-   to HEIGHT and WIDTH.  This is used mainly with ptys.  */
+   to HEIGHT and WIDTH.  This is used mainly with ptys.
+   Return a negative value on failure.  */
 
 int
 set_window_size (int fd, int height, int width)
@@ -1182,10 +1183,7 @@ set_window_size (int fd, int height, int width)
   size.ws_row = height;
   size.ws_col = width;
 
-  if (ioctl (fd, TIOCSWINSZ, &size) == -1)
-    return 0; /* error */
-  else
-    return 1;
+  return ioctl (fd, TIOCSWINSZ, &size);
 
 #else
 #ifdef TIOCSSIZE
@@ -1195,10 +1193,7 @@ set_window_size (int fd, int height, int width)
   size.ts_lines = height;
   size.ts_cols = width;
 
-  if (ioctl (fd, TIOCGSIZE, &size) == -1)
-    return 0;
-  else
-    return 1;
+  return ioctl (fd, TIOCGSIZE, &size);
 #else
   return -1;
 #endif /* not SunOS-style */
@@ -2459,7 +2454,7 @@ serial_configure (struct Lisp_Process *p,
   Lisp_Object childp2 = Qnil;
   Lisp_Object tem = Qnil;
   struct termios attr;
-  int err = -1;
+  int err;
   char summary[4] = "???"; /* This usually becomes "8N1".  */
 
   childp2 = Fcopy_sequence (p->childp);
@@ -2826,29 +2821,41 @@ procfs_ttyname (int rdev)
   return build_string (name);
 }
 
-static unsigned long
+static uintmax_t
 procfs_get_total_memory (void)
 {
   FILE *fmem;
-  unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */
+  uintmax_t retval = 2 * 1024 * 1024; /* default: 2 GiB */
+  int c;
 
   block_input ();
   fmem = emacs_fopen ("/proc/meminfo", "r");
 
   if (fmem)
     {
-      unsigned long entry_value;
-      char entry_name[20];     /* the longest I saw is 13+1 */
+      uintmax_t entry_value;
+      bool done;
+
+      do
+       switch (fscanf (fmem, "MemTotal: %"SCNuMAX, &entry_value))
+         {
+         case 1:
+           retval = entry_value;
+           done = 1;
+           break;
+
+         case 0:
+           while ((c = getc (fmem)) != EOF && c != '\n')
+             continue;
+           done = c == EOF;
+           break;
+
+         default:
+           done = 1;
+           break;
+         }
+      while (!done);
 
-      while (!feof (fmem) && !ferror (fmem))
-       {
-         if (fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value) >= 2
-             && strcmp (entry_name, "MemTotal:") == 0)
-           {
-             retval = entry_value;
-             break;
-           }
-       }
       fclose (fmem);
     }
   unblock_input ();
@@ -3249,7 +3256,7 @@ system_process_attributes (Lisp_Object pid)
 {
   int proc_id;
   int pagesize = getpagesize ();
-  int npages;
+  unsigned long npages;
   int fscale;
   struct passwd *pw;
   struct group  *gr;