Hello community,
here is the log from the commit of package tftp for openSUSE:Factory
checked in at Fri Jun 24 09:56:51 CEST 2011.
--------
--- tftp/tftp.changes 2010-12-11 01:00:45.000000000 +0100
+++ /mounts/work_src_done/STABLE/tftp/tftp.changes 2011-06-24 09:14:08.000000000 +0200
@@ -1,0 +2,19 @@
+Fri Jun 24 07:09:50 UTC 2011 - puzel@novell.com
+
+- unbreak tftp by changing to user to run as in tftpd itself,
+ not via xinetd (bnc#682340)
+
+-------------------------------------------------------------------
+Thu Jun 23 12:17:37 UTC 2011 - puzel@novell.com
+
+- update to version-5.1
+ - Add -P option to write a PID file. Patch by Ferenc Wagner.
+ - Bounce the syslog socket in standalone mode, in case the
+ syslog daemon has been restarted. Patch by Ferenc Wagner.
+ - Build fixes.
+ - Fix handling of block number wraparound after a successful
+ options negotiation.
+ - Fix a buffer overflow in option parsing.
+- fixes bnc#699714, CVE-2011-2199
+
+-------------------------------------------------------------------
calling whatdependson for head-i586
Old:
----
tftp-hpa-5.0.tar.bz2
New:
----
tftp-hpa-5.1.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ tftp.spec ++++++
--- /var/tmp/diff_new_pack.LhGDcW/_old 2011-06-24 09:54:44.000000000 +0200
+++ /var/tmp/diff_new_pack.LhGDcW/_new 2011-06-24 09:54:44.000000000 +0200
@@ -1,7 +1,7 @@
#
-# spec file for package tftp (Version 5.0)
+# spec file for package tftp
#
-# Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,13 +18,13 @@
Name: tftp
-Version: 5.0
+Version: 5.1
Release: 1
License: BSD3c
Summary: Trivial File Transfer Protocol (TFTP)
Url: http://www.kernel.org/pub/software/network/tftp/
Group: Productivity/Networking/Ftp/Clients
-Source: tftp-hpa-%{version}.tar.bz2
+Source: http://www.kernel.org/pub/software/network/tftp/tftp-hpa-%{version}.tar.bz2
Source1: tftp.xinetd
Patch0: tftp-hpa-0.43_include_sys_params.patch
Patch1: tftp-hpa-0.46_colon_check.patch
@@ -68,7 +68,7 @@
%install
%makeinstall INSTALLROOT=%{buildroot} MANDIR="%{_mandir}"
-install -D -m 0644 %{S:1} %{buildroot}%{_sysconfdir}/xinetd.d/tftp
+install -D -m 0644 %{SOURCE1} %{buildroot}%{_sysconfdir}/xinetd.d/tftp
install -d -m 0750 %{buildroot}/srv/tftpboot
%pre
++++++ tftp-hpa-0.48-tzfix.patch ++++++
--- /var/tmp/diff_new_pack.LhGDcW/_old 2011-06-24 09:54:44.000000000 +0200
+++ /var/tmp/diff_new_pack.LhGDcW/_new 2011-06-24 09:54:44.000000000 +0200
@@ -1,9 +1,9 @@
-Index: tftp-hpa-git-0.48/tftpd/tftpd.c
+Index: tftp-hpa-5.1/tftpd/tftpd.c
===================================================================
---- tftp-hpa-git-0.48.orig/tftpd/tftpd.c
-+++ tftp-hpa-git-0.48/tftpd/tftpd.c
-@@ -350,6 +350,14 @@ int main(int argc, char **argv)
- #endif
+--- tftp-hpa-5.1.orig/tftpd/tftpd.c
++++ tftp-hpa-5.1/tftpd/tftpd.c
+@@ -384,6 +384,14 @@ int main(int argc, char **argv)
+ const char *pidfile = NULL;
u_short tp_opcode;
+ time_t my_time = 0;
++++++ tftp-hpa-5.0.tar.bz2 -> tftp-hpa-5.1.tar.bz2 ++++++
++++ 20789 lines of diff (skipped)
++++ retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/tftp-hpa-5.0/CHANGES new/tftp-hpa-5.1/CHANGES
--- old/tftp-hpa-5.0/CHANGES 2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/CHANGES 2011-06-23 01:32:56.000000000 +0200
@@ -1,3 +1,17 @@
+Changes in 5.1:
+ Add -P option to write a PID file. Patch by Ferenc Wagner.
+
+ Bounce the syslog socket in standalone mode, in case the
+ syslog daemon has been restarted. Patch by Ferenc Wagner.
+
+ Build fixes.
+
+ Fix handling of block number wraparound after a successful
+ options negotiation.
+
+ Fix a buffer overflow in option parsing.
+
+
Changes in 5.0:
Try to on platforms with getaddrinfo() without AI_ADDRCONFIG or
AI_CANONNAME.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/tftp-hpa-5.0/MCONFIG.in new/tftp-hpa-5.1/MCONFIG.in
--- old/tftp-hpa-5.0/MCONFIG.in 2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/MCONFIG.in 2011-06-23 01:32:56.000000000 +0200
@@ -32,7 +32,7 @@
SBINDIR = @sbindir@
# Data root directory
-DATAROOTDIR = @datarootdir@
+datarootdir = @datarootdir@
# Binary suffixes
O = @OBJEXT@
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/tftp-hpa-5.0/aconfig.h.in new/tftp-hpa-5.1/aconfig.h.in
--- old/tftp-hpa-5.0/aconfig.h.in 2009-02-16 23:51:36.000000000 +0100
+++ new/tftp-hpa-5.1/aconfig.h.in 2011-06-23 01:33:28.000000000 +0200
@@ -21,6 +21,9 @@
/* Define to 1 if you have the `ftruncate' function. */
#undef HAVE_FTRUNCATE
+/* Define if fcntl.h defines F_SETLK */
+#undef HAVE_F_SETLK_DEFINITION
+
/* Define if getaddrinfo function was found */
#undef HAVE_GETADDRINFO
@@ -54,6 +57,12 @@
/* Define to 1 if you have the `wrap' library (-lwrap). */
#undef HAVE_LIBWRAP
+/* Define if sys/file.h defines LOCK_EX */
+#undef HAVE_LOCK_EX_DEFINITION
+
+/* Define if sys/file.h defines LOCK_SH */
+#undef HAVE_LOCK_SH_DEFINITION
+
/* Define to 1 if the system has the type `long long'. */
#undef HAVE_LONG_LONG
@@ -141,6 +150,9 @@
/* Define to 1 if you have the header file. */
#undef HAVE_SYSEXITS_H
+/* Define to 1 if you have the header file. */
+#undef HAVE_SYS_FILE_H
+
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_FILIO_H
@@ -204,6 +216,9 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
/* Define to the version of this package. */
#undef PACKAGE_VERSION
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/tftp-hpa-5.0/autogen.sh new/tftp-hpa-5.1/autogen.sh
--- old/tftp-hpa-5.0/autogen.sh 2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/autogen.sh 2011-06-23 01:32:56.000000000 +0200
@@ -1,3 +1,2 @@
#!/bin/sh
-autoheader
-autoconf
+make autoconf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/tftp-hpa-5.0/configure.in new/tftp-hpa-5.1/configure.in
--- old/tftp-hpa-5.0/configure.in 2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/configure.in 2011-06-23 01:32:56.000000000 +0200
@@ -46,6 +46,7 @@
AC_CHECK_HEADERS(sysexits.h)
AC_CHECK_HEADERS(time.h)
AC_CHECK_HEADERS(unistd.h)
+AC_CHECK_HEADERS(sys/file.h)
AC_CHECK_HEADERS(sys/filio.h)
AC_CHECK_HEADERS(sys/stat.h)
AC_CHECK_HEADERS(sys/time.h)
@@ -140,6 +141,11 @@
PA_HEADER_DEFINES(fcntl.h, int, O_BINARY)
PA_HEADER_DEFINES(fcntl.h, int, O_TEXT)
+PA_HEADER_DEFINES(fcntl.h, int, F_SETLK)
+
+PA_HEADER_DEFINES(sys/file.h, int, LOCK_SH)
+PA_HEADER_DEFINES(sys/file.h, int, LOCK_EX)
+
AH_TEMPLATE([HAVE_SIGSETJMP],
[Define if we have sigsetjmp, siglongjmp and sigjmp_buf.])
PA_SIGSETJMP([AC_DEFINE(HAVE_SIGSETJMP)])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/tftp-hpa-5.0/tftp.spec new/tftp-hpa-5.1/tftp.spec
--- old/tftp-hpa-5.0/tftp.spec 2009-02-16 23:51:36.000000000 +0100
+++ new/tftp-hpa-5.1/tftp.spec 2011-06-23 01:33:28.000000000 +0200
@@ -1,11 +1,11 @@
Summary: The client for the Trivial File Transfer Protocol (TFTP).
Name: tftp
-Version: 5.0
+Version: 5.1
Release: 1
License: BSD
Group: Applications/Internet
Source0: http://www.kernel.org/pub/software/network/tftp/tftp-hpa-%{version}.tar.gz
-BuildPreReq: tcp_wrappers
+BuildRequires: tcp_wrappers-devel
BuildRoot: %{_tmppath}/%{name}-root
%description
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/tftp-hpa-5.0/tftp.spec.in new/tftp-hpa-5.1/tftp.spec.in
--- old/tftp-hpa-5.0/tftp.spec.in 2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/tftp.spec.in 2011-06-23 01:32:56.000000000 +0200
@@ -5,7 +5,7 @@
License: BSD
Group: Applications/Internet
Source0: http://www.kernel.org/pub/software/network/tftp/tftp-hpa-%{version}.tar.gz
-BuildPreReq: tcp_wrappers
+BuildRequires: tcp_wrappers-devel
BuildRoot: %{_tmppath}/%{name}-root
%description
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/tftp-hpa-5.0/tftpd/recvfrom.c new/tftp-hpa-5.1/tftpd/recvfrom.c
--- old/tftp-hpa-5.0/tftpd/recvfrom.c 2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/tftpd/recvfrom.c 2011-06-23 01:32:56.000000000 +0200
@@ -245,7 +245,8 @@
int
myrecvfrom(int s, void *buf, int len, unsigned int flags,
- struct sockaddr *from, int *fromlen, union sock_addr *myaddr)
+ struct sockaddr *from, socklen_t * fromlen,
+ union sock_addr *myaddr)
{
/* There is no way we can get the local address, fudge it */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/tftp-hpa-5.0/tftpd/remap.c new/tftp-hpa-5.1/tftpd/remap.c
--- old/tftp-hpa-5.0/tftpd/remap.c 2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/tftpd/remap.c 2011-06-23 01:32:56.000000000 +0200
@@ -30,14 +30,13 @@
#define RULE_EXIT 0x04 /* Exit after matching this rule */
#define RULE_RESTART 0x08 /* Restart at the top after matching this rule */
#define RULE_ABORT 0x10 /* Terminate processing with an error */
-#define RULE_GETONLY 0x20 /* Applicable to GET only */
-#define RULE_PUTONLY 0x40 /* Applicable to PUT only */
-#define RULE_INVERSE 0x80 /* Execute if regex *doesn't* match */
+#define RULE_INVERSE 0x20 /* Execute if regex *doesn't* match */
struct rule {
struct rule *next;
int nrule;
int rule_flags;
+ char rule_mode;
regex_t rx;
const char *pattern;
};
@@ -221,15 +220,13 @@
case 'i':
rxflags |= REG_ICASE;
break;
- case 'G':
- r->rule_flags |= RULE_GETONLY;
- break;
- case 'P':
- r->rule_flags |= RULE_PUTONLY;
- break;
case '~':
r->rule_flags |= RULE_INVERSE;
break;
+ case 'G':
+ case 'P':
+ r->rule_mode = *p;
+ break;
default:
syslog(LOG_ERR,
"Remap command \"%s\" on line %d contains invalid char \"%c\"",
@@ -329,7 +326,7 @@
/* Execute a rule set on a string; returns a malloc'd new string. */
char *rewrite_string(const char *input, const struct rule *rules,
- int is_put, match_pattern_callback macrosub,
+ char mode, match_pattern_callback macrosub,
const char **errmsg)
{
char *current = tfstrdup(input);
@@ -348,10 +345,8 @@
}
for (ruleptr = rules; ruleptr; ruleptr = ruleptr->next) {
- if (((ruleptr->rule_flags & RULE_GETONLY) && is_put) ||
- ((ruleptr->rule_flags & RULE_PUTONLY) && !is_put)) {
+ if (ruleptr->rule_mode && ruleptr->rule_mode != mode)
continue; /* Rule not applicable, try next */
- }
if (!deadman--) {
syslog(LOG_WARNING,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/tftp-hpa-5.0/tftpd/remap.h new/tftp-hpa-5.1/tftpd/remap.h
--- old/tftp-hpa-5.0/tftpd/remap.h 2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/tftpd/remap.h 2011-06-23 01:32:56.000000000 +0200
@@ -35,7 +35,7 @@
void freerules(struct rule *);
/* Execute a rule set on a string; returns a malloc'd new string. */
-char *rewrite_string(const char *, const struct rule *, int,
+char *rewrite_string(const char *, const struct rule *, char,
match_pattern_callback, const char **);
#endif /* WITH_REGEX */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/tftp-hpa-5.0/tftpd/tftpd.8.in new/tftp-hpa-5.1/tftpd/tftpd.8.in
--- old/tftp-hpa-5.0/tftpd/tftpd.8.in 2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/tftpd/tftpd.8.in 2011-06-23 01:32:56.000000000 +0200
@@ -3,7 +3,7 @@
.\" Copyright (c) 1990, 1993, 1994
.\" The Regents of the University of California. All rights reserved.
.\"
-.\" Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
+.\" Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -30,10 +30,10 @@
.\" SUCH DAMAGE.
.\"
.\"----------------------------------------------------------------------- */
-.TH TFTPD 8 "30 July 2008" "tftp-hpa @@VERSION@@" "System Manager's Manual"
+.TH TFTPD 8 "14 September 2009" "tftp-hpa @@VERSION@@" "System Manager's Manual"
.SH NAME
.B tftpd
-\- IPv4 Trivial File Transfer Protocol server
+\- Trivial File Transfer Protocol server
.SH SYNOPSIS
.B in.tftpd
.RI [ options... ]
@@ -133,6 +133,11 @@
.B \-\-user
option.
.TP
+\fB\-\-pidfile\fP \fIpidfile\fP, \fB\-P\fP \fIpidfile\fP
+When run in standalone mode, write the process ID of the listening
+server into \fIpidfile\fP. On normal termination (SIGTERM or SIGINT)
+the pid file is automatically removed.
+.TP
\fB\-\-timeout\fP \fItimeout\fP, \fB\-t\fP \fItimeout\fP
When run from
.B inetd
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/tftp-hpa-5.0/tftpd/tftpd.c new/tftp-hpa-5.1/tftpd/tftpd.c
--- old/tftp-hpa-5.0/tftpd/tftpd.c 2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/tftpd/tftpd.c 2011-06-23 01:32:56.000000000 +0200
@@ -1,5 +1,7 @@
/*
* Copyright (c) 1983 Regents of the University of California.
+ * Copyright (c) 1999-2009 H. Peter Anvin
+ * Copyright (c) 2011 Intel Corporation; author: H. Peter Anvin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -113,18 +115,18 @@
int tftp(struct tftphdr *, int);
static void nak(int, const char *);
static void timer(int);
-static void do_opt(char *, char *, char **);
+static void do_opt(const char *, const char *, char **);
-static int set_blksize(char *, char **);
-static int set_blksize2(char *, char **);
-static int set_tsize(char *, char **);
-static int set_timeout(char *, char **);
-static int set_utimeout(char *, char **);
-static int set_rollover(char *, char **);
+static int set_blksize(uintmax_t *);
+static int set_blksize2(uintmax_t *);
+static int set_tsize(uintmax_t *);
+static int set_timeout(uintmax_t *);
+static int set_utimeout(uintmax_t *);
+static int set_rollover(uintmax_t *);
struct options {
const char *o_opt;
- int (*o_fnc) (char *, char **);
+ int (*o_fnc)(uintmax_t *);
} options[] = {
{"blksize", set_blksize},
{"blksize2", set_blksize2},
@@ -143,6 +145,13 @@
caught_sighup = 1;
}
+/* Handle exit requests by SIGTERM and SIGINT */
+static volatile sig_atomic_t exit_signal = 0;
+static void handle_exit(int sig)
+{
+ exit_signal = sig;
+}
+
/* Handle timeout signal or timeout event */
void timer(int sig)
{
@@ -171,6 +180,26 @@
}
#endif
+/*
+ * Rules for locking files; return 0 on success, -1 on failure
+ */
+static int lock_file(int fd, int lock_write)
+{
+#if defined(HAVE_FCNTL) && defined(HAVE_F_SETLK_DEFINITION)
+ struct flock fl;
+
+ fl.l_type = lock_write ? F_WRLCK : F_RDLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0; /* Whole file */
+ return fcntl(fd, F_SETLK, &fl);
+#elif defined(HAVE_LOCK_SH_DEFINITION)
+ return flock(fd, lock_write ? LOCK_EX|LOCK_NB : LOCK_SH|LOCK_NB);
+#else
+ return 0; /* Hope & pray... */
+#endif
+}
+
static void set_socket_nonblock(int fd, int flag)
{
int err;
@@ -317,9 +346,10 @@
{ "retransmit", 1, NULL, 'T' },
{ "port-range", 1, NULL, 'R' },
{ "map-file", 1, NULL, 'm' },
+ { "pidfile", 1, NULL, 'P' },
{ NULL, 0, NULL, 0 }
};
-static const char short_options[] = "46cspvVlLa:B:u:U:r:t:T:R:m:";
+static const char short_options[] = "46cspvVlLa:B:u:U:r:t:T:R:m:P:";
int main(int argc, char **argv)
{
@@ -351,6 +381,7 @@
#ifdef WITH_REGEX
char *rewrite_file = NULL;
#endif
+ const char *pidfile = NULL;
u_short tp_opcode;
/* basename() is way too much of a pain from a portability standpoint */
@@ -363,7 +394,7 @@
srand(time(NULL) ^ getpid());
while ((c = getopt_long(argc, argv, short_options, long_options, NULL))
- != -1)
+ != -1)
switch (c) {
case '4':
ai_fam = AF_INET;
@@ -466,14 +497,17 @@
case 'v':
verbosity++;
break;
- case OPT_VERBOSITY:
- verbosity = atoi(optarg);
- break;
+ case OPT_VERBOSITY:
+ verbosity = atoi(optarg);
+ break;
case 'V':
/* Print configuration to stdout and exit */
printf("%s\n", TFTPD_CONFIG_STR);
exit(0);
break;
+ case 'P':
+ pidfile = optarg;
+ break;
default:
syslog(LOG_ERR, "Unknown option: '%c'", optopt);
break;
@@ -506,16 +540,19 @@
exit(EX_NOUSER);
}
- if (spec_umask || !unixperms)
- umask(my_umask);
-
#ifdef WITH_REGEX
if (rewrite_file)
rewrite_rules = read_remap_rules(rewrite_file);
#endif
+ if (pidfile && !standalone) {
+ syslog(LOG_WARNING, "not in standalone mode, ignoring pid file");
+ pidfile = NULL;
+ }
+
/* If we're running standalone, set up the input port */
if (standalone) {
+ FILE *pf;
#ifdef HAVE_IPV6
if (ai_fam != AF_INET6) {
#endif
@@ -695,12 +732,26 @@
}
#endif
/* Daemonize this process */
- /* Note: when running in secure mode (-s), we must not chroot, since
+ /* Note: when running in secure mode (-s), we must not chdir, since
we are already in the proper directory. */
if (!nodaemon && daemon(secure, 0) < 0) {
syslog(LOG_ERR, "cannot daemonize: %m");
exit(EX_OSERR);
}
+ set_signal(SIGTERM, handle_exit, 0);
+ set_signal(SIGINT, handle_exit, 0);
+ if (pidfile) {
+ pf = fopen (pidfile, "w");
+ if (!pf) {
+ syslog(LOG_ERR, "cannot open pid file '%s' for writing: %m", pidfile);
+ pidfile = NULL;
+ } else {
+ if (fprintf(pf, "%d\n", getpid()) < 0)
+ syslog(LOG_ERR, "error writing pid file '%s': %m", pidfile);
+ if (fclose(pf))
+ syslog(LOG_ERR, "error closing pid file '%s': %m", pidfile);
+ }
+ }
if (fd6 > fd4)
fdmax = fd6;
else
@@ -733,11 +784,23 @@
lose packets as a result. */
set_signal(SIGHUP, handle_sighup, 0);
+ if (spec_umask || !unixperms)
+ umask(my_umask);
+
while (1) {
fd_set readset;
struct timeval tv_waittime;
int rv;
+ if (exit_signal) { /* happens in standalone mode only */
+ if (pidfile && unlink(pidfile)) {
+ syslog(LOG_WARNING, "error removing pid file '%s': %m", pidfile);
+ exit(EX_OSERR);
+ } else {
+ exit(0);
+ }
+ }
+
if (caught_sighup) {
caught_sighup = 0;
if (standalone) {
@@ -869,6 +932,15 @@
/* Ignore SIGHUP */
set_signal(SIGHUP, SIG_IGN, 0);
+ /* Make sure the log socket is still connected. This has to be
+ done before the chroot, while /dev/log is still accessible.
+ When not running standalone, there is little chance that the
+ syslog daemon gets restarted by the time we get here. */
+ if (secure && standalone) {
+ closelog();
+ openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
+ }
+
#ifdef HAVE_TCPWRAPPERS
/* Verify if this was a legal request for us. This has to be
done before the chroot, while /etc is still accessible. */
@@ -972,18 +1044,19 @@
}
static char *rewrite_access(char *, int, const char **);
-static int validate_access(char *, int, struct formats *, const char **);
-static void tftp_sendfile(struct formats *, struct tftphdr *, int);
-static void tftp_recvfile(struct formats *, struct tftphdr *, int);
+static int validate_access(char *, int, const struct formats *, const char **);
+static void tftp_sendfile(const struct formats *, struct tftphdr *, int);
+static void tftp_recvfile(const struct formats *, struct tftphdr *, int);
struct formats {
const char *f_mode;
char *(*f_rewrite) (char *, int, const char **);
- int (*f_validate) (char *, int, struct formats *, const char **);
- void (*f_send) (struct formats *, struct tftphdr *, int);
- void (*f_recv) (struct formats *, struct tftphdr *, int);
+ int (*f_validate) (char *, int, const struct formats *, const char **);
+ void (*f_send) (const struct formats *, struct tftphdr *, int);
+ void (*f_recv) (const struct formats *, struct tftphdr *, int);
int f_convert;
-} formats[] = {
+};
+static const struct formats formats[] = {
{
"netascii", rewrite_access, validate_access, tftp_sendfile,
tftp_recvfile, 1}, {
@@ -999,7 +1072,7 @@
{
char *cp, *end;
int argn, ecode;
- struct formats *pf = NULL;
+ const struct formats *pf = NULL;
char *origfilename;
char *filename, *mode = NULL;
const char *errmsgptr;
@@ -1103,48 +1176,38 @@
/*
* Set a non-standard block size (c.f. RFC2348)
*/
-static int set_blksize(char *val, char **ret)
+static int set_blksize(uintmax_t *vp)
{
- static char b_ret[6];
- unsigned int sz;
- char *vend;
-
- sz = (unsigned int)strtoul(val, &vend, 10);
+ uintmax_t sz = *vp;
- if (blksize_set || *vend)
+ if (blksize_set)
return 0;
if (sz < 8)
- return (0);
+ return 0;
else if (sz > max_blksize)
sz = max_blksize;
- segsize = sz;
- sprintf(*ret = b_ret, "%u", sz);
-
+ *vp = segsize = sz;
blksize_set = 1;
-
- return (1);
+ return 1;
}
/*
* Set a power-of-two block size (nonstandard)
*/
-static int set_blksize2(char *val, char **ret)
+static int set_blksize2(uintmax_t *vp)
{
- static char b_ret[6];
- unsigned int sz;
- char *vend;
-
- sz = (unsigned int)strtoul(val, &vend, 10);
+ uintmax_t sz = *vp;
- if (blksize_set || *vend)
+ if (blksize_set)
return 0;
if (sz < 8)
return (0);
else if (sz > max_blksize)
sz = max_blksize;
+ else
/* Convert to a power of two */
if (sz & (sz - 1)) {
@@ -1155,29 +1218,23 @@
sz = sz1;
}
- segsize = sz;
- sprintf(*ret = b_ret, "%u", sz);
-
+ *vp = segsize = sz;
blksize_set = 1;
-
- return (1);
+ return 1;
}
/*
* Set the block number rollover value
*/
-static int set_rollover(char *val, char **ret)
+static int set_rollover(uintmax_t *vp)
{
- uintmax_t ro;
- char *vend;
+ uintmax_t ro = *vp;
+
+ if (ro > 65535)
+ return 0;
- ro = strtoumax(val, &vend, 10);
- if (ro > 65535 || *vend)
- return 0;
-
- rollover_val = (uint16_t)ro;
- *ret = val;
- return 1;
+ rollover_val = (uint16_t)ro;
+ return 1;
}
/*
@@ -1185,22 +1242,18 @@
* For netascii mode, we don't know the size ahead of time;
* so reject the option.
*/
-static int set_tsize(char *val, char **ret)
+static int set_tsize(uintmax_t *vp)
{
- static char b_ret[sizeof(uintmax_t) * CHAR_BIT / 3 + 2];
- uintmax_t sz;
- char *vend;
+ uintmax_t sz = *vp;
- sz = strtoumax(val, &vend, 10);
-
- if (!tsize_ok || *vend)
+ if (!tsize_ok)
return 0;
if (sz == 0)
- sz = (uintmax_t) tsize;
+ sz = tsize;
- sprintf(*ret = b_ret, "%" PRIuMAX, sz);
- return (1);
+ *vp = sz;
+ return 1;
}
/*
@@ -1208,74 +1261,86 @@
* to be the (default) retransmission timeout, but being an
* integer in seconds it seems a bit limited.
*/
-static int set_timeout(char *val, char **ret)
+static int set_timeout(uintmax_t *vp)
{
- static char b_ret[4];
- unsigned long to;
- char *vend;
+ uintmax_t to = *vp;
- to = strtoul(val, &vend, 10);
-
- if (to < 1 || to > 255 || *vend)
+ if (to < 1 || to > 255)
return 0;
rexmtval = timeout = to * 1000000UL;
maxtimeout = rexmtval * TIMEOUT_LIMIT;
- sprintf(*ret = b_ret, "%lu", to);
- return (1);
+ return 1;
}
/* Similar, but in microseconds. We allow down to 10 ms. */
-static int set_utimeout(char *val, char **ret)
+static int set_utimeout(uintmax_t *vp)
{
- static char b_ret[4];
- unsigned long to;
- char *vend;
+ uintmax_t to = *vp;
- to = strtoul(val, &vend, 10);
-
- if (to < 10000UL || to > 255000000UL || *vend)
+ if (to < 10000UL || to > 255000000UL)
return 0;
rexmtval = timeout = to;
maxtimeout = rexmtval * TIMEOUT_LIMIT;
- sprintf(*ret = b_ret, "%lu", to);
- return (1);
+ return 1;
}
/*
- * Parse RFC2347 style options
+ * Conservative calculation for the size of a buffer which can hold an
+ * arbitrary integer
+ */
+#define OPTBUFSIZE (sizeof(uintmax_t) * CHAR_BIT / 3 + 3)
+
+/*
+ * Parse RFC2347 style options; we limit the arguments to positive
+ * integers which matches all our current options.
*/
-static void do_opt(char *opt, char *val, char **ap)
+static void do_opt(const char *opt, const char *val, char **ap)
{
struct options *po;
- char *ret;
+ char retbuf[OPTBUFSIZE];
+ char *p = *ap;
+ size_t optlen, retlen;
+ char *vend;
+ uintmax_t v;
/* Global option-parsing variables initialization */
blksize_set = 0;
- if (!*opt)
+ if (!*opt || !*val)
return;
+ errno = 0;
+ v = strtoumax(val, &vend, 10);
+ if (*vend || errno == ERANGE)
+ return;
+
for (po = options; po->o_opt; po++)
if (!strcasecmp(po->o_opt, opt)) {
- if (po->o_fnc(val, &ret)) {
- if (*ap + strlen(opt) + strlen(ret) + 2 >=
- ackbuf + sizeof(ackbuf)) {
+ if (po->o_fnc(&v)) {
+ optlen = strlen(opt);
+ retlen = sprintf(retbuf, "%"PRIuMAX, v);
+
+ if (p + optlen + retlen + 2 >= ackbuf + sizeof(ackbuf)) {
nak(EOPTNEG, "Insufficient space for options");
exit(0);
}
- *ap = strrchr(strcpy(strrchr(strcpy(*ap, opt), '\0') + 1,
- ret), '\0') + 1;
+
+ memcpy(p, opt, optlen+1);
+ p += optlen+1;
+ memcpy(p, retbuf, retlen+1);
+ p += retlen+1;
} else {
nak(EOPTNEG, "Unsupported option(s) requested");
exit(0);
}
break;
}
- return;
+
+ *ap = p;
}
#ifdef WITH_REGEX
@@ -1337,7 +1402,8 @@
{
if (rewrite_rules) {
char *newname =
- rewrite_string(filename, rewrite_rules, mode != RRQ,
+ rewrite_string(filename, rewrite_rules,
+ mode != RRQ ? 'P' : 'G',
rewrite_macros, msg);
filename = newname;
}
@@ -1366,7 +1432,7 @@
* given as we have no login directory.
*/
static int validate_access(char *filename, int mode,
- struct formats *pf, const char **errmsg)
+ const struct formats *pf, const char **errmsg)
{
struct stat stbuf;
int i, len;
@@ -1410,11 +1476,13 @@
* We use different a different permissions scheme if `cancreate' is
* set.
*/
- wmode = O_WRONLY |
- (cancreate ? O_CREAT : 0) |
- (unixperms ? O_TRUNC : 0) | (pf->f_convert ? O_TEXT : O_BINARY);
+ wmode = O_WRONLY | (cancreate ? O_CREAT : 0) | (pf->f_convert ? O_TEXT : O_BINARY);
rmode = O_RDONLY | (pf->f_convert ? O_TEXT : O_BINARY);
+#ifndef HAVE_FTRUNCATE
+ wmode |= O_TRUNC; /* This really sucks on a dupe */
+#endif
+
fd = open(filename, mode == RRQ ? rmode : wmode, 0666);
if (fd < 0) {
switch (errno) {
@@ -1433,6 +1501,10 @@
if (fstat(fd, &stbuf) < 0)
exit(EX_OSERR); /* This shouldn't happen */
+ /* A duplicate RRQ or (worse!) WRQ packet could really cause havoc... */
+ if (lock_file(fd, mode != RRQ))
+ exit(0);
+
if (mode == RRQ) {
if (!unixperms && (stbuf.st_mode & (S_IREAD >> 6)) == 0) {
*errmsg = "File must have global read permissions";
@@ -1447,15 +1519,15 @@
*errmsg = "File must have global write permissions";
return (EACCESS);
}
+ }
- /* We didn't get to truncate the file at open() time */
#ifdef HAVE_FTRUNCATE
- if (ftruncate(fd, (off_t) 0)) {
- *errmsg = "Cannot reset file size";
- return (EACCESS);
- }
+ /* We didn't get to truncate the file at open() time */
+ if (ftruncate(fd, (off_t) 0)) {
+ *errmsg = "Cannot reset file size";
+ return (EACCESS);
+ }
#endif
- }
tsize = 0;
tsize_ok = 1;
}
@@ -1474,7 +1546,7 @@
/*
* Send the requested file.
*/
-static void tftp_sendfile(struct formats *pf, struct tftphdr *oap, int oacklen)
+static void tftp_sendfile(const struct formats *pf, struct tftphdr *oap, int oacklen)
{
struct tftphdr *dp;
struct tftphdr *ap; /* ack packet */
@@ -1572,7 +1644,7 @@
/*
* Receive a file.
*/
-static void tftp_recvfile(struct formats *pf, struct tftphdr *oap, int oacklen)
+static void tftp_recvfile(const struct formats *pf, struct tftphdr *oap, int oacklen)
{
struct tftphdr *dp;
int n, size;
@@ -1595,6 +1667,10 @@
ap->th_opcode = htons((u_short) ACK);
ap->th_block = htons((u_short) block);
acksize = 4;
+ /* If we're sending a regular ACK, that means we have successfully
+ * sent the OACK. Clear oap so that we won't try to send another
+ * OACK when the block number wraps back to 0. */
+ oap = NULL;
}
if (!++block)
block = rollover_val;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/tftp-hpa-5.0/version new/tftp-hpa-5.1/version
--- old/tftp-hpa-5.0/version 2009-02-16 23:51:22.000000000 +0100
+++ new/tftp-hpa-5.1/version 2011-06-23 01:32:56.000000000 +0200
@@ -1 +1 @@
-5.0
+5.1
++++++ tftp.xinetd ++++++
--- /var/tmp/diff_new_pack.LhGDcW/_old 2011-06-24 09:54:44.000000000 +0200
+++ /var/tmp/diff_new_pack.LhGDcW/_new 2011-06-24 09:54:44.000000000 +0200
@@ -11,9 +11,9 @@
protocol = udp
wait = yes
flags = IPv6 IPv4
- user = tftp
+ user = root
server = /usr/sbin/in.tftpd
- server_args = -s /srv/tftpboot
+ server_args = -u tftp -s /srv/tftpboot
# per_source = 11
# cps = 100 2
disable = yes
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org