Compare commits

...
Author SHA1 Message Date
Peter Wemm 1ebb47c83a Mention FreeBSD-SA-05:03.amd64, bump patchlevel.
Approved by:  so (cperciva)
2005-04-06 02:10:53 +00:00
Peter Wemm a940444601 MFC: initialize the tss iobase properly
Approved by:  so (cperciva)
2005-04-06 01:44:36 +00:00
Colin Percival a225d5f34e FreeBSD-SA-04:17.procfs:
MFC revision 1.54 of src/sys/fs/procfs/procfs_status.c
MFC revision 1.86 of src/sys/compat/linprocfs/linprocfs.c

Approved by:	so (nectar)
2004-12-01 21:34:43 +00:00
Colin Percival 64f548f29d FreeBSD-SA-04:16.fetch:
MFC revision 1.75 of src/usr.bin/fetch/fetch.c
Bump newvers.sh and document in UPDATING.

Approved by:	so
2004-11-18 12:06:51 +00:00
Jacques Vidrine a437630a8c MFC 1.429: Disallow negative coordinates and sizes in the syscons
CONS_SCRSHOT ioctl.

Approved by:	so
2004-10-04 17:04:25 +00:00
Jacques Vidrine c92cfee45d Correct several vulnerabilities in CVS 1.11.5 (CAN-2004-0414,
CAN-2004-0416, CAN-2004-0417, CAN-2004-0418, CAN-2004-0778 and
others).

Approved by:	so
2004-09-19 22:37:11 +00:00
Colin Percival 9ff423a7d9 FreeBSD-SA-04:13.linux:
MFC revision 1.116 of sys/compat/linux/linux_ioctl.c
Bump newvers.sh and document in UPDATING.

Approved by:	so (des)
2004-06-30 17:34:38 +00:00
cvs2svn 8572a12667 This commit was manufactured by cvs2svn to create branch 'RELENG_5_2'. 2004-06-10 19:05:40 +00:00
Dag-Erling Smørgrav 4c783325c1 Bump patch level and document the change.
Approved by:	so
2004-05-26 06:44:34 +00:00
Dag-Erling Smørgrav 044fa52655 MFS: msync(2) with the MS_INVALIDATE flag should not delete dirty pages.
Approved by:	so
2004-05-25 23:07:55 +00:00
Dag-Erling Smørgrav 3ea2671c8d Merge updated patch from vendor branch (1.1.1.17)
Approved by:	so
2004-05-20 13:18:10 +00:00
Dag-Erling Smørgrav 19a7f1a9de Bump and document patch level.
Approved by:	so
2004-05-19 06:40:56 +00:00
Dag-Erling Smørgrav a2bc8b03d8 Merge parser fix from vendor branch (rev 1.1.1.16)
Approved by:	so
2004-05-19 06:19:57 +00:00
Jacques Vidrine 615a439a9e Correctly validate the transited field in Kerberos tickets.
http://vuxml.freebsd.org/bfb36941-84fa-11d8-a41f-0020ed76ef5a.html

Obtained from:	Heimdal 0.6.1
Approved by:	so
2004-05-05 19:55:46 +00:00
Jacques Vidrine 1a15dd91ff Merge from 4-STABLE client.c 1.2.2.7, modules.c 1.1.1.5.2.4:
Correct some path validation errors in CVS.

Approved by:	so
2004-04-15 15:42:50 +00:00
Jacques Vidrine 299c870ea6 MFC ip6.h 1.11, ip6_output.c 1.79:
Validate IPv6 socket options more carefully.
2004-03-29 14:01:33 +00:00
Jacques Vidrine 6ab589eba7 MFC s3_pkt.c 1.1.1.9:
Correct a denial-of-service vulnerability in OpenSSL (CAN-2004-0079).
2004-03-17 12:18:23 +00:00
Jacques Vidrine 56d478fbea Bump patch level for update of FreeBSD-SA-04:04.tcp fix. 2004-03-16 13:47:33 +00:00
Max Khon 1c464c822e The tcp_reass_qsize increment should occur only after we have
checked for memory allocation failure.  On systems that frequently
have a memory shortage, this could result in an effectively smaller
reassembly queue than was configured.

Approved by:	security-officer
2004-03-15 18:17:10 +00:00
Hideyuki KURASHINA 7cd945dd92 Merge the following from the English version:
1.3       -> 1.3.6.1    relnotes/common/relnotes.ent
  1.7       -> 1.7.4.1    share/sgml/release.dsl
  1.663.2.5 -> 1.663.2.13 relnotes/common/new.sgml

Approved by:	so (nectar)
Refined by:	hrs
2004-03-05 04:11:23 +00:00
Jacques Vidrine 2ccb8fa10b MFC in part tcp_input.c 1.228, tcp_subr.c 1.182, tcp_var.h 1.98:
Limit TCP segment reassembly queue size and use UMA for it.

Submitted by:	andre
2004-03-02 17:24:46 +00:00
Andrey A. Chernov d02dfb867e Back out prev. commit, because not approved. 2004-03-01 16:49:38 +00:00
Andrey A. Chernov c07f4f5d50 MFC important bugfixes from v1.49-1.50 2004-03-01 11:43:50 +00:00
39 changed files with 935 additions and 175 deletions

No files matched your search

+53
View File
@@ -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
+110
View File
@@ -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 */
+13
View File
@@ -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);
+6 -1
View File
@@ -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);
+4
View File
@@ -41,6 +41,10 @@
#include "popen.h"
#endif
/* Begin GNULIB headers. */
#include "xsize.h"
/* End GNULIB headers. */
#ifdef STDC_HEADERS
#include <stdlib.h>
#else
+7 -1
View File
@@ -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]);
}
+24 -9
View File
@@ -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);
}
+26
View File
@@ -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
View File
@@ -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)
+28 -6
View File
@@ -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 );
+20 -2
View File
@@ -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,
+22 -1
View File
@@ -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.
+4
View File
@@ -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
View File
@@ -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;
+9
View File
@@ -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*/,
+34 -23
View File
@@ -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,
+49
View File
@@ -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,
+1 -1
View File
@@ -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
+8
View File
@@ -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)
+1 -1
View File
@@ -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
+119 -29
View File
@@ -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>
+3
View File
@@ -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);
+1
View File
@@ -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],
-1
View File
@@ -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 */
+13 -1
View File
@@ -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);
+15 -10
View File
@@ -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, &lte, 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, &lte.cdte_addr);
copyout(&lte, (void *)args->arg, sizeof(lte));
error = copyout(&lte, (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
View File
@@ -36,7 +36,7 @@
TYPE="FreeBSD"
REVISION="5.2.1"
BRANCH="RELEASE"
BRANCH="RELEASE-p14"
RELEASE="${REVISION}-${BRANCH}"
VERSION="${TYPE} ${RELEASE}"
+4 -2
View File
@@ -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;
}
+13 -1
View File
@@ -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);
+1
View File
@@ -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
View File
@@ -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);
+5 -2
View File
@@ -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);
+3 -3
View File
@@ -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);
+37 -1
View File
@@ -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
+2
View File
@@ -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
View File
@@ -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);
}
+2 -1
View File
@@ -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;