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'.
This commit is contained in:
Paul Eggert 2013-08-23 19:23:34 -07:00
parent 2d85dc347c
commit 9c05bccfb9
3 changed files with 55 additions and 29 deletions

View 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.

View 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;

View 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;