mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
Compare commits
23
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ebb47c83a | ||
|
|
a940444601 | ||
|
|
a225d5f34e | ||
|
|
64f548f29d | ||
|
|
a437630a8c | ||
|
|
c92cfee45d | ||
|
|
9ff423a7d9 | ||
|
|
8572a12667 | ||
|
|
4c783325c1 | ||
|
|
044fa52655 | ||
|
|
3ea2671c8d | ||
|
|
19a7f1a9de | ||
|
|
a2bc8b03d8 | ||
|
|
615a439a9e | ||
|
|
1a15dd91ff | ||
|
|
299c870ea6 | ||
|
|
6ab589eba7 | ||
|
|
56d478fbea | ||
|
|
1c464c822e | ||
|
|
7cd945dd92 | ||
|
|
2ccb8fa10b | ||
|
|
d02dfb867e | ||
|
|
c07f4f5d50 |
No files matched your search
@@ -14,6 +14,59 @@ minimal number of processes, if possible, for that patch. For those
|
||||
updates that don't have an advisory, or to be safe, you can do a full
|
||||
build and install as described in the COMMON ITEMS section.
|
||||
|
||||
20050406: p14 FreeBSD-SA-05:03.amd64
|
||||
Correctly initialize the I/O permission bitmap on amd64.
|
||||
|
||||
20041201: p13 FreeBSD-SA-04:17.procfs
|
||||
Fix a tainted pointer dereference in procfs(5) and linprocfs(5)
|
||||
which could allow a local attacker to panic a system and/or read
|
||||
from kernel memory.
|
||||
|
||||
20041118: p12 FreeBSD-SA-04:16.fetch
|
||||
Correct a buffer overflow in fetch(1) which could allow a
|
||||
mallicious server to execute arbitrary code on the client.
|
||||
|
||||
20041003: p11 FreeBSD-SA-04:15.syscons
|
||||
Correct a kernel memory disclosure vulnerability in syscons(4).
|
||||
|
||||
20040919: p10 FreeBSD-SA-04:14.cvs
|
||||
Correct several vulnerabilities in CVS (CAN-2004-0414,
|
||||
CAN-2004-0416, CAN-2004-0417, CAN-2004-0418, CAN-2004-0778).
|
||||
|
||||
20040630: p9 FreeBSD-SA-04:13.linux
|
||||
Correct an input validation error in the linux binary
|
||||
compatibility code.
|
||||
|
||||
20040526: p8 FreeBSD-SA-04:11.msync
|
||||
Fix a bug in msync(2) which could cause it to discard dirty
|
||||
pages.
|
||||
|
||||
NOTE: In some cases involving NFS, the incorrect behaviour may
|
||||
actually be preferrable. Setting the vm.old_msync sysctl
|
||||
variable to 1 will revert msync(2) to its old behaviour.
|
||||
|
||||
20040519: p7 FreeBSD-SA-04:10.cvs
|
||||
Correct a heap overflow in cvs's pserver protocol parser.
|
||||
|
||||
20040505: p6 FreeBSD-SA-04:08.heimdal
|
||||
Correctly validate the transited field in Kerberos tickets.
|
||||
|
||||
20040415: p5 FreeBSD-SA-04:07.cvs
|
||||
Correct some path validation errors in CVS.
|
||||
|
||||
20040329: p4 FreeBSD-SA-04:06.ipv6
|
||||
Correct an input validation error involving setsockopt and
|
||||
IPv6 sockets.
|
||||
|
||||
20040317: p3 FreeBSD-SA-04:05.openssl
|
||||
Correct a denial-of-service vulnerability in OpenSSL.
|
||||
|
||||
20040316: p2
|
||||
Improvement of FreeBSD-SA-04:04.tcp fix.
|
||||
|
||||
20040302: p1 FreeBSD-SA-04:04.tcp
|
||||
Limit TCP segment reassembly queue size.
|
||||
|
||||
20040222:
|
||||
FreeBSD 5.2.1 RELEASE
|
||||
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/* xsize.h -- Checked size_t computations.
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _XSIZE_H
|
||||
#define _XSIZE_H
|
||||
|
||||
/* Get size_t. */
|
||||
#include <stddef.h>
|
||||
|
||||
/* Get SIZE_MAX. */
|
||||
#include <limits.h>
|
||||
#if HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#else
|
||||
#define SIZE_MAX UINT_MAX /* XXX */
|
||||
#endif
|
||||
|
||||
/* The size of memory objects is often computed through expressions of
|
||||
type size_t. Example:
|
||||
void* p = malloc (header_size + n * element_size).
|
||||
These computations can lead to overflow. When this happens, malloc()
|
||||
returns a piece of memory that is way too small, and the program then
|
||||
crashes while attempting to fill the memory.
|
||||
To avoid this, the functions and macros in this file check for overflow.
|
||||
The convention is that SIZE_MAX represents overflow.
|
||||
malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc
|
||||
implementation that uses mmap --, it's recommended to use size_overflow_p()
|
||||
or size_in_bounds_p() before invoking malloc().
|
||||
The example thus becomes:
|
||||
size_t size = xsum (header_size, xtimes (n, element_size));
|
||||
void *p = (size_in_bounds_p (size) ? malloc (size) : NULL);
|
||||
*/
|
||||
|
||||
/* Convert an arbitrary value >= 0 to type size_t. */
|
||||
#define xcast_size_t(N) \
|
||||
((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX)
|
||||
|
||||
/* Sum of two sizes, with overflow check. */
|
||||
static inline size_t
|
||||
#if __GNUC__ >= 3
|
||||
__attribute__ ((__pure__))
|
||||
#endif
|
||||
xsum (size_t size1, size_t size2)
|
||||
{
|
||||
size_t sum = size1 + size2;
|
||||
return (sum >= size1 ? sum : SIZE_MAX);
|
||||
}
|
||||
|
||||
/* Sum of three sizes, with overflow check. */
|
||||
static inline size_t
|
||||
#if __GNUC__ >= 3
|
||||
__attribute__ ((__pure__))
|
||||
#endif
|
||||
xsum3 (size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
return xsum (xsum (size1, size2), size3);
|
||||
}
|
||||
|
||||
/* Sum of four sizes, with overflow check. */
|
||||
static inline size_t
|
||||
#if __GNUC__ >= 3
|
||||
__attribute__ ((__pure__))
|
||||
#endif
|
||||
xsum4 (size_t size1, size_t size2, size_t size3, size_t size4)
|
||||
{
|
||||
return xsum (xsum (xsum (size1, size2), size3), size4);
|
||||
}
|
||||
|
||||
/* Maximum of two sizes, with overflow check. */
|
||||
static inline size_t
|
||||
#if __GNUC__ >= 3
|
||||
__attribute__ ((__pure__))
|
||||
#endif
|
||||
xmax (size_t size1, size_t size2)
|
||||
{
|
||||
/* No explicit check is needed here, because for any n:
|
||||
max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX. */
|
||||
return (size1 >= size2 ? size1 : size2);
|
||||
}
|
||||
|
||||
/* Multiplication of a count with an element size, with overflow check.
|
||||
The count must be >= 0 and the element size must be > 0.
|
||||
This is a macro, not an inline function, so that it works correctly even
|
||||
when N is of a wider tupe and N > SIZE_MAX. */
|
||||
#define xtimes(N, ELSIZE) \
|
||||
((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX)
|
||||
|
||||
/* Check for overflow. */
|
||||
#define size_overflow_p(SIZE) \
|
||||
((SIZE) == SIZE_MAX)
|
||||
/* Check against overflow. */
|
||||
#define size_in_bounds_p(SIZE) \
|
||||
((SIZE) != SIZE_MAX)
|
||||
|
||||
#endif /* _XSIZE_H */
|
||||
@@ -1054,6 +1054,19 @@ call_in_directory (pathname, func, data)
|
||||
char *rdirp;
|
||||
int reposdirname_absolute;
|
||||
|
||||
/* For security reasons, if PATHNAME is absolute or attemps to ascend
|
||||
* outside of the current sanbbox, we abort. The server should not send us
|
||||
* anything but relative paths which remain inside the sandbox here.
|
||||
* Anything less means a trojan CVS server could create and edit arbitrary
|
||||
* files on the client.
|
||||
*/
|
||||
if (isabsolute (pathname) || pathname_levels (pathname) > 0)
|
||||
{
|
||||
error (0, 0,
|
||||
"Server attempted to update a file via an invalid pathname:");
|
||||
error (1, 0, "`%s'.", pathname);
|
||||
}
|
||||
|
||||
reposname = NULL;
|
||||
read_line (&reposname);
|
||||
assert (reposname != NULL);
|
||||
|
||||
@@ -481,7 +481,12 @@ commit (argc, argv)
|
||||
operate on, and only work with those files in the future.
|
||||
This saves time--we don't want to search the file system
|
||||
of the working directory twice. */
|
||||
find_args.argv = (char **) xmalloc (find_args.argc * sizeof (char **));
|
||||
if (size_overflow_p (xtimes (find_args.argc, sizeof (char **))))
|
||||
{
|
||||
find_args.argc = 0;
|
||||
return 0;
|
||||
}
|
||||
find_args.argv = xmalloc (xtimes (find_args.argc, sizeof (char **)));
|
||||
find_args.argc = 0;
|
||||
walklist (find_args.ulist, copy_ulist, &find_args);
|
||||
|
||||
|
||||
@@ -41,6 +41,10 @@
|
||||
#include "popen.h"
|
||||
#endif
|
||||
|
||||
/* Begin GNULIB headers. */
|
||||
#include "xsize.h"
|
||||
/* End GNULIB headers. */
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
|
||||
@@ -988,8 +988,14 @@ expand_wild (argc, argv, pargc, pargv)
|
||||
char ***pargv;
|
||||
{
|
||||
int i;
|
||||
if (size_overflow_p (xtimes (argc, sizeof (char *)))) {
|
||||
*pargc = 0;
|
||||
*pargv = NULL;
|
||||
error (0, 0, "expand_wild: too many arguments");
|
||||
return;
|
||||
}
|
||||
*pargc = argc;
|
||||
*pargv = (char **) xmalloc (argc * sizeof (char *));
|
||||
*pargv = xmalloc (xtimes (argc, sizeof (char *)));
|
||||
for (i = 0; i < argc; ++i)
|
||||
(*pargv)[i] = xstrdup (argv[i]);
|
||||
}
|
||||
|
||||
@@ -414,8 +414,11 @@ history (argc, argv)
|
||||
working = 1;
|
||||
break;
|
||||
case 'X': /* Undocumented debugging flag */
|
||||
#ifdef DEBUG
|
||||
histfile = optarg;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'D': /* Since specified date */
|
||||
if (*since_rev || *since_tag || *backto)
|
||||
{
|
||||
@@ -890,9 +893,13 @@ save_user (name)
|
||||
{
|
||||
if (user_count == user_max)
|
||||
{
|
||||
user_max += USER_INCREMENT;
|
||||
user_list = (char **) xrealloc ((char *) user_list,
|
||||
(int) user_max * sizeof (char *));
|
||||
user_max = xsum (user_max, USER_INCREMENT);
|
||||
if (size_overflow_p (xtimes (user_max, sizeof (char *))))
|
||||
{
|
||||
error (0, 0, "save_user: too many users");
|
||||
return;
|
||||
}
|
||||
user_list = xrealloc (user_list, xtimes (user_max, sizeof (char *)));
|
||||
}
|
||||
user_list[user_count++] = xstrdup (name);
|
||||
}
|
||||
@@ -920,9 +927,13 @@ save_file (dir, name, module)
|
||||
|
||||
if (file_count == file_max)
|
||||
{
|
||||
file_max += FILE_INCREMENT;
|
||||
file_list = (struct file_list_str *) xrealloc ((char *) file_list,
|
||||
file_max * sizeof (*fl));
|
||||
file_max = xsum (file_max, FILE_INCREMENT);
|
||||
if (size_overflow_p (xtimes (file_max, sizeof (*fl))))
|
||||
{
|
||||
error (0, 0, "save_file: too many files");
|
||||
return;
|
||||
}
|
||||
file_list = xrealloc (file_list, xtimes (file_max, sizeof (*fl)));
|
||||
}
|
||||
fl = &file_list[file_count++];
|
||||
fl->l_file = cp = xmalloc (strlen (dir) + strlen (name) + 2);
|
||||
@@ -961,9 +972,13 @@ save_module (module)
|
||||
{
|
||||
if (mod_count == mod_max)
|
||||
{
|
||||
mod_max += MODULE_INCREMENT;
|
||||
mod_list = (char **) xrealloc ((char *) mod_list,
|
||||
mod_max * sizeof (char *));
|
||||
mod_max = xsum (mod_max, MODULE_INCREMENT);
|
||||
if (size_overflow_p (xtimes (mod_max, sizeof (char *))))
|
||||
{
|
||||
error (0, 0, "save_module: too many modules");
|
||||
return;
|
||||
}
|
||||
mod_list = xrealloc (mod_list, xtimes (mod_max, sizeof (char *)));
|
||||
}
|
||||
mod_list[mod_count++] = xstrdup (module);
|
||||
}
|
||||
|
||||
@@ -170,6 +170,32 @@ do_module (db, mname, m_type, msg, callback_proc, where, shorten,
|
||||
if (isabsolute (mname))
|
||||
error (1, 0, "Absolute module reference invalid: `%s'", mname);
|
||||
|
||||
/* Similarly for directories that attempt to step above the root of the
|
||||
* repository.
|
||||
*/
|
||||
if (pathname_levels (mname) > 0)
|
||||
error (1, 0, "up-level in module reference (`..') invalid: `%s'.",
|
||||
mname);
|
||||
|
||||
|
||||
/* Don't process absolute directories. Anything else could be a security
|
||||
* problem. Before this check was put in place:
|
||||
*
|
||||
* $ cvs -d:fork:/cvsroot co /foo
|
||||
* cvs server: warning: cannot make directory CVS in /: Permission denied
|
||||
* cvs [server aborted]: cannot make directory /foo: Permission denied
|
||||
* $
|
||||
*/
|
||||
if (isabsolute (mname))
|
||||
error (1, 0, "Absolute module reference invalid: `%s'", mname);
|
||||
|
||||
/* Similarly for directories that attempt to step above the root of the
|
||||
* repository.
|
||||
*/
|
||||
if (pathname_levels (mname) > 0)
|
||||
error (1, 0, "up-level in module reference (`..') invalid: `%s'.",
|
||||
mname);
|
||||
|
||||
/* if this is a directory to ignore, add it to that list */
|
||||
if (mname[0] == '!' && mname[1] != '\0')
|
||||
{
|
||||
|
||||
+106
-10
@@ -927,7 +927,7 @@ serve_max_dotdot (arg)
|
||||
int i;
|
||||
char *p;
|
||||
|
||||
if (lim < 0)
|
||||
if (lim < 0 || lim > 10000)
|
||||
return;
|
||||
p = xmalloc (strlen (server_temp_dir) + 2 * lim + 10);
|
||||
if (p == NULL)
|
||||
@@ -1647,9 +1647,28 @@ serve_unchanged (arg)
|
||||
&& strlen (arg) == cp - name
|
||||
&& strncmp (arg, name, cp - name) == 0)
|
||||
{
|
||||
timefield = strchr (cp + 1, '/') + 1;
|
||||
if (*timefield != '=')
|
||||
if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0')
|
||||
{
|
||||
/* We didn't find the record separator or it is followed by
|
||||
* the end of the string, so just exit.
|
||||
*/
|
||||
if (alloc_pending (80))
|
||||
sprintf (pending_error_text,
|
||||
"E Malformed Entry encountered.");
|
||||
return;
|
||||
}
|
||||
/* If the time field is not currently empty, then one of
|
||||
* serve_modified, serve_is_modified, & serve_unchanged were
|
||||
* already called for this file. We would like to ignore the
|
||||
* reinvocation silently or, better yet, exit with an error
|
||||
* message, but we just avoid the copy-forward and overwrite the
|
||||
* value from the last invocation instead. See the comment below
|
||||
* for more.
|
||||
*/
|
||||
if (*timefield == '/')
|
||||
{
|
||||
/* Copy forward one character. Space was allocated for this
|
||||
* already in serve_entry(). */
|
||||
cp = timefield + strlen (timefield);
|
||||
cp[1] = '\0';
|
||||
while (cp > timefield)
|
||||
@@ -1657,8 +1676,17 @@ serve_unchanged (arg)
|
||||
*cp = cp[-1];
|
||||
--cp;
|
||||
}
|
||||
*timefield = '=';
|
||||
}
|
||||
/* If *TIMEFIELD wasn't "/", we assume that it was because of
|
||||
* multiple calls to Is-Modified & Unchanged by the client and
|
||||
* just overwrite the value from the last call. Technically, we
|
||||
* should probably either ignore calls after the first or send the
|
||||
* client an error, since the client/server protocol specification
|
||||
* specifies that only one call to either Is-Modified or Unchanged
|
||||
* is allowed, but broken versions of WinCVS & TortoiseCVS rely on
|
||||
* this behavior.
|
||||
*/
|
||||
*timefield = '=';
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1691,9 +1719,28 @@ serve_is_modified (arg)
|
||||
&& strlen (arg) == cp - name
|
||||
&& strncmp (arg, name, cp - name) == 0)
|
||||
{
|
||||
timefield = strchr (cp + 1, '/') + 1;
|
||||
if (!(timefield[0] == 'M' && timefield[1] == '/'))
|
||||
if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0')
|
||||
{
|
||||
/* We didn't find the record separator or it is followed by
|
||||
* the end of the string, so just exit.
|
||||
*/
|
||||
if (alloc_pending (80))
|
||||
sprintf (pending_error_text,
|
||||
"E Malformed Entry encountered.");
|
||||
return;
|
||||
}
|
||||
/* If the time field is not currently empty, then one of
|
||||
* serve_modified, serve_is_modified, & serve_unchanged were
|
||||
* already called for this file. We would like to ignore the
|
||||
* reinvocation silently or, better yet, exit with an error
|
||||
* message, but we just avoid the copy-forward and overwrite the
|
||||
* value from the last invocation instead. See the comment below
|
||||
* for more.
|
||||
*/
|
||||
if (*timefield == '/')
|
||||
{
|
||||
/* Copy forward one character. Space was allocated for this
|
||||
* already in serve_entry(). */
|
||||
cp = timefield + strlen (timefield);
|
||||
cp[1] = '\0';
|
||||
while (cp > timefield)
|
||||
@@ -1701,8 +1748,17 @@ serve_is_modified (arg)
|
||||
*cp = cp[-1];
|
||||
--cp;
|
||||
}
|
||||
*timefield = 'M';
|
||||
}
|
||||
/* If *TIMEFIELD wasn't "/", we assume that it was because of
|
||||
* multiple calls to Is-Modified & Unchanged by the client and
|
||||
* just overwrite the value from the last call. Technically, we
|
||||
* should probably either ignore calls after the first or send the
|
||||
* client an error, since the client/server protocol specification
|
||||
* specifies that only one call to either Is-Modified or Unchanged
|
||||
* is allowed, but broken versions of WinCVS & TortoiseCVS rely on
|
||||
* this behavior.
|
||||
*/
|
||||
*timefield = 'M';
|
||||
if (kopt != NULL)
|
||||
{
|
||||
if (alloc_pending (strlen (name) + 80))
|
||||
@@ -1757,8 +1813,29 @@ serve_entry (arg)
|
||||
{
|
||||
struct an_entry *p;
|
||||
char *cp;
|
||||
int i = 0;
|
||||
if (error_pending()) return;
|
||||
p = (struct an_entry *) xmalloc (sizeof (struct an_entry));
|
||||
|
||||
/* Verify that the entry is well-formed. This can avoid problems later.
|
||||
* At the moment we only check that the Entry contains five slashes in
|
||||
* approximately the correct locations since some of the code makes
|
||||
* assumptions about this.
|
||||
*/
|
||||
cp = arg;
|
||||
if (*cp == 'D') cp++;
|
||||
while (i++ < 5)
|
||||
{
|
||||
if (!cp || *cp != '/')
|
||||
{
|
||||
if (alloc_pending (80))
|
||||
sprintf (pending_error_text,
|
||||
"E protocol error: Malformed Entry");
|
||||
return;
|
||||
}
|
||||
cp = strchr (cp + 1, '/');
|
||||
}
|
||||
|
||||
p = xmalloc (sizeof (struct an_entry));
|
||||
if (p == NULL)
|
||||
{
|
||||
pending_error = ENOMEM;
|
||||
@@ -1990,6 +2067,9 @@ serve_notify (arg)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (!data[0])
|
||||
goto error;
|
||||
|
||||
if (strchr (data, '+'))
|
||||
goto error;
|
||||
|
||||
@@ -2122,6 +2202,14 @@ serve_argument (arg)
|
||||
|
||||
if (error_pending()) return;
|
||||
|
||||
if (argument_count >= 10000)
|
||||
{
|
||||
if (alloc_pending (80))
|
||||
sprintf (pending_error_text,
|
||||
"E Protocol error: too many arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
if (argument_vector_size <= argument_count)
|
||||
{
|
||||
argument_vector_size *= 2;
|
||||
@@ -2152,6 +2240,14 @@ serve_argumentx (arg)
|
||||
|
||||
if (error_pending()) return;
|
||||
|
||||
if (argument_count <= 1)
|
||||
{
|
||||
if (alloc_pending (80))
|
||||
sprintf (pending_error_text,
|
||||
"E Protocol error: called argumentx without prior call to argument");
|
||||
return;
|
||||
}
|
||||
|
||||
p = argument_vector[argument_count - 1];
|
||||
p = xrealloc (p, strlen (p) + 1 + strlen (arg) + 1);
|
||||
if (p == NULL)
|
||||
@@ -2508,7 +2604,7 @@ check_command_legal_p (cmd_name)
|
||||
save some code here... -kff */
|
||||
|
||||
/* Chop newline by hand, for strcmp()'s sake. */
|
||||
if (linebuf[num_red - 1] == '\n')
|
||||
if (num_red > 0 && linebuf[num_red - 1] == '\n')
|
||||
linebuf[num_red - 1] = '\0';
|
||||
|
||||
if (strcmp (linebuf, CVS_Username) == 0)
|
||||
@@ -2563,7 +2659,7 @@ check_command_legal_p (cmd_name)
|
||||
while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0)
|
||||
{
|
||||
/* Chop newline by hand, for strcmp()'s sake. */
|
||||
if (linebuf[num_red - 1] == '\n')
|
||||
if (num_red > 0 && linebuf[num_red - 1] == '\n')
|
||||
linebuf[num_red - 1] = '\0';
|
||||
|
||||
if (strcmp (linebuf, CVS_Username) == 0)
|
||||
|
||||
@@ -238,6 +238,30 @@ wrap_unparse_rcs_options (line, first_call_p)
|
||||
}
|
||||
#endif /* SERVER_SUPPORT || CLIENT_SUPPORT */
|
||||
|
||||
/*
|
||||
* Remove fmt str specifier other than %% or %s. And allow
|
||||
* only max_s %s specifiers
|
||||
*/
|
||||
wrap_clean_fmt_str(char *fmt, int max_s)
|
||||
{
|
||||
while (*fmt) {
|
||||
if (fmt[0] == '%' && fmt[1])
|
||||
{
|
||||
if (fmt[1] == '%')
|
||||
fmt++;
|
||||
else
|
||||
if (fmt[1] == 's' && max_s > 0)
|
||||
{
|
||||
max_s--;
|
||||
fmt++;
|
||||
} else
|
||||
*fmt = ' ';
|
||||
}
|
||||
fmt++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open a file and read lines, feeding each line to a line parser. Arrange
|
||||
* for keeping a temporary list of wrappers at the end, if the "temp"
|
||||
@@ -558,9 +582,8 @@ wrap_tocvs_process_file(fileName)
|
||||
args = xmalloc (strlen (e->tocvsFilter)
|
||||
+ strlen (fileName)
|
||||
+ strlen (buf));
|
||||
/* FIXME: sprintf will blow up if the format string contains items other
|
||||
than %s, or contains too many %s's. We should instead be parsing
|
||||
e->tocvsFilter ourselves and giving a real error. */
|
||||
|
||||
wrap_clean_fmt_str(e->tocvsFilter, 2);
|
||||
sprintf (args, e->tocvsFilter, fileName, buf);
|
||||
run_setup (args);
|
||||
run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY );
|
||||
@@ -592,9 +615,8 @@ wrap_fromcvs_process_file(fileName)
|
||||
|
||||
args = xmalloc (strlen (e->fromcvsFilter)
|
||||
+ strlen (fileName));
|
||||
/* FIXME: sprintf will blow up if the format string contains items other
|
||||
than %s, or contains too many %s's. We should instead be parsing
|
||||
e->fromcvsFilter ourselves and giving a real error. */
|
||||
|
||||
wrap_clean_fmt_str(e->fromcvsFilter, 1);
|
||||
sprintf (args, e->fromcvsFilter, fileName);
|
||||
run_setup (args);
|
||||
run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL );
|
||||
|
||||
@@ -64,6 +64,8 @@ krb5_boolean encode_as_rep_as_tgs_rep; /* bug compatibility */
|
||||
krb5_boolean check_ticket_addresses;
|
||||
krb5_boolean allow_null_ticket_addresses;
|
||||
krb5_boolean allow_anonymous;
|
||||
int trpolicy;
|
||||
static const char *trpolicy_str;
|
||||
|
||||
static struct getarg_strings addresses_str; /* addresses to listen on */
|
||||
krb5_addresses explicit_addresses;
|
||||
@@ -293,9 +295,8 @@ configure(int argc, char **argv)
|
||||
|
||||
get_dbinfo();
|
||||
|
||||
if(max_request_str){
|
||||
if(max_request_str)
|
||||
max_request = parse_bytes(max_request_str, NULL);
|
||||
}
|
||||
|
||||
if(max_request == 0){
|
||||
p = krb5_config_get_string (context,
|
||||
@@ -366,6 +367,23 @@ configure(int argc, char **argv)
|
||||
allow_anonymous =
|
||||
krb5_config_get_bool(context, NULL, "kdc",
|
||||
"allow-anonymous", NULL);
|
||||
trpolicy_str =
|
||||
krb5_config_get_string_default(context, NULL, "always-check", "kdc",
|
||||
"transited-policy", NULL);
|
||||
if(strcasecmp(trpolicy_str, "always-check") == 0)
|
||||
trpolicy = TRPOLICY_ALWAYS_CHECK;
|
||||
else if(strcasecmp(trpolicy_str, "allow-per-principal") == 0)
|
||||
trpolicy = TRPOLICY_ALLOW_PER_PRINCIPAL;
|
||||
else if(strcasecmp(trpolicy_str, "always-honour-request") == 0)
|
||||
trpolicy = TRPOLICY_ALWAYS_HONOUR_REQUEST;
|
||||
else {
|
||||
kdc_log(0, "unknown transited-policy: %s, reverting to always-check",
|
||||
trpolicy_str);
|
||||
trpolicy = TRPOLICY_ALWAYS_CHECK;
|
||||
}
|
||||
|
||||
krb5_config_get_bool_default(context, NULL, TRUE, "kdc",
|
||||
"enforce-transited-policy", NULL);
|
||||
#ifdef KRB4
|
||||
if(v4_realm == NULL){
|
||||
p = krb5_config_get_string (context, NULL,
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
.\"
|
||||
.\" $Id: kdc.8,v 1.23 2003/04/06 17:48:40 lha Exp $
|
||||
.\"
|
||||
.Dd August 22, 2002
|
||||
.Dd October 22, 2003
|
||||
.Dt KDC 8
|
||||
.Os HEIMDAL
|
||||
.Sh NAME
|
||||
@@ -185,6 +185,27 @@ Permit tickets with no addresses.
|
||||
This option is only relevant when check-ticket-addresses is TRUE.
|
||||
.It Li allow-anonymous = Va boolean
|
||||
Permit anonymous tickets with no addresses.
|
||||
.It Li transited-policy = Xo
|
||||
.Li always-check \*(Ba
|
||||
.Li allow-per-principal |
|
||||
.Li always-honour-request
|
||||
.Xc
|
||||
This controls how KDC requests with the
|
||||
.Li disable-transited-check
|
||||
flag are handled. It can be one of:
|
||||
.Bl -tag -width "xxx" -offset indent
|
||||
.It Li always-check
|
||||
Always check transited encoding, this is the default.
|
||||
.It Li allow-per-principal
|
||||
Currently this is identical to
|
||||
.Li always-check .
|
||||
In a future release, it will be possible to mark a principal as able
|
||||
to handle unchecked requests.
|
||||
.It Li always-honour-request
|
||||
Always do what the client asked.
|
||||
In a future release, it will be possible to force a check per
|
||||
principal.
|
||||
.El
|
||||
.It encode_as_rep_as_tgs_rep = Va boolean
|
||||
Encode AS-Rep as TGS-Rep to be bug-compatible with old DCE code.
|
||||
The Heimdal clients allow both.
|
||||
|
||||
@@ -62,6 +62,10 @@ extern krb5_boolean encode_as_rep_as_tgs_rep;
|
||||
extern krb5_boolean check_ticket_addresses;
|
||||
extern krb5_boolean allow_null_ticket_addresses;
|
||||
extern krb5_boolean allow_anonymous;
|
||||
enum { TRPOLICY_ALWAYS_CHECK,
|
||||
TRPOLICY_ALLOW_PER_PRINCIPAL,
|
||||
TRPOLICY_ALWAYS_HONOUR_REQUEST };
|
||||
extern int trpolicy;
|
||||
extern int enable_524;
|
||||
extern int enable_v4_cross_realm;
|
||||
|
||||
|
||||
+120
-56
@@ -496,8 +496,8 @@ as_rep(KDC_REQ *req,
|
||||
krb5_enctype cetype, setype;
|
||||
EncTicketPart et;
|
||||
EncKDCRepPart ek;
|
||||
krb5_principal client_princ, server_princ;
|
||||
char *client_name, *server_name;
|
||||
krb5_principal client_princ = NULL, server_princ = NULL;
|
||||
char *client_name = NULL, *server_name = NULL;
|
||||
krb5_error_code ret = 0;
|
||||
const char *e_text = NULL;
|
||||
krb5_crypto crypto;
|
||||
@@ -506,27 +506,30 @@ as_rep(KDC_REQ *req,
|
||||
memset(&rep, 0, sizeof(rep));
|
||||
|
||||
if(b->sname == NULL){
|
||||
server_name = "<unknown server>";
|
||||
ret = KRB5KRB_ERR_GENERIC;
|
||||
e_text = "No server in request";
|
||||
} else{
|
||||
principalname2krb5_principal (&server_princ, *(b->sname), b->realm);
|
||||
krb5_unparse_name(context, server_princ, &server_name);
|
||||
}
|
||||
if (ret) {
|
||||
kdc_log(0, "AS-REQ malformed server name from %s", from);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(b->cname == NULL){
|
||||
client_name = "<unknown client>";
|
||||
ret = KRB5KRB_ERR_GENERIC;
|
||||
e_text = "No client in request";
|
||||
} else {
|
||||
principalname2krb5_principal (&client_princ, *(b->cname), b->realm);
|
||||
krb5_unparse_name(context, client_princ, &client_name);
|
||||
}
|
||||
kdc_log(0, "AS-REQ %s from %s for %s",
|
||||
client_name, from, server_name);
|
||||
|
||||
if(ret)
|
||||
if (ret) {
|
||||
kdc_log(0, "AS-REQ malformed client name from %s", from);
|
||||
goto out;
|
||||
}
|
||||
|
||||
kdc_log(0, "AS-REQ %s from %s for %s", client_name, from, server_name);
|
||||
|
||||
ret = db_fetch(client_princ, &client);
|
||||
if(ret){
|
||||
@@ -842,13 +845,8 @@ as_rep(KDC_REQ *req,
|
||||
copy_HostAddresses(b->addresses, et.caddr);
|
||||
}
|
||||
|
||||
{
|
||||
krb5_data empty_string;
|
||||
|
||||
krb5_data_zero(&empty_string);
|
||||
et.transited.tr_type = DOMAIN_X500_COMPRESS;
|
||||
et.transited.contents = empty_string;
|
||||
}
|
||||
et.transited.tr_type = DOMAIN_X500_COMPRESS;
|
||||
krb5_data_zero(&et.transited.contents);
|
||||
|
||||
copy_EncryptionKey(&et.key, &ek.key);
|
||||
|
||||
@@ -930,9 +928,11 @@ as_rep(KDC_REQ *req,
|
||||
ret = 0;
|
||||
}
|
||||
out2:
|
||||
krb5_free_principal(context, client_princ);
|
||||
if (client_princ)
|
||||
krb5_free_principal(context, client_princ);
|
||||
free(client_name);
|
||||
krb5_free_principal(context, server_princ);
|
||||
if (server_princ)
|
||||
krb5_free_principal(context, server_princ);
|
||||
free(server_name);
|
||||
if(client)
|
||||
free_ent(client);
|
||||
@@ -1055,33 +1055,35 @@ check_tgs_flags(KDC_REQ_BODY *b, EncTicketPart *tgt, EncTicketPart *et)
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
fix_transited_encoding(TransitedEncoding *tr,
|
||||
fix_transited_encoding(krb5_boolean check_policy,
|
||||
TransitedEncoding *tr,
|
||||
EncTicketPart *et,
|
||||
const char *client_realm,
|
||||
const char *server_realm,
|
||||
const char *tgt_realm)
|
||||
{
|
||||
krb5_error_code ret = 0;
|
||||
if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)){
|
||||
char **realms = NULL, **tmp;
|
||||
int num_realms = 0;
|
||||
int i;
|
||||
if(tr->tr_type && tr->contents.length != 0) {
|
||||
if(tr->tr_type != DOMAIN_X500_COMPRESS){
|
||||
kdc_log(0, "Unknown transited type: %u",
|
||||
tr->tr_type);
|
||||
return KRB5KDC_ERR_TRTYPE_NOSUPP;
|
||||
}
|
||||
ret = krb5_domain_x500_decode(context,
|
||||
tr->contents,
|
||||
&realms,
|
||||
&num_realms,
|
||||
client_realm,
|
||||
server_realm);
|
||||
if(ret){
|
||||
krb5_warn(context, ret, "Decoding transited encoding");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
char **realms, **tmp;
|
||||
int num_realms;
|
||||
int i;
|
||||
|
||||
if(tr->tr_type != DOMAIN_X500_COMPRESS) {
|
||||
kdc_log(0, "Unknown transited type: %u", tr->tr_type);
|
||||
return KRB5KDC_ERR_TRTYPE_NOSUPP;
|
||||
}
|
||||
|
||||
ret = krb5_domain_x500_decode(context,
|
||||
tr->contents,
|
||||
&realms,
|
||||
&num_realms,
|
||||
client_realm,
|
||||
server_realm);
|
||||
if(ret){
|
||||
krb5_warn(context, ret, "Decoding transited encoding");
|
||||
return ret;
|
||||
}
|
||||
if(strcmp(client_realm, tgt_realm) && strcmp(server_realm, tgt_realm)) {
|
||||
/* not us, so add the previous realm to transited set */
|
||||
if (num_realms < 0 || num_realms + 1 > UINT_MAX/sizeof(*realms)) {
|
||||
ret = ERANGE;
|
||||
goto free_realms;
|
||||
@@ -1098,16 +1100,46 @@ fix_transited_encoding(TransitedEncoding *tr,
|
||||
goto free_realms;
|
||||
}
|
||||
num_realms++;
|
||||
free_TransitedEncoding(tr);
|
||||
tr->tr_type = DOMAIN_X500_COMPRESS;
|
||||
ret = krb5_domain_x500_encode(realms, num_realms, &tr->contents);
|
||||
if(ret)
|
||||
krb5_warn(context, ret, "Encoding transited encoding");
|
||||
free_realms:
|
||||
for(i = 0; i < num_realms; i++)
|
||||
free(realms[i]);
|
||||
free(realms);
|
||||
}
|
||||
if(num_realms == 0) {
|
||||
if(strcmp(client_realm, server_realm))
|
||||
kdc_log(0, "cross-realm %s -> %s", client_realm, server_realm);
|
||||
} else {
|
||||
size_t l = 0;
|
||||
char *rs;
|
||||
for(i = 0; i < num_realms; i++)
|
||||
l += strlen(realms[i]) + 2;
|
||||
rs = malloc(l);
|
||||
if(rs != NULL) {
|
||||
*rs = '\0';
|
||||
for(i = 0; i < num_realms; i++) {
|
||||
if(i > 0)
|
||||
strlcat(rs, ", ", l);
|
||||
strlcat(rs, realms[i], l);
|
||||
}
|
||||
kdc_log(0, "cross-realm %s -> %s via [%s]", client_realm, server_realm, rs);
|
||||
free(rs);
|
||||
}
|
||||
}
|
||||
if(check_policy) {
|
||||
ret = krb5_check_transited(context, client_realm,
|
||||
server_realm,
|
||||
realms, num_realms, NULL);
|
||||
if(ret) {
|
||||
krb5_warn(context, ret, "cross-realm %s -> %s",
|
||||
client_realm, server_realm);
|
||||
goto free_realms;
|
||||
}
|
||||
et->flags.transited_policy_checked = 1;
|
||||
}
|
||||
et->transited.tr_type = DOMAIN_X500_COMPRESS;
|
||||
ret = krb5_domain_x500_encode(realms, num_realms, &et->transited.contents);
|
||||
if(ret)
|
||||
krb5_warn(context, ret, "Encoding transited encoding");
|
||||
free_realms:
|
||||
for(i = 0; i < num_realms; i++)
|
||||
free(realms[i]);
|
||||
free(realms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1175,8 +1207,28 @@ tgs_make_reply(KDC_REQ_BODY *b,
|
||||
if(ret)
|
||||
goto out;
|
||||
|
||||
copy_TransitedEncoding(&tgt->transited, &et.transited);
|
||||
ret = fix_transited_encoding(&et.transited,
|
||||
/* We should check the transited encoding if:
|
||||
1) the request doesn't ask not to be checked
|
||||
2) globally enforcing a check
|
||||
3) principal requires checking
|
||||
4) we allow non-check per-principal, but principal isn't marked as allowing this
|
||||
5) we don't globally allow this
|
||||
*/
|
||||
|
||||
#define GLOBAL_FORCE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_CHECK)
|
||||
#define GLOBAL_ALLOW_PER_PRINCIPAL (trpolicy == TRPOLICY_ALLOW_PER_PRINCIPAL)
|
||||
#define GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_HONOUR_REQUEST)
|
||||
/* these will consult the database in future release */
|
||||
#define PRINCIPAL_FORCE_TRANSITED_CHECK(P) 0
|
||||
#define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P) 0
|
||||
|
||||
ret = fix_transited_encoding(!f.disable_transited_check ||
|
||||
GLOBAL_FORCE_TRANSITED_CHECK ||
|
||||
PRINCIPAL_FORCE_TRANSITED_CHECK(server) ||
|
||||
!((GLOBAL_ALLOW_PER_PRINCIPAL &&
|
||||
PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server)) ||
|
||||
GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK),
|
||||
&tgt->transited, &et,
|
||||
*krb5_princ_realm(context, client_principal),
|
||||
*krb5_princ_realm(context, server->principal),
|
||||
*krb5_princ_realm(context, krbtgt->principal));
|
||||
@@ -1276,7 +1328,7 @@ tgs_make_reply(KDC_REQ_BODY *b,
|
||||
DES3? */
|
||||
ret = encode_reply(&rep, &et, &ek, etype, adtkt ? 0 : server->kvno, ekey,
|
||||
0, &tgt->key, e_text, reply);
|
||||
out:
|
||||
out:
|
||||
free_TGS_REP(&rep);
|
||||
free_TransitedEncoding(&et.transited);
|
||||
if(et.starttime)
|
||||
@@ -1378,13 +1430,13 @@ get_krbtgt_realm(const PrincipalName *p)
|
||||
}
|
||||
|
||||
static Realm
|
||||
find_rpath(Realm r)
|
||||
find_rpath(Realm crealm, Realm srealm)
|
||||
{
|
||||
const char *new_realm = krb5_config_get_string(context,
|
||||
NULL,
|
||||
"libdefaults",
|
||||
"capath",
|
||||
r,
|
||||
"capaths",
|
||||
crealm,
|
||||
srealm,
|
||||
NULL);
|
||||
return (Realm)new_realm;
|
||||
}
|
||||
@@ -1676,7 +1728,7 @@ tgs_rep2(KDC_REQ_BODY *b,
|
||||
|
||||
if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) {
|
||||
if(loop++ < 2) {
|
||||
new_rlm = find_rpath(req_rlm);
|
||||
new_rlm = find_rpath(tgt->crealm, req_rlm);
|
||||
if(new_rlm) {
|
||||
kdc_log(5, "krbtgt for realm %s not found, trying %s",
|
||||
req_rlm, new_rlm);
|
||||
@@ -1725,6 +1777,18 @@ tgs_rep2(KDC_REQ_BODY *b,
|
||||
}
|
||||
#endif
|
||||
|
||||
if(strcmp(krb5_principal_get_realm(context, sp),
|
||||
krb5_principal_get_comp_string(context, krbtgt->principal, 1)) != 0) {
|
||||
char *tpn;
|
||||
ret = krb5_unparse_name(context, krbtgt->principal, &tpn);
|
||||
kdc_log(0, "Request with wrong krbtgt: %s", (ret == 0) ? tpn : "<unknown>");
|
||||
if(ret == 0)
|
||||
free(tpn);
|
||||
ret = KRB5KRB_AP_ERR_NOT_US;
|
||||
goto out;
|
||||
|
||||
}
|
||||
|
||||
ret = check_flags(client, cpn, server, spn, FALSE);
|
||||
if(ret)
|
||||
goto out;
|
||||
|
||||
@@ -540,6 +540,15 @@ krb5_change_password (
|
||||
krb5_data */*result_code_string*/,
|
||||
krb5_data */*result_string*/);
|
||||
|
||||
krb5_error_code
|
||||
krb5_check_transited (
|
||||
krb5_context /*context*/,
|
||||
krb5_const_realm /*client_realm*/,
|
||||
krb5_const_realm /*server_realm*/,
|
||||
krb5_realm */*realms*/,
|
||||
int /*num_realms*/,
|
||||
int */*bad_realm*/);
|
||||
|
||||
krb5_error_code
|
||||
krb5_check_transited_realms (
|
||||
krb5_context /*context*/,
|
||||
|
||||
@@ -129,6 +129,32 @@ krb5_decode_ap_req(krb5_context context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
check_transited(krb5_context context, Ticket *ticket, EncTicketPart *enc)
|
||||
{
|
||||
char **realms;
|
||||
int num_realms;
|
||||
krb5_error_code ret;
|
||||
|
||||
if(enc->transited.tr_type != DOMAIN_X500_COMPRESS)
|
||||
return KRB5KDC_ERR_TRTYPE_NOSUPP;
|
||||
|
||||
if(enc->transited.contents.length == 0)
|
||||
return 0;
|
||||
|
||||
ret = krb5_domain_x500_decode(context, enc->transited.contents,
|
||||
&realms, &num_realms,
|
||||
enc->crealm,
|
||||
ticket->realm);
|
||||
if(ret)
|
||||
return ret;
|
||||
ret = krb5_check_transited(context, enc->crealm,
|
||||
ticket->realm,
|
||||
realms, num_realms, NULL);
|
||||
free(realms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_decrypt_ticket(krb5_context context,
|
||||
Ticket *ticket,
|
||||
@@ -161,6 +187,14 @@ krb5_decrypt_ticket(krb5_context context,
|
||||
krb5_clear_error_string (context);
|
||||
return KRB5KRB_AP_ERR_TKT_EXPIRED;
|
||||
}
|
||||
|
||||
if(!t.flags.transited_policy_checked) {
|
||||
ret = check_transited(context, ticket, &t);
|
||||
if(ret) {
|
||||
free_EncTicketPart(&t);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(out)
|
||||
@@ -209,29 +243,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static krb5_error_code
|
||||
check_transited(krb5_context context,
|
||||
krb5_ticket *ticket)
|
||||
{
|
||||
char **realms;
|
||||
int num_realms;
|
||||
krb5_error_code ret;
|
||||
|
||||
if(ticket->ticket.transited.tr_type != DOMAIN_X500_COMPRESS)
|
||||
return KRB5KDC_ERR_TRTYPE_NOSUPP;
|
||||
|
||||
ret = krb5_domain_x500_decode(ticket->ticket.transited.contents,
|
||||
&realms, &num_realms,
|
||||
ticket->client->realm,
|
||||
ticket->server->realm);
|
||||
if(ret)
|
||||
return ret;
|
||||
ret = krb5_check_transited_realms(context, realms, num_realms, NULL);
|
||||
free(realms);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
krb5_error_code
|
||||
krb5_verify_ap_req(krb5_context context,
|
||||
|
||||
@@ -308,6 +308,12 @@ krb5_domain_x500_decode(krb5_context context,
|
||||
struct tr_realm *p, **q;
|
||||
int ret;
|
||||
|
||||
if(tr.length == 0) {
|
||||
*realms = NULL;
|
||||
*num_realms = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* split string in components */
|
||||
ret = decode_realms(context, tr.data, tr.length, &r);
|
||||
if(ret)
|
||||
@@ -362,6 +368,9 @@ krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding)
|
||||
char *s = NULL;
|
||||
int len = 0;
|
||||
int i;
|
||||
krb5_data_zero(encoding);
|
||||
if (num_realms == 0)
|
||||
return 0;
|
||||
for(i = 0; i < num_realms; i++){
|
||||
len += strlen(realms[i]);
|
||||
if(realms[i][0] == '/')
|
||||
@@ -369,6 +378,8 @@ krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding)
|
||||
}
|
||||
len += num_realms - 1;
|
||||
s = malloc(len + 1);
|
||||
if (s == NULL)
|
||||
return ENOMEM;
|
||||
*s = '\0';
|
||||
for(i = 0; i < num_realms; i++){
|
||||
if(i && i < num_realms - 1)
|
||||
@@ -382,6 +393,44 @@ krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding)
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_check_transited(krb5_context context,
|
||||
krb5_const_realm client_realm,
|
||||
krb5_const_realm server_realm,
|
||||
krb5_realm *realms,
|
||||
int num_realms,
|
||||
int *bad_realm)
|
||||
{
|
||||
char **tr_realms;
|
||||
char **p;
|
||||
int i;
|
||||
|
||||
if(num_realms == 0)
|
||||
return 0;
|
||||
|
||||
tr_realms = krb5_config_get_strings(context, NULL,
|
||||
"capaths",
|
||||
client_realm,
|
||||
server_realm,
|
||||
NULL);
|
||||
for(i = 0; i < num_realms; i++) {
|
||||
for(p = tr_realms; p && *p; p++) {
|
||||
if(strcmp(*p, realms[i]) == 0)
|
||||
break;
|
||||
}
|
||||
if(p == NULL || *p == NULL) {
|
||||
krb5_config_free_strings(tr_realms);
|
||||
krb5_set_error_string (context, "no transit through realm %s",
|
||||
realms[i]);
|
||||
if(bad_realm)
|
||||
*bad_realm = i;
|
||||
return KRB5KRB_AP_ERR_ILL_CR_TKT;
|
||||
}
|
||||
}
|
||||
krb5_config_free_strings(tr_realms);
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_check_transited_realms(krb5_context context,
|
||||
const char *const *realms,
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
* major minor fix final patch/beta)
|
||||
*/
|
||||
#define OPENSSL_VERSION_NUMBER 0x0090703fL
|
||||
#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.7c 30 Sep 2003"
|
||||
#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.7c-p1 30 Sep 2003"
|
||||
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
|
||||
|
||||
|
||||
|
||||
@@ -1085,6 +1085,14 @@ start:
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Check we have a cipher to change to */
|
||||
if (s->s3->tmp.new_cipher == NULL)
|
||||
{
|
||||
i=SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_CCS_RECEIVED_EARLY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
rr->length=0;
|
||||
|
||||
if (s->msg_callback)
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
#define HAVE_SIGVEC 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
/* #undef HAVE_STDINT_H */
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
$FreeBSD$
|
||||
|
||||
Original revision: 1.663.2.5
|
||||
Original revision: 1.663.2.13
|
||||
-->
|
||||
|
||||
<articleinfo>
|
||||
@@ -47,31 +47,9 @@
|
||||
これは &os; に最近追加、変更、削除された機能について解説したものであり、
|
||||
&os; の前のバージョンからのアップグレードについても言及しています。</para>
|
||||
|
||||
<![ %release.type.snapshot [
|
||||
|
||||
<para>このリリースノートが対応する &release.type; 配布物は、
|
||||
&release.branch; 開発ブランチの &release.prev; から
|
||||
将来の &release.next; の間に位置します。
|
||||
このブランチのあらかじめコンパイルされたバイナリ &release.type;
|
||||
配布物は <ulink url="&release.url;"></ulink> に公開されています。
|
||||
</para>
|
||||
|
||||
]]>
|
||||
|
||||
<![ %release.type.release [
|
||||
|
||||
<para>この &os; &release.current; 配布物は &release.type; 配布物です。
|
||||
この配布物はあらゆるミラーの <ulink url="&release.url;"></ulink>
|
||||
で見つけることができます。
|
||||
この (もしくは他の) &os; の &release.type; 配布物を取得する方法
|
||||
は
|
||||
<ulink url="http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/">FreeBSD ハンドブック</ulink>
|
||||
の
|
||||
<ulink url="http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/mirrors.html">
|
||||
付録 <quote>FreeBSD を取得する</quote></ulink>
|
||||
を参照してください。</para>
|
||||
|
||||
]]>
|
||||
<para>この &os; &release.current; 配布物は
|
||||
<quote>ポイントリリース</quote> であり、&os; &release.base; で発見された
|
||||
いくつかの問題 (主にバグ) の修正をおこなったものです。</para>
|
||||
|
||||
<para>&os; &release.type; の &release.branch;
|
||||
系列をはじめて利用するユーザは、まず <quote>&os;
|
||||
@@ -130,6 +108,9 @@
|
||||
監査で見つかったセキュリティ上好ましくないスタイルで書かれたコードの修正、
|
||||
ソースコードの整理などです。</para>
|
||||
|
||||
<para>&new.521; という印は、このポイントリリースで追加された
|
||||
リリースノートの項目を表しています。</para>
|
||||
|
||||
<sect2 id="security">
|
||||
<title>セキュリティ勧告</title>
|
||||
|
||||
@@ -211,6 +192,34 @@
|
||||
<ulink url="ftp://ftp.FreeBSD.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-03:19.bind.asc">FreeBSD-SA-03:19</ulink>
|
||||
をご覧ください。
|
||||
&merged;</para>
|
||||
|
||||
<para>&new.521;
|
||||
ファイルシステムのスナップショットを作成すると、
|
||||
対象ファイルシステムのフラグが初期値に戻ってしまうという、
|
||||
&man.mksnap.ffs.8; のバグが修正されました。
|
||||
これによる影響の大小はシステムの利用形態によりますが、
|
||||
拡張アクセス制御リストを無効にしたり、信頼できないファイルシステムに
|
||||
置かれている setuid 実行ファイルの実行が可能になるおそれがあります。
|
||||
&man.dump.8; の <option>-L</option> オプションも、
|
||||
&man.mksnap.ffs.8; を利用するため、このバグによる影響を受けます。
|
||||
ただし通常、&man.mksnap.ffs.8; を実行可能なのは
|
||||
スーパユーザと <groupname>operator</groupname> のメンバのみです。
|
||||
詳細はセキュリティ勧告 <ulink
|
||||
url="ftp://ftp.FreeBSD.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-04:01.mksnap_ffs.asc">FreeBSD-SA-04:01</ulink>
|
||||
をご覧ください。</para>
|
||||
|
||||
<para>&new.521;
|
||||
System V 共有メモリインタフェース
|
||||
(のうち &man.shmat.2; システムコール) において、
|
||||
未割当のカーネルメモリを参照する共有メモリセグメントをつくることができる、
|
||||
というバグが修正されました。
|
||||
ローカルの攻撃者がこれを悪用すると、カーネルメモリの一部に不正にアクセスすることが
|
||||
可能になるため、結果としてセキュリティ上重要な情報の漏洩、アクセス制御機構の迂回や
|
||||
高い権限の不正な獲得などに利用されるおそれがあります。
|
||||
詳細はセキュリティ勧告 <ulink
|
||||
url="ftp://ftp.FreeBSD.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-04:02.shmat.asc">FreeBSD-SA-04:02</ulink>
|
||||
をご覧ください。&merged;</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="kernel">
|
||||
@@ -236,6 +245,9 @@
|
||||
ユーザランドの設定ユーティリティ cxconfig は、&man.sconfig.8;
|
||||
というユーティリティに置き換えられました。</para>
|
||||
|
||||
<para>&new.521; &man.devfs.5; の path ルールがディレクトリに対しても
|
||||
正しく動作するようになりました。</para>
|
||||
|
||||
<para arch="i386,pc98">DRM カーネルモジュールが
|
||||
DRI CVS リポジトリの 2003 年 11 月 12 日時点のコードに更新されました。
|
||||
この変更には、最近移植された SiS 300/305/540/630/730 ドライバの
|
||||
@@ -343,7 +355,9 @@
|
||||
<sect3 id="boot">
|
||||
<title>ブートローダの変更</title>
|
||||
|
||||
<para></para>
|
||||
<para arch="i386">&new.521;
|
||||
BIOS に問題があるシステムでも、USB CDROM ドライブからの起動で
|
||||
<filename>cdboot</filename> が動作するようになりました。</para>
|
||||
|
||||
<!-- Above this line, order bootloader changes by keyword-->
|
||||
|
||||
@@ -367,6 +381,10 @@
|
||||
<para>&man.bge.4; にあったバグが修正され、
|
||||
10Mbps で正常に動作するようになりました。</para>
|
||||
|
||||
<para arch="sparc64">&new.521; &man.dc.4; ドライバが
|
||||
OpenFirmware に MAC アドレスを格納している
|
||||
Davicom 製のカードに対応しました。</para>
|
||||
|
||||
<para>&man.em.4; ドライバが、ドライバを再コンパイルしなくても、
|
||||
割込みの遅延量を sysctl 変数を利用して調整できるようになりました。</para>
|
||||
|
||||
@@ -399,6 +417,9 @@
|
||||
Gigabit Ethernet NIC に対応しました。
|
||||
&merged;</para>
|
||||
|
||||
<para>&new.521; &man.sk.4; ドライバのマルチキャストモードおよび
|
||||
プロミスキャスモードに関係するバグが修正されました。</para>
|
||||
|
||||
<para>新しく &man.utopia.4; ドライバが追加されました。
|
||||
これは、多くの ATM-PHY チップで使われている
|
||||
25MBit/sec, 155MBit/sec. 622MBit/sec の
|
||||
@@ -529,13 +550,27 @@
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>IPv6 および IPSec のコードおける数多くの修正と更新が、
|
||||
<para>IPv6 および IPsec のコードおける数多くの修正と更新が、
|
||||
KAME プロジェクトから統合されました。</para>
|
||||
|
||||
<para>&new.521; KAME プロジェクトから統合された IPsec
|
||||
の実装に含まれていたバグが修正されました。このバグは、
|
||||
まだ参照されているメモリオブジェクトを開放してしまうもので、
|
||||
セキュリティポリシデータベース (SPD; Security Policy Database)
|
||||
をフラッシュした後に異常な動作をしたり
|
||||
カーネルパニックが発生するという症状を引き起こします。</para>
|
||||
|
||||
<para>IPv6 Advanced Sockets API 対応が RFC 2292 ではなく
|
||||
RFC 3542 (別名 RFC 2292bis) に準拠しました。
|
||||
この API を使っているアプリケーションも、それに応じて更新されています。</para>
|
||||
|
||||
<para>&new.521; <literal>PFIL_HOOKS</literal> オプションが
|
||||
<filename>GENERIC</filename> カーネルにおいて
|
||||
デフォルトで有効になりました。
|
||||
これにより、<application>IPFilter</application> が
|
||||
カーネルモジュールとして読み込まれた時にも、正しく動作するように
|
||||
なりました。</para>
|
||||
|
||||
<para>RFC 3484 に含まれているソースアドレス選択 (source address selection)
|
||||
機能が追加されました。アドレス選択ポリシの設定には、
|
||||
&man.ip6addrctl.8; ユーティリティが使用できます。</para>
|
||||
@@ -545,6 +580,23 @@
|
||||
以降に発生する同一の送信元アドレス・送信先アドレスの接続において、
|
||||
より適切な初期値を与えることを可能にします。
|
||||
経路表に格納されていた、同じような情報は削除されました。</para>
|
||||
|
||||
<para>&os; の TCP 実装に TCP セグメントのサイズと速度を制限するという形で、
|
||||
ある種の TCP MSS 資源枯渇攻撃に対する対策が追加されました。
|
||||
ひとつ目は TCP セグメントサイズの最大と最小を制限するもので、
|
||||
sysctl 変数 <varname>net.inet.tcp.minmss</varname> (デフォルトは
|
||||
<literal>216</literal>) で制御することができます。
|
||||
ふたつ目は、セグメントの平均サイズが
|
||||
<varname>net.inet.tcp.minmss</varname> より小さい接続の
|
||||
最大通信速度を制限するもので、
|
||||
<varname>net.inet.tcp.minmssoverload</varname>
|
||||
変数で制御することができます。
|
||||
設定されたパケット速度を超える接続は、reset されて切断されます。
|
||||
この機能は &release.base; リリースサイクルの終りごろに追加されたため、
|
||||
デフォルトでは、この接続速度の制限は無効になっていますが、
|
||||
<varname>net.inet.tcp.minmssoverload</varname> に 0 でない
|
||||
値を設定することで、手動で有効にすることができます。</para>
|
||||
|
||||
</sect3>
|
||||
|
||||
<sect3 id="disks">
|
||||
@@ -561,6 +613,10 @@
|
||||
現在は、明示的にカーネルコンフィグファイルに
|
||||
<literal>device ataraid</literal> を追加する必要があります。</para>
|
||||
|
||||
<para>&new.521; &man.ata.4; ドライバにあったバグの数々が修正されました。
|
||||
特に、マスタ/スレーブ接続のデバイス検出が改善され、
|
||||
タイムアウトによる問題などが解決しています。</para>
|
||||
|
||||
<para>&man.ccd.4; が raw ディスクおよび、その他の
|
||||
&man.geom.4; プロバイダに対して動作するようになりました。</para>
|
||||
|
||||
@@ -604,6 +660,9 @@
|
||||
<literal>UDF_ICONV</literal>
|
||||
をカーネルコンフィグファイルに指定してください。</para>
|
||||
|
||||
<para>&new.521; まれに I/O が固まった状態に陥るという GEOM の
|
||||
バグが修正されました。</para>
|
||||
|
||||
<para>smbfs が 15 文字の NetBIOS 名で正しく動作するのを阻害していた
|
||||
いくつかの一つ違い (off-by-one) の誤りが修正されました。</para>
|
||||
|
||||
@@ -640,6 +699,11 @@
|
||||
NFSv4 に対応しました。
|
||||
詳細は、&man.mount.nfs4.8; および
|
||||
&man.idmapd.8; のマニュアルページをご覧ください。</para>
|
||||
|
||||
<para>&new.521; NFSv4 クライアントが NFSv3 のみ、あるいは NFSv2 のみに
|
||||
対応したサーバに NFSv4 操作をおこなおうとした場合にパニックする
|
||||
バグが修正されました。</para>
|
||||
|
||||
</sect3>
|
||||
|
||||
<sect3 id="mm">
|
||||
@@ -755,6 +819,12 @@
|
||||
すべて <filename>libcrypto</filename>
|
||||
を使うように変更されています。</para>
|
||||
|
||||
<para arch="pc98">&new.521; <filename>libdisk</filename> が
|
||||
正しい PC98 ディスクパーティションタイプを使用するようになりました。
|
||||
これにより、&man.sysinstall.8; のディスクパーティションエディタで
|
||||
ディスク全体を使用する単一の &os; パーティションを正しく作成できる
|
||||
ようになりました。</para>
|
||||
|
||||
<para>カーネルに読み込み可能な文字集合変換テーブルの操作をおこなう
|
||||
<filename>libkiconv</filename> ライブラリが追加されました。</para>
|
||||
|
||||
@@ -807,6 +877,11 @@
|
||||
<para>(以前はシェルスクリプトだった) &man.nologin.8; プログラムが
|
||||
C 言語で再実装されました。</para>
|
||||
|
||||
<para>&new.521; NSS サポートのバグが修正されました。
|
||||
<filename role="package">net/nss_ldap</filename> などの
|
||||
サードパーティ製 NSS モジュールを使い、大量のメンバリストを含む
|
||||
グループが存在する場合に発生する問題が解決しています。</para>
|
||||
|
||||
<para>&man.rc.conf.5; にある、&man.ntpd.8; の起動オプションを設定する変数
|
||||
<varname>ntpd_flags</varname> がデフォルトで
|
||||
<option>-f /var/db/ntpd.drift</option> を含むようになりました。</para>
|
||||
@@ -896,9 +971,17 @@
|
||||
<para><application>BIND</application> がバージョン 8.3.4
|
||||
から、バージョン 8.3.7 に更新されました。&merged;</para>
|
||||
|
||||
<para>&new.521; <application>CVS</application> のバージョン
|
||||
1.11.10 および 1.11.11 から、セキュリティの改善部分が
|
||||
統合されました。具体的には、
|
||||
ある形式で書かれた不正なモジュールのリクエストは拒否されるようになったこと、
|
||||
<command>cvs pserver</command> モードを使用した場合に
|
||||
<username>root</username> による認証は拒否され
|
||||
&man.syslog.3; 経由で記録が残るようになったことが含まれます。</para>
|
||||
|
||||
<para><application>GCC</application> が、バージョン 3.2.2
|
||||
から、2003 年 11 月 6 日における 3.3.3 の
|
||||
post release snapshot に更新されました。
|
||||
pre release snapshot に更新されました。
|
||||
|
||||
<note>
|
||||
<para><application>GCC</application> の前のバージョンは、
|
||||
@@ -970,6 +1053,13 @@
|
||||
<para><application>KDE</application> の対応リリースが
|
||||
3.1.2 から 3.1.4 に更新されました。
|
||||
&merged;</para>
|
||||
|
||||
<para>&new.521; <filename role="package">sysutils/kdeadmin3</filename>
|
||||
port とその package がバージョン 3.1.4_1 に更新されました。
|
||||
この更新では <application>KUser</application> を使うとシステム
|
||||
パスワードファイルから <username>root</username> ユーザが
|
||||
削除されてしまう可能性のあるバグが修正されています。</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="doc">
|
||||
|
||||
@@ -5,11 +5,14 @@
|
||||
|
||||
$FreeBSD$
|
||||
|
||||
Original revision: 1.3
|
||||
Original revision: 1.3.6.1
|
||||
-->
|
||||
|
||||
<!-- Text constants which probably don't need to be changed.-->
|
||||
|
||||
<!-- Notes new to our first point release (hopefully there'll only be one!) -->
|
||||
<!ENTITY new.521 "[5.2.1]">
|
||||
|
||||
<!-- The marker for MFCs. -->
|
||||
<!ENTITY merged "[MFC ºÑ]">
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- $FreeBSD$ -->
|
||||
<!-- Original revision: 1.7 -->
|
||||
<!-- Original revision: 1.7.4.1 -->
|
||||
|
||||
<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
|
||||
<!ENTITY release.dsl PUBLIC "-//FreeBSD//DOCUMENT Release Notes DocBook Language Neutral Stylesheet//EN" CDATA DSSSL>
|
||||
|
||||
@@ -1210,6 +1210,9 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
|
||||
/* doublefault stack space, runs on ist1 */
|
||||
common_tss[0].tss_ist1 = (long)&dblfault_stack[sizeof(dblfault_stack)];
|
||||
|
||||
/* Set the IO permission bitmap (empty due to tss seg limit) */
|
||||
common_tss[0].tss_iobase = sizeof(struct amd64tss);
|
||||
|
||||
gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
|
||||
ltr(gsel_tss);
|
||||
|
||||
|
||||
@@ -335,6 +335,7 @@ init_secondary(void)
|
||||
/* Init tss */
|
||||
common_tss[cpu] = common_tss[0];
|
||||
common_tss[cpu].tss_rsp0 = 0; /* not used until after switch */
|
||||
common_tss[cpu].tss_iobase = sizeof(struct amd64tss);
|
||||
|
||||
gdt_segs[GPROC0_SEL].ssd_base = (long) &common_tss[cpu];
|
||||
ssdtosyssd(&gdt_segs[GPROC0_SEL],
|
||||
|
||||
@@ -54,7 +54,6 @@ struct amd64tss {
|
||||
u_int64_t tss_rsp2 __packed; /* kernel stack pointer ring 2 */
|
||||
u_int32_t tss_rsvd1;
|
||||
u_int32_t tss_rsvd2;
|
||||
u_int32_t tss_rsvd3;
|
||||
u_int64_t tss_ist1 __packed; /* Interrupt stack table 1 */
|
||||
u_int64_t tss_ist2 __packed; /* Interrupt stack table 2 */
|
||||
u_int64_t tss_ist3 __packed; /* Interrupt stack table 3 */
|
||||
|
||||
@@ -771,6 +771,7 @@ static int
|
||||
linprocfs_doproccmdline(PFS_FILL_ARGS)
|
||||
{
|
||||
struct ps_strings pstr;
|
||||
char **ps_argvstr;
|
||||
int error, i;
|
||||
|
||||
/*
|
||||
@@ -796,10 +797,21 @@ linprocfs_doproccmdline(PFS_FILL_ARGS)
|
||||
sizeof(pstr));
|
||||
if (error)
|
||||
return (error);
|
||||
if (pstr.ps_nargvstr > ARG_MAX)
|
||||
return (E2BIG);
|
||||
ps_argvstr = malloc(pstr.ps_nargvstr * sizeof(char *),
|
||||
M_TEMP, M_WAITOK);
|
||||
error = copyin((void *)pstr.ps_argvstr, ps_argvstr,
|
||||
pstr.ps_nargvstr * sizeof(char *));
|
||||
if (error) {
|
||||
free(ps_argvstr, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
for (i = 0; i < pstr.ps_nargvstr; i++) {
|
||||
sbuf_copyin(sb, pstr.ps_argvstr[i], 0);
|
||||
sbuf_copyin(sb, ps_argvstr[i], 0);
|
||||
sbuf_printf(sb, "%c", '\0');
|
||||
}
|
||||
free(ps_argvstr, M_TEMP);
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
||||
@@ -1328,20 +1328,22 @@ linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args)
|
||||
}
|
||||
|
||||
case LINUX_CDROMREADTOCENTRY: {
|
||||
struct linux_cdrom_tocentry lte, *ltep =
|
||||
(struct linux_cdrom_tocentry *)args->arg;
|
||||
struct linux_cdrom_tocentry lte;
|
||||
struct ioc_read_toc_single_entry irtse;
|
||||
irtse.address_format = ltep->cdte_format;
|
||||
irtse.track = ltep->cdte_track;
|
||||
|
||||
error = copyin((void *)args->arg, <e, sizeof(lte));
|
||||
if (error)
|
||||
break;
|
||||
irtse.address_format = lte.cdte_format;
|
||||
irtse.track = lte.cdte_track;
|
||||
error = fo_ioctl(fp, CDIOREADTOCENTRY, (caddr_t)&irtse,
|
||||
td->td_ucred, td);
|
||||
if (!error) {
|
||||
lte = *ltep;
|
||||
lte.cdte_ctrl = irtse.entry.control;
|
||||
lte.cdte_adr = irtse.entry.addr_type;
|
||||
bsd_to_linux_msf_lba(irtse.address_format,
|
||||
&irtse.entry.addr, <e.cdte_addr);
|
||||
copyout(<e, (void *)args->arg, sizeof(lte));
|
||||
error = copyout(<e, (void *)args->arg, sizeof(lte));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1826,11 +1828,14 @@ linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args)
|
||||
break;
|
||||
|
||||
case LINUX_VT_SETMODE: {
|
||||
struct vt_mode *mode;
|
||||
struct vt_mode mode;
|
||||
if ((error = copyin((void *)args->arg, &mode, sizeof(mode))))
|
||||
break;
|
||||
if (!ISSIGVALID(mode.frsig) && ISSIGVALID(mode.acqsig))
|
||||
mode.frsig = mode.acqsig;
|
||||
if ((error = copyout(&mode, (void *)args->arg, sizeof(mode))))
|
||||
break;
|
||||
args->cmd = VT_SETMODE;
|
||||
mode = (struct vt_mode *)args->arg;
|
||||
if (!ISSIGVALID(mode->frsig) && ISSIGVALID(mode->acqsig))
|
||||
mode->frsig = mode->acqsig;
|
||||
error = (ioctl(td, (struct ioctl_args *)args));
|
||||
break;
|
||||
}
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@
|
||||
|
||||
TYPE="FreeBSD"
|
||||
REVISION="5.2.1"
|
||||
BRANCH="RELEASE"
|
||||
BRANCH="RELEASE-p14"
|
||||
RELEASE="${REVISION}-${BRANCH}"
|
||||
VERSION="${TYPE} ${RELEASE}"
|
||||
|
||||
|
||||
@@ -855,14 +855,16 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
|
||||
scrshot_t *ptr = (scrshot_t *)data;
|
||||
void *outp = ptr->buf;
|
||||
|
||||
if (ptr->x < 0 || ptr->y < 0 || ptr->xsize < 0 || ptr->ysize < 0)
|
||||
return EINVAL;
|
||||
s = spltty();
|
||||
if (ISGRAPHSC(scp)) {
|
||||
splx(s);
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
hist_rsz = (scp->history != NULL) ? scp->history->vtb_rows : 0;
|
||||
if ((ptr->x + ptr->xsize) > scp->xsize ||
|
||||
(ptr->y + ptr->ysize) > (scp->ysize + hist_rsz)) {
|
||||
if (((u_int)ptr->x + ptr->xsize) > scp->xsize ||
|
||||
((u_int)ptr->y + ptr->ysize) > (scp->ysize + hist_rsz)) {
|
||||
splx(s);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
@@ -178,6 +178,7 @@ int
|
||||
procfs_doproccmdline(PFS_FILL_ARGS)
|
||||
{
|
||||
struct ps_strings pstr;
|
||||
char **ps_argvstr;
|
||||
int error, i;
|
||||
|
||||
/*
|
||||
@@ -204,10 +205,21 @@ procfs_doproccmdline(PFS_FILL_ARGS)
|
||||
sizeof(pstr));
|
||||
if (error)
|
||||
return (error);
|
||||
if (pstr.ps_nargvstr > ARG_MAX)
|
||||
return (E2BIG);
|
||||
ps_argvstr = malloc(pstr.ps_nargvstr * sizeof(char *),
|
||||
M_TEMP, M_WAITOK);
|
||||
error = copyin((void *)pstr.ps_argvstr, ps_argvstr,
|
||||
pstr.ps_nargvstr * sizeof(char *));
|
||||
if (error) {
|
||||
free(ps_argvstr, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
for (i = 0; i < pstr.ps_nargvstr; i++) {
|
||||
sbuf_copyin(sb, pstr.ps_argvstr[i], 0);
|
||||
sbuf_copyin(sb, ps_argvstr[i], 0);
|
||||
sbuf_printf(sb, "%c", '\0');
|
||||
}
|
||||
free(ps_argvstr, M_TEMP);
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
||||
@@ -213,6 +213,7 @@ struct ip6_frag {
|
||||
|
||||
#define IPV6_MMTU 1280 /* minimal MTU and reassembly. 1024 + 256 */
|
||||
#define IPV6_MAXPACKET 65535 /* ip6 max packet size without Jumbo payload*/
|
||||
#define IPV6_MAXOPTHDR 2048 /* max option header size, 256 64-bit words */
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
|
||||
+61
-9
@@ -57,6 +57,8 @@
|
||||
|
||||
#include <machine/cpu.h> /* before tcp_seq.h, for tcp_random18() */
|
||||
|
||||
#include <vm/uma.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
@@ -97,8 +99,6 @@
|
||||
|
||||
#include <machine/in_cksum.h>
|
||||
|
||||
MALLOC_DEFINE(M_TSEGQ, "tseg_qent", "TCP segment queue entry");
|
||||
|
||||
static const int tcprexmtthresh = 3;
|
||||
tcp_cc tcp_ccgen;
|
||||
|
||||
@@ -134,6 +134,24 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3390, CTLFLAG_RW,
|
||||
&tcp_do_rfc3390, 0,
|
||||
"Enable RFC 3390 (Increasing TCP's Initial Congestion Window)");
|
||||
|
||||
SYSCTL_NODE(_net_inet_tcp, OID_AUTO, reass, CTLFLAG_RW, 0,
|
||||
"TCP Segment Reassembly Queue");
|
||||
|
||||
static int tcp_reass_maxseg = 0;
|
||||
SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, maxsegments, CTLFLAG_RDTUN,
|
||||
&tcp_reass_maxseg, 0,
|
||||
"Global maximum number of TCP Segments in Reassembly Queue");
|
||||
|
||||
int tcp_reass_qsize = 0;
|
||||
SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, cursegments, CTLFLAG_RD,
|
||||
&tcp_reass_qsize, 0,
|
||||
"Global number of TCP Segments currently in Reassembly Queue");
|
||||
|
||||
static int tcp_reass_overflows = 0;
|
||||
SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, overflows, CTLFLAG_RD,
|
||||
&tcp_reass_overflows, 0,
|
||||
"Global number of TCP Segment Reassembly Queue Overflows");
|
||||
|
||||
struct inpcbhead tcb;
|
||||
#define tcb6 tcb /* for KAME src sync over BSD*'s */
|
||||
struct inpcbinfo tcbinfo;
|
||||
@@ -174,6 +192,19 @@ do { \
|
||||
(tp->t_flags & TF_RXWIN0SENT) == 0) && \
|
||||
(tcp_delack_enabled || (tp->t_flags & TF_NEEDSYN)))
|
||||
|
||||
/* Initialize TCP reassembly queue */
|
||||
uma_zone_t tcp_reass_zone;
|
||||
void
|
||||
tcp_reass_init()
|
||||
{
|
||||
tcp_reass_maxseg = nmbclusters / 16;
|
||||
TUNABLE_INT_FETCH("net.inet.tcp.reass.maxsegments",
|
||||
&tcp_reass_maxseg);
|
||||
tcp_reass_zone = uma_zcreate("tcpreass", sizeof (struct tseg_qent),
|
||||
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
|
||||
uma_zone_set_max(tcp_reass_zone, tcp_reass_maxseg);
|
||||
}
|
||||
|
||||
static int
|
||||
tcp_reass(tp, th, tlenp, m)
|
||||
register struct tcpcb *tp;
|
||||
@@ -184,7 +215,7 @@ tcp_reass(tp, th, tlenp, m)
|
||||
struct tseg_qent *q;
|
||||
struct tseg_qent *p = NULL;
|
||||
struct tseg_qent *nq;
|
||||
struct tseg_qent *te;
|
||||
struct tseg_qent *te = NULL;
|
||||
struct socket *so = tp->t_inpcb->inp_socket;
|
||||
int flags;
|
||||
|
||||
@@ -195,14 +226,32 @@ tcp_reass(tp, th, tlenp, m)
|
||||
if (th == 0)
|
||||
goto present;
|
||||
|
||||
/* Allocate a new queue entry. If we can't, just drop the pkt. XXX */
|
||||
MALLOC(te, struct tseg_qent *, sizeof (struct tseg_qent), M_TSEGQ,
|
||||
M_NOWAIT);
|
||||
/*
|
||||
* Limit the number of segments in the reassembly queue to prevent
|
||||
* holding on to too many segments (and thus running out of mbufs).
|
||||
* Make sure to let the missing segment through which caused this
|
||||
* queue. Always keep one global queue entry spare to be able to
|
||||
* process the missing segment.
|
||||
*/
|
||||
if (th->th_seq != tp->rcv_nxt &&
|
||||
tcp_reass_qsize + 1 >= tcp_reass_maxseg) {
|
||||
tcp_reass_overflows++;
|
||||
tcpstat.tcps_rcvmemdrop++;
|
||||
m_freem(m);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a new queue entry. If we can't, or hit the zone limit
|
||||
* just drop the pkt.
|
||||
*/
|
||||
te = uma_zalloc(tcp_reass_zone, M_NOWAIT);
|
||||
if (te == NULL) {
|
||||
tcpstat.tcps_rcvmemdrop++;
|
||||
m_freem(m);
|
||||
return (0);
|
||||
}
|
||||
tcp_reass_qsize++;
|
||||
|
||||
/*
|
||||
* Find a segment which begins after this one does.
|
||||
@@ -227,7 +276,8 @@ tcp_reass(tp, th, tlenp, m)
|
||||
tcpstat.tcps_rcvduppack++;
|
||||
tcpstat.tcps_rcvdupbyte += *tlenp;
|
||||
m_freem(m);
|
||||
FREE(te, M_TSEGQ);
|
||||
uma_zfree(tcp_reass_zone, te);
|
||||
tcp_reass_qsize--;
|
||||
/*
|
||||
* Try to present any queued data
|
||||
* at the left window edge to the user.
|
||||
@@ -262,7 +312,8 @@ tcp_reass(tp, th, tlenp, m)
|
||||
nq = LIST_NEXT(q, tqe_q);
|
||||
LIST_REMOVE(q, tqe_q);
|
||||
m_freem(q->tqe_m);
|
||||
FREE(q, M_TSEGQ);
|
||||
uma_zfree(tcp_reass_zone, q);
|
||||
tcp_reass_qsize--;
|
||||
q = nq;
|
||||
}
|
||||
|
||||
@@ -296,7 +347,8 @@ present:
|
||||
m_freem(q->tqe_m);
|
||||
else
|
||||
sbappendstream(&so->so_rcv, q->tqe_m);
|
||||
FREE(q, M_TSEGQ);
|
||||
uma_zfree(tcp_reass_zone, q);
|
||||
tcp_reass_qsize--;
|
||||
q = nq;
|
||||
} while (q && q->tqe_th->th_seq == tp->rcv_nxt);
|
||||
ND6_HINT(tp);
|
||||
|
||||
@@ -286,6 +286,7 @@ tcp_init()
|
||||
tcp_timer_init();
|
||||
syncache_init();
|
||||
tcp_hc_init();
|
||||
tcp_reass_init();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -708,7 +709,8 @@ tcp_discardcb(tp)
|
||||
while ((q = LIST_FIRST(&tp->t_segq)) != NULL) {
|
||||
LIST_REMOVE(q, tqe_q);
|
||||
m_freem(q->tqe_m);
|
||||
FREE(q, M_TSEGQ);
|
||||
uma_zfree(tcp_reass_zone, q);
|
||||
tcp_reass_qsize--;
|
||||
}
|
||||
inp->inp_ppcb = NULL;
|
||||
tp->t_inpcb = NULL;
|
||||
@@ -769,7 +771,8 @@ tcp_drain()
|
||||
!= NULL) {
|
||||
LIST_REMOVE(te, tqe_q);
|
||||
m_freem(te->tqe_m);
|
||||
FREE(te, M_TSEGQ);
|
||||
uma_zfree(tcp_reass_zone, te);
|
||||
tcp_reass_qsize--;
|
||||
}
|
||||
}
|
||||
INP_UNLOCK(inpb);
|
||||
|
||||
@@ -54,9 +54,8 @@ struct tseg_qent {
|
||||
struct mbuf *tqe_m; /* mbuf contains packet */
|
||||
};
|
||||
LIST_HEAD(tsegqe_head, tseg_qent);
|
||||
#ifdef MALLOC_DECLARE
|
||||
MALLOC_DECLARE(M_TSEGQ);
|
||||
#endif
|
||||
extern int tcp_reass_qsize;
|
||||
extern struct uma_zone *tcp_reass_zone;
|
||||
|
||||
struct tcptemp {
|
||||
u_char tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */
|
||||
@@ -514,6 +513,7 @@ struct tcpcb *
|
||||
int tcp_output(struct tcpcb *);
|
||||
struct inpcb *
|
||||
tcp_quench(struct inpcb *, int);
|
||||
void tcp_reass_init(void);
|
||||
void tcp_respond(struct tcpcb *, void *,
|
||||
struct tcphdr *, struct mbuf *, tcp_seq, tcp_seq, int);
|
||||
int tcp_twrespond(struct tcptw *, struct socket *, struct mbuf *, int);
|
||||
|
||||
@@ -1762,12 +1762,48 @@ do { \
|
||||
break;
|
||||
}
|
||||
|
||||
optbuf = sopt->sopt_val;
|
||||
switch (optname) {
|
||||
case IPV6_HOPOPTS:
|
||||
case IPV6_DSTOPTS:
|
||||
case IPV6_RTHDRDSTOPTS:
|
||||
case IPV6_NEXTHOP:
|
||||
if (!privileged)
|
||||
error = EPERM;
|
||||
break;
|
||||
}
|
||||
if (error)
|
||||
break;
|
||||
|
||||
switch (optname) {
|
||||
case IPV6_PKTINFO:
|
||||
optlen = sizeof(struct in6_pktinfo);
|
||||
break;
|
||||
case IPV6_NEXTHOP:
|
||||
optlen = SOCK_MAXADDRLEN;
|
||||
break;
|
||||
default:
|
||||
optlen = IPV6_MAXOPTHDR;
|
||||
break;
|
||||
}
|
||||
if (sopt->sopt_valsize > optlen) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
optlen = sopt->sopt_valsize;
|
||||
optbuf = malloc(optlen, M_TEMP, M_WAITOK);
|
||||
error = sooptcopyin(sopt, optbuf, optlen,
|
||||
optlen);
|
||||
if (error) {
|
||||
free(optbuf, M_TEMP);
|
||||
break;
|
||||
}
|
||||
|
||||
optp = &in6p->in6p_outputopts;
|
||||
error = ip6_pcbopt(optname,
|
||||
optbuf, optlen,
|
||||
optp, privileged, uproto);
|
||||
free(optbuf, M_TEMP);
|
||||
break;
|
||||
}
|
||||
#undef OPTSET
|
||||
|
||||
@@ -710,6 +710,8 @@ ffs_write(ap)
|
||||
vfs_bio_clrbuf(bp);
|
||||
if (ioflag & IO_DIRECT)
|
||||
bp->b_flags |= B_DIRECT;
|
||||
if ((ioflag & (IO_SYNC|IO_INVAL)) == (IO_SYNC|IO_INVAL))
|
||||
bp->b_flags |= B_NOCACHE;
|
||||
|
||||
if (uio->uio_offset + xfersize > ip->i_size) {
|
||||
ip->i_size = uio->uio_offset + xfersize;
|
||||
|
||||
+5
-1
@@ -108,6 +108,10 @@ static int msync_flush_flags = MSYNC_FLUSH_HARDSEQ | MSYNC_FLUSH_SOFTSEQ;
|
||||
SYSCTL_INT(_vm, OID_AUTO, msync_flush_flags,
|
||||
CTLFLAG_RW, &msync_flush_flags, 0, "");
|
||||
|
||||
static int old_msync;
|
||||
SYSCTL_INT(_vm, OID_AUTO, old_msync, CTLFLAG_RW, &old_msync, 0,
|
||||
"Use old (insecure) msync behavior");
|
||||
|
||||
static void vm_object_qcollapse(vm_object_t object);
|
||||
static int vm_object_page_collect_flush(vm_object_t object, vm_page_t p, int curgeneration, int pagerflags);
|
||||
|
||||
@@ -1027,7 +1031,7 @@ vm_object_sync(vm_object_t object, vm_ooffset_t offset, vm_size_t size,
|
||||
vm_object_page_remove(object,
|
||||
OFF_TO_IDX(offset),
|
||||
OFF_TO_IDX(offset + size + PAGE_MASK),
|
||||
FALSE);
|
||||
old_msync ? FALSE : TRUE);
|
||||
}
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
}
|
||||
|
||||
@@ -565,7 +565,8 @@ fetch(char *URL, const char *path)
|
||||
/* suck in the data */
|
||||
signal(SIGINFO, sig_handler);
|
||||
while (!sigint) {
|
||||
if (us.size != -1 && us.size - count < B_size)
|
||||
if (us.size != -1 && us.size - count < B_size &&
|
||||
us.size - count >= 0)
|
||||
size = us.size - count;
|
||||
else
|
||||
size = B_size;
|
||||
|
||||
Reference in new issue
Block a user