NetBSD Problem Report #43164
From www@NetBSD.org Wed Apr 14 19:22:40 2010
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
by www.NetBSD.org (Postfix) with ESMTP id D42DC63B8FE
for <gnats-bugs@gnats.NetBSD.org>; Wed, 14 Apr 2010 19:22:40 +0000 (UTC)
Message-Id: <20100414192240.3F5ED63B8BC@www.NetBSD.org>
Date: Wed, 14 Apr 2010 19:22:40 +0000 (UTC)
From: hubertf@NetBSD.org
Reply-To: hubertf@NetBSD.org
To: gnats-bugs@NetBSD.org
Subject: tftpd: file upload broken
X-Send-Pr-Version: www-1.0
>Number: 43164
>Category: bin
>Synopsis: tftpd: file upload broken
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: hubertf
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Apr 14 19:25:00 +0000 2010
>Closed-Date: Wed Apr 28 22:22:27 +0000 2010
>Last-Modified: Wed Apr 28 22:25:03 +0000 2010
>Originator: Hubert Feyrer
>Release: netbsd-5 as of 20100103
>Organization:
NetBSD.org and some others
>Environment:
>Description:
Problem uploading files via tftp to netbsd-5 Branch i386.
Patch at the end.
Server configuration:
# grep tftp /etc/inetd.conf
tftp dgram udp wait root /usr/libexec/tftpd tftpd -l -s /tftpboot
# ident /usr/libexec/tftpd
/usr/libexec/tftpd:
$NetBSD: crt0.c,v 1.17 2007/12/01 10:16:06 yamt Exp $
$NetBSD: tftpd.c,v 1.31 2008/07/21 13:25:47 lukem Exp $
$NetBSD: tftpsubs.c,v 1.10 2006/04/09 18:45:19 christos Exp $
# ls -la /tftpboot
total 4
drwxrwxrwx 2 root wheel 512 Apr 7 23:35 .
drwxr-xr-x 25 root wheel 1024 Apr 7 23:35 ..
Failing upload:
Client:
# cd /etc
# tftp 127.0.0.1
tftp> verbose
Verbose mode on.
tftp> trace
Packet tracing on.
tftp> put group
putting group to 127.0.0.1:group [netascii]
sent WRQ <file=group, mode=netascii>
received ERROR <code=1, msg=File not found>
===> Error code 256: File not found
tftp>
Creating (empty) file for upload:
Server:
# touch /tftpboot/group
Client:
tftp> put group
putting group to 127.0.0.1:group [netascii]
sent WRQ <file=group, mode=netascii>
===> received ERROR <code=2, msg=Access violation>
Error code 512: Access violation
tftp>
Making sure everyone can write to (empty) file:
Server:
# chmod 777 /tftpboot/group
Client:
tftp> put group
putting group to 127.0.0.1:group [netascii]
sent WRQ <file=group, mode=netascii>
received ACK <block=0>
sent DATA <block=1, 512 bytes>
received ACK <block=1>
sent DATA <block=2, 102 bytes>
received ACK <block=2>
Sent 614 bytes in 0.0 seconds [inf bits/sec]
Server:
# head -1 /tftpboot/group
wheel:*:0:root
Observing ktrace eith nonexistang /tftpboot/group:
Numbers are line numbers from full ktrace output listed below[1]:
3 inetd forks & execs tftpd
844 tftpd chroots to /tftpboot
875 tftpd forks
907 stat "group", fails (of course)
911+ try to find /etc/nsswitch.conf, hosts, resolv.conf (fails)
From there things to downhill - I guess that it's trying to
syslog the failed stat, and can't reach syslog, DNS and
whatnot.
Code observation:
validate_access() does stat() the file in question,
and fails if it's not there. Which is quite likely
when uploading a file.
Fix:
Do not error out when creating a new file.
See patch below [2]
[1] Full ktrace output:
1 1341 1 inetd EMUL "netbsd"
2 1341 1 inetd RET kevent 1
3 1341 1 inetd CALL fork
4 1341 1 inetd RET fork 540/0x21c
5 1341 1 inetd CALL kevent(3,0x804efc0,1,0xbfbfe3cc,0x40,0)
6 540 1 inetd EMUL "netbsd"
7 540 1 inetd RET fork 0
8 540 1 inetd CALL __sigaction_sigtramp(SIGALRM,0xbfbfe378,0xbfbfe360,0xbbb44770,2)
9 540 1 inetd RET __sigaction_sigtramp 0
10 540 1 inetd CALL __sigaction_sigtramp(SIGHUP,0xbfbfe378,0xbfbfe360,0xbbb44770,2)
11 540 1 inetd RET __sigaction_sigtramp 0
12 540 1 inetd CALL __sigaction_sigtramp(SIGCHLD,0xbfbfe378,0xbfbfe360,0xbbb44770,2)
13 540 1 inetd RET __sigaction_sigtramp 0
14 540 1 inetd CALL __sigaction_sigtramp(SIGTERM,0xbfbfe378,0xbfbfe360,0xbbb44770,2)
15 540 1 inetd RET __sigaction_sigtramp 0
16 540 1 inetd CALL __sigaction_sigtramp(SIGINT,0xbfbfe378,0xbfbfe360,0xbbb44770,2)
17 540 1 inetd RET __sigaction_sigtramp 0
18 540 1 inetd CALL __sigaction_sigtramp(SIGPIPE,0xbfbfe378,0xbfbfe360,0xbbb44770,2)
19 540 1 inetd RET __sigaction_sigtramp 0
20 540 1 inetd CALL __stat30(0xbbba91e0,0xbfbfdee8)
21 540 1 inetd NAMI "/etc/nsswitch.conf"
22 540 1 inetd RET __stat30 0
23 540 1 inetd CALL open(0xbbba91e0,0,0x1b6)
24 540 1 inetd NAMI "/etc/nsswitch.conf"
25 540 1 inetd RET open 3
26 540 1 inetd CALL __fstat30(3,0xbfbfdce8)
27 540 1 inetd RET __fstat30 0
28 540 1 inetd CALL read(3,0xbb921000,0x4000)
29 540 1 inetd GIO fd 3 read 598 bytes
30 "# $NetBSD: nsswitch.conf,v 1.5 1999/10/24 12:36:52 lukem Exp $\n\
31 #\n# nsswitch.conf(5) -\n# name service switch configuration file\
32 \n#\n\n\n# These are the defaults in libc\n#\ngroup: compat\
33 \ngroup_compat: nis\nhosts: files dns\nnetgroup: files \
34 [notfound=return] nis\nnetworks: files\npasswd: compat\
35 \npasswd_compat: nis\nshells: files\n\n\n# List of s\
36 upported sources for each database\n#\n# group: compat, dns, f\
37 iles, nis\n# group_compat: dns, nis\n# hosts: \
38 dns, files, nis\n# netgroup: files, nis\n# networks\
39 : dns, files, nis\n# passwd: compat, dns, f\
40 iles, nis\n# passwd_compat: dns, nis\n# shells: dns, f\
41 iles, nis\n"
42 540 1 inetd RET read 598/0x256
43 540 1 inetd CALL read(3,0xbb921000,0x4000)
44 540 1 inetd GIO fd 3 read 0 bytes
45 ""
46 540 1 inetd RET read 0
47 540 1 inetd CALL open(0xbfbfd378,0,0xbfbfd298)
48 540 1 inetd NAMI "/usr/lib/nss_compat.so.0"
49 540 1 inetd RET open -1 errno 2 No such file or directory
50 540 1 inetd CALL open(0xbfbfd378,0,0xbfbfd298)
51 540 1 inetd NAMI "/usr/lib/nss_nis.so.0"
52 540 1 inetd RET open -1 errno 2 No such file or directory
53 540 1 inetd CALL open(0xbfbfd378,0,0xbfbfd298)
54 540 1 inetd NAMI "/usr/lib/nss_files.so.0"
55 540 1 inetd RET open -1 errno 2 No such file or directory
56 540 1 inetd CALL open(0xbfbfd378,0,0xbfbfd298)
57 540 1 inetd NAMI "/usr/lib/nss_dns.so.0"
58 540 1 inetd RET open -1 errno 2 No such file or directory
59 540 1 inetd CALL close(3)
60 540 1 inetd RET close 0
61 540 1 inetd CALL geteuid
62 540 1 inetd RET geteuid 0
63 540 1 inetd CALL __stat30(0xbbba4da3,0xbfbfddc0)
64 540 1 inetd NAMI "/etc/spwd.db"
65 540 1 inetd RET __stat30 0
66 540 1 inetd CALL open(0xbbba4da3,0,0)
67 540 1 inetd NAMI "/etc/spwd.db"
68 540 1 inetd RET open 3
69 540 1 inetd CALL fcntl(3,2,1)
70 540 1 inetd RET fcntl 0
71 540 1 inetd CALL __fstat30(3,0xbfbfddc0)
72 540 1 inetd RET __fstat30 0
73 540 1 inetd CALL read(3,0xbb927160,0x104)
74 540 1 inetd GIO fd 3 read 260 bytes
...
83 540 1 inetd RET read 260/0x104
84 540 1 inetd CALL pread(3,0xbb912000,0x1000,0,0x1000,0)
85 540 1 inetd GIO fd 3 read 4088 bytes
...
199 540 1 inetd GIO fd 3 read 8 bytes
...
201 540 1 inetd RET pread 4096/0x1000
202 540 1 inetd CALL pread(3,0xbb921000,0x1000,0,0x5000,0)
203 540 1 inetd GIO fd 3 read 4088 bytes
...
313 540 1 inetd GIO fd 3 read 8 bytes
...
315 540 1 inetd RET pread 4096/0x1000
316 540 1 inetd CALL pread(3,0xbb922000,0x1000,0,0x6000,0)
317 540 1 inetd GIO fd 3 read 4088 bytes
...
426 540 1 inetd GIO fd 3 read 8 bytes
...
428 540 1 inetd RET pread 4096/0x1000
429 540 1 inetd CALL close(3)
430 540 1 inetd RET close 0
431 540 1 inetd CALL fcntl(7,2,0)
432 540 1 inetd RET fcntl 0
433 540 1 inetd CALL dup2(7,0)
434 540 1 inetd RET dup2 0
435 540 1 inetd CALL close(7)
436 540 1 inetd RET close 0
437 540 1 inetd CALL dup2(0,1)
438 540 1 inetd RET dup2 1
439 540 1 inetd CALL dup2(0,2)
440 540 1 inetd RET dup2 2
441 540 1 inetd CALL execve(0xbb9040c0,0xbb90ac40,0xbfbfeb54)
442 540 1 inetd NAMI "/usr/libexec/tftpd"
443 540 1 inetd NAMI "/usr/libexec/ld.elf_so"
444 540 1 tftpd EMUL "netbsd"
445 540 1 tftpd RET syscall JUSTRETURN
446 540 1 tftpd CALL mmap(0,0x8000,3,0x1002,0xffffffff,0,0,0)
447 540 1 tftpd RET mmap -1145139200/0xbbbe9000
448 540 1 tftpd CALL open(0xbbbfbc0c,0,0)
449 540 1 tftpd NAMI "/etc/ld.so.conf"
450 540 1 tftpd RET open 3
451 540 1 tftpd CALL read(3,0xbfbfea28,0x80)
452 540 1 tftpd GIO fd 3 read 55 bytes
453 "libm.so.0 machdep.fpu_present 1:libm387.so.0,libm.so.0\n"
454 540 1 tftpd RET read 55/0x37
455 540 1 tftpd CALL close(3)
456 540 1 tftpd RET close 0
457 540 1 tftpd CALL open(0xbfbfe408,0,0)
458 540 1 tftpd NAMI "/usr/lib/libc.so.12"
459 540 1 tftpd RET open 3
460 540 1 tftpd CALL __fstat30(3,0xbfbfe344)
461 540 1 tftpd RET __fstat30 0
462 540 1 tftpd CALL mmap(0,0x1000,1,1,3,0,0,0)
463 540 1 tftpd RET mmap -1145143296/0xbbbe8000
464 540 1 tftpd CALL munmap(0xbbbe8000,0x1000)
465 540 1 tftpd RET munmap 0
466 540 1 tftpd CALL mmap(0,0xf0000,5,2,3,0,0,0)
467 540 1 tftpd RET mmap -1146122240/0xbbaf9000
468 540 1 tftpd CALL mmap(0xbbbd1000,0x8000,3,0x12,3,0,0xd8000,0)
469 540 1 tftpd RET mmap -1145237504/0xbbbd1000
470 540 1 tftpd CALL mmap(0xbbbd9000,0x10000,3,0x1012,0xffffffff,0,0,0)
471 540 1 tftpd RET mmap -1145204736/0xbbbd9000
472 540 1 tftpd CALL close(3)
473 540 1 tftpd RET close 0
474 540 1 tftpd CALL __sysctl(0xbfbfea5c,2,0x804c2a0,0xbfbfea64,0,0)
475 540 1 tftpd RET __sysctl 0
476 540 1 tftpd CALL __sysctl(0xbfbfe568,2,0xbbbe06b4,0xbfbfe570,0,0)
477 540 1 tftpd RET __sysctl 0
478 540 1 tftpd CALL __sysctl(0xbfbfe4a8,2,0xbbbe7500,0xbfbfe4b0,0,0)
479 540 1 tftpd RET __sysctl 0
480 540 1 tftpd CALL readlink(0xbbbcae58,0xbfbfe575,0x400)
481 540 1 tftpd NAMI "/etc/malloc.conf"
482 540 1 tftpd RET readlink -1 errno 2 No such file or directory
483 540 1 tftpd CALL break(0x8100000)
484 540 1 tftpd RET break 0
485 540 1 tftpd CALL mmap(0,0x100000,3,0x14001002,0xffffffff,0,0,0)
486 540 1 tftpd RET mmap -1148190720/0xbb900000
487 540 1 tftpd CALL access(0xbbbcabb4,4)
488 540 1 tftpd NAMI "/etc/localtime"
489 540 1 tftpd RET access 0
490 540 1 tftpd CALL open(0xbbbcabb4,0,0)
491 540 1 tftpd NAMI "/etc/localtime"
492 540 1 tftpd RET open 3
493 540 1 tftpd CALL read(3,0xbfbfc6af,0x1f08)
494 540 1 tftpd GIO fd 3 read 842 bytes
495 "TZif\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\b\0\0\0\b\0\0\0\0\0\0\0\M^P\
...
528 540 1 tftpd RET read 842/0x34a
529 540 1 tftpd CALL close(3)
530 540 1 tftpd RET close 0
531 540 1 tftpd CALL __socket30(1,2,0)
532 540 1 tftpd RET __socket30 3
533 540 1 tftpd CALL fcntl(3,2,1)
534 540 1 tftpd RET fcntl 0
535 540 1 tftpd CALL connect(3,0xbbbcf6c0,0x6a)
536 540 1 tftpd MISC sockargs: 106, 6a012f7661722f72756e2f6c6f670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
537 540 1 tftpd NAMI "/var/run/log"
538 540 1 tftpd RET connect 0
539 540 1 tftpd CALL getuid
540 540 1 tftpd RET getuid 0
541 540 1 tftpd CALL getgid
542 540 1 tftpd RET getgid 0
543 540 1 tftpd CALL __stat30(0xbbbce1e0,0xbfbfe8b8)
544 540 1 tftpd NAMI "/etc/nsswitch.conf"
545 540 1 tftpd RET __stat30 0
546 540 1 tftpd CALL open(0xbbbce1e0,0,0x1b6)
547 540 1 tftpd NAMI "/etc/nsswitch.conf"
548 540 1 tftpd RET open 4
549 540 1 tftpd CALL __fstat30(4,0xbfbfe6b8)
550 540 1 tftpd RET __fstat30 0
551 540 1 tftpd CALL read(4,0xbb91a000,0x4000)
552 540 1 tftpd GIO fd 4 read 598 bytes
553 "# $NetBSD: nsswitch.conf,v 1.5 1999/10/24 12:36:52 lukem Exp $\n\
554 #\n# nsswitch.conf(5) -\n# name service switch configuration file\
555 \n#\n\n\n# These are the defaults in libc\n#\ngroup: compat\
556 \ngroup_compat: nis\nhosts: files dns\nnetgroup: files \
557 [notfound=return] nis\nnetworks: files\npasswd: compat\
558 \npasswd_compat: nis\nshells: files\n\n\n# List of s\
559 upported sources for each database\n#\n# group: compat, dns, f\
560 iles, nis\n# group_compat: dns, nis\n# hosts: \
561 dns, files, nis\n# netgroup: files, nis\n# networks\
562 : dns, files, nis\n# passwd: compat, dns, f\
563 iles, nis\n# passwd_compat: dns, nis\n# shells: dns, f\
564 iles, nis\n"
565 540 1 tftpd RET read 598/0x256
566 540 1 tftpd CALL read(4,0xbb91a000,0x4000)
567 540 1 tftpd GIO fd 4 read 0 bytes
568 ""
569 540 1 tftpd RET read 0
570 540 1 tftpd CALL open(0xbfbfdd48,0,0)
571 540 1 tftpd NAMI "/usr/lib/nss_compat.so.0"
572 540 1 tftpd RET open -1 errno 2 No such file or directory
573 540 1 tftpd CALL open(0xbfbfdd48,0,0)
574 540 1 tftpd NAMI "/usr/lib/nss_nis.so.0"
575 540 1 tftpd RET open -1 errno 2 No such file or directory
576 540 1 tftpd CALL open(0xbfbfdd48,0,0)
577 540 1 tftpd NAMI "/usr/lib/nss_files.so.0"
578 540 1 tftpd RET open -1 errno 2 No such file or directory
579 540 1 tftpd CALL open(0xbfbfdd48,0,0)
580 540 1 tftpd NAMI "/usr/lib/nss_dns.so.0"
581 540 1 tftpd RET open -1 errno 2 No such file or directory
582 540 1 tftpd CALL close(4)
583 540 1 tftpd RET close 0
584 540 1 tftpd CALL geteuid
585 540 1 tftpd RET geteuid 0
586 540 1 tftpd CALL __stat30(0xbbbc9da3,0xbfbfe790)
587 540 1 tftpd NAMI "/etc/spwd.db"
588 540 1 tftpd RET __stat30 0
589 540 1 tftpd CALL open(0xbbbc9da3,0,0)
590 540 1 tftpd NAMI "/etc/spwd.db"
591 540 1 tftpd RET open 4
592 540 1 tftpd CALL fcntl(4,2,1)
593 540 1 tftpd RET fcntl 0
594 540 1 tftpd CALL __fstat30(4,0xbfbfe790)
595 540 1 tftpd RET __fstat30 0
596 540 1 tftpd CALL read(4,0xbb926160,0x104)
597 540 1 tftpd GIO fd 4 read 260 bytes
...
606 540 1 tftpd RET read 260/0x104
607 540 1 tftpd CALL pread(4,0xbb91b000,0x1000,0,0x1000,0)
608 540 1 tftpd GIO fd 4 read 4088 bytes
...
722 540 1 tftpd GIO fd 4 read 8 bytes
...
724 540 1 tftpd RET pread 4096/0x1000
725 540 1 tftpd CALL pread(4,0xbb91c000,0x1000,0,0x5000,0)
726 540 1 tftpd GIO fd 4 read 4088 bytes
...
836 540 1 tftpd GIO fd 4 read 8 bytes
...
838 540 1 tftpd RET pread 4096/0x1000
839 540 1 tftpd CALL close(4)
840 540 1 tftpd RET close 0
841 540 1 tftpd CALL chdir(0xbfbffc18)
842 540 1 tftpd NAMI "/tftpboot"
843 540 1 tftpd RET chdir 0
844 540 1 tftpd CALL chroot(0x804b1cd)
845 540 1 tftpd NAMI "."
846 540 1 tftpd RET chroot 0
847 540 1 tftpd CALL gettimeofday(0xbfbfdc48,0)
848 540 1 tftpd RET gettimeofday 0
849 540 1 tftpd CALL getpid
850 540 1 tftpd RET getpid 540/0x21c, 1341/0x53d
851 540 1 tftpd CALL fcntl(3,3,0)
852 540 1 tftpd RET fcntl 2
853 540 1 tftpd CALL sendto(3,0xbfbfdcf8,0x5c,0,0,0)
854 540 1 tftpd MISC msghdr: 28, 0000000000000000d4bcddcb01000000000000000600000000000000
855 540 1 tftpd GIO fd 3 wrote 92 bytes
856 "<31>Apr 7 23:41:26 tftpd[540]: running as user `nobody' (32767), grou\
857 p `(unspecified)' (39)"
858 540 1 tftpd RET sendto 92/0x5c
859 540 1 tftpd CALL setgid(0x27)
860 540 1 tftpd RET setgid 0
861 540 1 tftpd CALL setgroups(0,0)
862 540 1 tftpd RET setgroups 0
863 540 1 tftpd CALL setuid(0x7fff)
864 540 1 tftpd RET setuid 0
865 540 1 tftpd CALL ioctl(0,FIONBIO,0xbfbfea4c)
866 540 1 tftpd GIO fd 0 wrote 4 bytes
867 "\^A\0\0\0"
868 540 1 tftpd RET ioctl 0
869 540 1 tftpd CALL recvfrom(0,0x804ce20,0xffbc,0,0x804c960,0x804cbec)
870 540 1 tftpd MISC msghdr: 28, 00000000207ae8cbc8bcddcb010000000000000092eb4fc000000000
871 540 1 tftpd GIO fd 0 read 17 bytes
872 "\0\^Bgroup\0netascii\0"
873 540 1 tftpd MISC sockname: 16, 1002fb987f0000010000000000000000
874 540 1 tftpd RET recvfrom 17/0x11
875 540 1 tftpd CALL fork
876 540 1 tftpd RET fork 670/0x29e
877 540 1 tftpd CALL exit(0)
878 1341 1 inetd RET kevent 1
879 1341 1 inetd CALL wait4(0xffffffff,0xbfbfead4,1,0)
880 1341 1 inetd RET wait4 540/0x21c
881 1341 1 inetd CALL wait4(0xffffffff,0xbfbfead4,1,0)
882 1341 1 inetd RET wait4 -1 errno 10 No child processes
883 1341 1 inetd CALL kevent(3,0x804efc0,1,0xbfbfe3cc,0x40,0)
884 670 1 tftpd EMUL "netbsd"
885 670 1 tftpd RET fork 0
886 670 1 tftpd CALL getsockname(0,0xbfbfea54,0xbfbfea44)
887 670 1 tftpd MISC sockname: 16, 10020045000000000000000000000000
888 670 1 tftpd RET getsockname 0
889 670 1 tftpd CALL setitimer(0,0xbfbfe9d4,0xbfbfe9c4)
890 670 1 tftpd RET setitimer 0
891 670 1 tftpd CALL close(0)
892 670 1 tftpd RET close 0
893 670 1 tftpd CALL close(1)
894 670 1 tftpd RET close 0
895 670 1 tftpd CALL __socket30(2,2,0)
896 670 1 tftpd RET __socket30 0
897 670 1 tftpd CALL bind(0,0xbfbfea54,0x10)
898 670 1 tftpd MISC sockargs: 16, 10020000000000000000000000000000
899 670 1 tftpd RET bind 0
900 670 1 tftpd CALL connect(0,0x804c960,0x10)
901 670 1 tftpd MISC sockargs: 16, 1002fb987f0000010000000000000000
902 670 1 tftpd RET connect 0
903 670 1 tftpd CALL setsockopt(0,0xffff,0x1001,0xbfbfea48,4)
904 670 1 tftpd RET setsockopt 0
905 670 1 tftpd CALL setsockopt(0,0xffff,0x1002,0xbfbfea48,4)
906 670 1 tftpd RET setsockopt 0
907 670 1 tftpd CALL __stat30(0x804ce22,0xbfbfe978)
908 670 1 tftpd NAMI "group"
909 670 1 tftpd RET __stat30 -1 errno 2 No such file or directory
910 670 1 tftpd CALL __stat30(0xbbbce1e0,0xbfbfe408)
911 670 1 tftpd NAMI "/etc/nsswitch.conf"
912 670 1 tftpd RET __stat30 -1 errno 2 No such file or directory
913 670 1 tftpd CALL open(0xbbbcc3e3,0,0x1b6)
914 670 1 tftpd NAMI "/etc/hosts"
915 670 1 tftpd RET open -1 errno 2 No such file or directory
916 670 1 tftpd CALL open(0xbbbcc3e3,0,0x1b6)
917 670 1 tftpd NAMI "/etc/hosts"
918 670 1 tftpd RET open -1 errno 2 No such file or directory
919 670 1 tftpd CALL gettimeofday(0xbfbfd9f8,0)
920 670 1 tftpd RET gettimeofday 0
921 670 1 tftpd CALL getpid
922 670 1 tftpd RET getpid 670/0x29e, 1
923 670 1 tftpd CALL open(0xbbbcc758,0,0x1b6)
924 670 1 tftpd NAMI "/etc/resolv.conf"
925 670 1 tftpd RET open -1 errno 2 No such file or directory
926 670 1 tftpd CALL __sysctl(0xbfbfd9e8,2,0xbfbfdba8,0xbfbfd9f0,0,0)
927 670 1 tftpd RET __sysctl 0
928 670 1 tftpd CALL getrlimit(8,0xbfbfd388)
929 670 1 tftpd RET getrlimit 0
930 670 1 tftpd CALL __socket30(2,2,0)
931 670 1 tftpd RET __socket30 1
932 670 1 tftpd CALL connect(1,0xbbbe7ef0,0x10)
933 670 1 tftpd MISC sockargs: 16, 00020035000000000000000000000000
934 670 1 tftpd RET connect 0
935 670 1 tftpd CALL sendto(1,0xbfbfdbe8,0x28,0,0,0)
936 670 1 tftpd MISC msghdr: 28, 0000000000000000d4ece7cb01000000000000000600000000000000
937 670 1 tftpd GIO fd 1 wrote 40 bytes
938 "\M-bA\^A\0\0\^A\0\0\0\0\0\0\^A1\^A0\^A0\^C127\ain-addr\^Darpa\0\0\f\0\
939 \^A"
940 670 1 tftpd RET sendto 40/0x28
941 670 1 tftpd CALL clock_gettime(0,0xbfbfd240)
942 670 1 tftpd RET clock_gettime 0
943 670 1 tftpd CALL poll(0xbfbfd2f8,1,0x1388)
944 670 1 tftpd RET poll 1
945 670 1 tftpd CALL recvfrom(1,0xbb926000,0x10000,0,0xbfbfd304,0xbfbfd300)
946 670 1 tftpd MISC msghdr: 28, 00000000a072e8cbc8ece7cb010000000000000092eb4fc000000000
947 670 1 tftpd RET recvfrom -1 errno 61 Connection refused
948 670 1 tftpd CALL close(1)
949 670 1 tftpd RET close 0
950 670 1 tftpd CALL __socket30(2,2,0)
951 670 1 tftpd RET __socket30 1
952 670 1 tftpd CALL connect(1,0xbbbe7ef0,0x10)
953 670 1 tftpd MISC sockargs: 16, 00020035000000000000000000000000
954 670 1 tftpd RET connect 0
955 670 1 tftpd CALL sendto(1,0xbfbfdbe8,0x28,0,0,0)
956 670 1 tftpd MISC msghdr: 28, 0000000000000000d4ece7cb01000000000000000600000000000000
957 670 1 tftpd GIO fd 1 wrote 40 bytes
958 "\M-bA\^A\0\0\^A\0\0\0\0\0\0\^A1\^A0\^A0\^C127\ain-addr\^Darpa\0\0\f\0\
959 \^A"
960 670 1 tftpd RET sendto 40/0x28
961 670 1 tftpd CALL clock_gettime(0,0xbfbfd240)
962 670 1 tftpd RET clock_gettime 0
963 670 1 tftpd CALL poll(0xbfbfd2f8,1,0x2710)
964 670 1 tftpd RET poll 1
965 670 1 tftpd CALL recvfrom(1,0xbb926000,0x10000,0,0xbfbfd304,0xbfbfd300)
966 670 1 tftpd MISC msghdr: 28, 00000000a072e8cbc8ece7cb010000000000000092eb4fc000000000
967 670 1 tftpd RET recvfrom -1 errno 61 Connection refused
968 670 1 tftpd CALL close(1)
969 670 1 tftpd RET close 0
970 670 1 tftpd CALL gettimeofday(0xbfbfdc48,0)
971 670 1 tftpd RET gettimeofday 0
972 670 1 tftpd CALL getpid
973 670 1 tftpd RET getpid 670/0x29e, 1
974 670 1 tftpd CALL fcntl(3,3,0)
975 670 1 tftpd RET fcntl 2
976 670 1 tftpd CALL sendto(3,0xbfbfdcf8,0x52,0,0,0)
977 670 1 tftpd MISC msghdr: 28, 0000000000000000d4ece7cb01000000000000000600000000000000
978 670 1 tftpd GIO fd 3 wrote 82 bytes
979 "<30>Apr 7 23:41:26 tftpd[670]: 127.0.0.1: write request for group: Fi\
980 le not found"
981 670 1 tftpd RET sendto 82/0x52
982 670 1 tftpd CALL sendto(0,0x804ce20,0x13,0,0,0)
983 670 1 tftpd MISC msghdr: 28, 0000000000000000d4ece7cb01000000000000000600000000000000
984 670 1 tftpd GIO fd 0 wrote 19 bytes
985 "\0\^E\0\^AFile not found\0"
986 670 1 tftpd RET sendto 19/0x13
987 670 1 tftpd CALL exit(1)
[2] Patch:
Index: tftpd.c
===================================================================
RCS file: /cvsroot/src/libexec/tftpd/tftpd.c,v
retrieving revision 1.31
diff -u -r1.31 tftpd.c
--- tftpd.c 21 Jul 2008 13:25:47 -0000 1.31
+++ tftpd.c 14 Apr 2010 19:08:44 -0000
@@ -722,6 +722,8 @@
static char pathname[MAXPATHLEN];
char *filename;
int fd;
+ int creat=0;
+ int trunc=0;
filename = *filep;
@@ -787,21 +789,38 @@
return (EACCESS);
*filep = filename = pathname;
} else {
+ int rc;
+
/*
* If there's no directory list, take our cue from the
* absolute file request check above (*filename == '/'),
* and allow access to anything.
*/
- if (stat(filename, &stbuf) < 0)
- return (errno == ENOENT ? ENOTFOUND : EACCESS);
- if (!S_ISREG(stbuf.st_mode))
- return (ENOTFOUND);
+ rc = stat(filename, &stbuf);
if (mode == RRQ) {
+ if (rc < 0)
+ return (errno == ENOENT ? ENOTFOUND : EACCESS);
+ if (!S_ISREG(stbuf.st_mode))
+ return (ENOTFOUND);
if ((stbuf.st_mode & S_IROTH) == 0)
return (EACCESS);
} else {
- if ((stbuf.st_mode & S_IWOTH) == 0)
- return (EACCESS);
+ if (rc < 0) {
+ /* Can't stat */
+ if (errno == EACCES) {
+ /* Permission denied */
+ return EACCESS;
+ } else {
+ /* Not there - need to creat new file! */
+ creat = O_CREAT;
+ }
+ } else {
+ /* Can stat */
+ if ((stbuf.st_mode & S_IWOTH) == 0) {
+ return (EACCESS);
+ }
+ trunc = O_TRUNC;
+ }
}
*filep = filename;
}
@@ -810,9 +829,10 @@
if (tftp_opt_tsize && mode == RRQ)
tftp_tsize = (unsigned long) stbuf.st_size;
- fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY | O_TRUNC);
- if (fd < 0)
+ fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY | trunc | creat, 0644); /*644=debatable... maybe 646? or 004? or 006, so the file can be overwritten? */
+ if (fd < 0) {
return (errno + 100);
+ }
file = fdopen(fd, (mode == RRQ)? "r":"w");
if (file == NULL) {
close(fd);
>How-To-Repeat:
see above
>Fix:
see above
>Release-Note:
>Audit-Trail:
From: Takahiro Kambe <taca@back-street.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: bin/43164: tftpd: file upload broken
Date: Fri, 16 Apr 2010 12:57:24 +0900 (JST)
Hi.
Do you expect to tftpd creating a new file?
--
Takahiro Kambe <taca@back-street.net>
From: Hubert Feyrer <hubert@feyrer.de>
To: gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/43164: tftpd: file upload broken
Date: Fri, 16 Apr 2010 08:08:38 +0200 (CEST)
On Fri, 16 Apr 2010, Takahiro Kambe wrote:
> Do you expect to tftpd creating a new file?
When I do "put foo" yes of course I expect it to create a new file "foo".
That's also what I see from other tftpd implementaitons.
- Hubert
From: Takahiro Kambe <taca@back-street.net>
To: hubert@feyrer.de
Cc: gnats-bugs@NetBSD.org
Subject: Re: bin/43164: tftpd: file upload broken
Date: Fri, 16 Apr 2010 15:23:22 +0900 (JST)
In message <alpine.DEB.1.10.1004160808000.21020@calanda.fehu.org>
on Fri, 16 Apr 2010 08:08:38 +0200 (CEST),
Hubert Feyrer <hubert@feyrer.de> wrote:
> On Fri, 16 Apr 2010, Takahiro Kambe wrote:
>> Do you expect to tftpd creating a new file?
>
> When I do "put foo" yes of course I expect it to create a new file
> "foo".
Quote from tftpd(8):
The use of tftp(1) does not require an account or password on the remote
system. Due to the lack of authentication information, tftpd will allow
only publicly readable files to be accessed. Filenames beginning in
``../'' or containing ``/../'' are not allowed. Files may be written to
only if they already exist and are publicly writable.
It is the specification of tftpd(8) since 4.2BSD.
> That's also what I see from other tftpd implementaitons.
If you really want to allow tftpd(8) to creating a new file, it should
be provided as "--insecure" option and not be allowed default.
--
Takahiro Kambe <taca@back-street.net>
State-Changed-From-To: open->closed
State-Changed-By: mrg@NetBSD.org
State-Changed-When: Fri, 16 Apr 2010 07:26:00 +0000
State-Changed-Why:
this is not a bug.
this is exactly how our tftpd is supposed to work.
From: Hubert Feyrer <hubert@feyrer.de>
To: mrg@NetBSD.org
Cc: gnats-bugs@NetBSD.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/43164 (tftpd: file upload broken)
Date: Fri, 16 Apr 2010 09:58:06 +0200 (CEST)
On Fri, 16 Apr 2010, mrg@NetBSD.org wrote:
> State-Changed-From-To: open->closed
I'm not fond of "it's not broken if it's documented", if there's no clear
documentation and if the code behaves different than what one would
commonly expect. And judgement of it's insecure is left to me, please.
I see a point that it's good to prevent a DOS by default,
but I also think that adding a "allow general writes" switch makes sense.
As such, please re-open the PR and assign it to me that I can look into
adding such an option.
Thanks!
- Hubert
From: matthew green <mrg@eterna.com.au>
To: Hubert Feyrer <hubert@feyrer.de>
Cc: gnats-bugs@NetBSD.org
Subject: re: bin/43164 (tftpd: file upload broken)
Date: Fri, 16 Apr 2010 18:13:49 +1000
As such, please re-open the PR and assign it to me that I can look into
adding such an option.
go for it.
.mrg.
Responsible-Changed-From-To: bin-bug-people->hubertf
Responsible-Changed-By: hubertf@NetBSD.org
Responsible-Changed-When: Fri, 16 Apr 2010 20:29:08 +0000
Responsible-Changed-Why:
let's add this with an option
State-Changed-From-To: closed->feedback
State-Changed-By: hubertf@NetBSD.org
State-Changed-When: Fri, 16 Apr 2010 20:29:08 +0000
State-Changed-Why:
let's add this with an option
From: Hubert Feyrer <hubert@feyrer.de>
To: gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/43164 (tftpd: file upload broken)
Date: Fri, 16 Apr 2010 22:41:54 +0200 (CEST)
Updated patch (V2):
Currently, file uploads require files to exist.
Allow file upload without that restriction if option -w is used.
Document with hint at proper security precautions.
Patch applies to netbsd-4 and netbsd-5 branch as of 20100414.
- Hubert Feyrer <hubert@feyrer.de>
Index: tftpd.c
===================================================================
RCS file: /cvsroot/src/libexec/tftpd/tftpd.c,v
retrieving revision 1.31
diff -u -r1.31 tftpd.c
--- tftpd.c 21 Jul 2008 13:25:47 -0000 1.31
+++ tftpd.c 16 Apr 2010 20:35:11 -0000
@@ -108,6 +108,7 @@
static int logging;
static int secure;
static char *securedir;
+static int unrestricted_writes; /* uploaded files don't have to exist */
struct formats;
@@ -170,7 +171,7 @@
curuid = getuid();
curgid = getgid();
- while ((ch = getopt(argc, argv, "dg:lns:u:")) != -1)
+ while ((ch = getopt(argc, argv, "dg:lns:u:w")) != -1)
switch (ch) {
case 'd':
debug++;
@@ -197,6 +198,10 @@
tgtuser = optarg;
break;
+ case 'w':
+ unrestricted_writes = 1;
+ break;
+
default:
usage();
break;
@@ -722,6 +727,8 @@
static char pathname[MAXPATHLEN];
char *filename;
int fd;
+ int creat=0;
+ int trunc=0;
filename = *filep;
@@ -787,21 +794,46 @@
return (EACCESS);
*filep = filename = pathname;
} else {
+ int stat_rc;
+
/*
* If there's no directory list, take our cue from the
* absolute file request check above (*filename == '/'),
* and allow access to anything.
*/
- if (stat(filename, &stbuf) < 0)
- return (errno == ENOENT ? ENOTFOUND : EACCESS);
- if (!S_ISREG(stbuf.st_mode))
- return (ENOTFOUND);
+ stat_rc = stat(filename, &stbuf);
if (mode == RRQ) {
+ /* Read request */
+ if (stat_rc < 0)
+ return (errno == ENOENT ? ENOTFOUND : EACCESS);
+ if (!S_ISREG(stbuf.st_mode))
+ return (ENOTFOUND);
if ((stbuf.st_mode & S_IROTH) == 0)
return (EACCESS);
} else {
- if ((stbuf.st_mode & S_IWOTH) == 0)
- return (EACCESS);
+ /* Write request */
+ if (stat_rc < 0) {
+ /* Can't stat */
+ if (errno == EACCES) {
+ /* Permission denied */
+ return EACCESS;
+ } else {
+ /* Not there */
+ if (unrestricted_writes) {
+ /* need to creat new file! */
+ creat = O_CREAT;
+ } else {
+ /* Permission denied */
+ return EACCESS;
+ }
+ }
+ } else {
+ /* Can stat */
+ if ((stbuf.st_mode & S_IWOTH) == 0) {
+ return (EACCESS);
+ }
+ trunc = O_TRUNC;
+ }
}
*filep = filename;
}
@@ -810,9 +842,10 @@
if (tftp_opt_tsize && mode == RRQ)
tftp_tsize = (unsigned long) stbuf.st_size;
- fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY | O_TRUNC);
- if (fd < 0)
+ fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY | trunc | creat, 0644); /*644=debatable... maybe 646? or 004? or 006, so the file can be overwritten? */
+ if (fd < 0) {
return (errno + 100);
+ }
file = fdopen(fd, (mode == RRQ)? "r":"w");
if (file == NULL) {
close(fd);
Index: tftpd.8
===================================================================
RCS file: /cvsroot/src/libexec/tftpd/tftpd.8,v
retrieving revision 1.21
diff -u -r1.21 tftpd.8
--- tftpd.8 7 Aug 2003 09:46:53 -0000 1.21
+++ tftpd.8 16 Apr 2010 20:35:11 -0000
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)tftpd.8 8.1 (Berkeley) 6/4/93
.\"
-.Dd June 11, 2003
+.Dd April 16, 2010
.Dt TFTPD 8
.Os
.Sh NAME
@@ -45,6 +45,7 @@
.Op Fl n
.Op Fl s Ar directory
.Op Fl u Ar user
+.Op Fl w
.Op Ar directory ...
.Sh DESCRIPTION
.Nm
@@ -68,7 +69,10 @@
will allow only publicly readable files to be accessed.
Filenames beginning in ``\|\fB.\|.\fP\|/'' or
containing ``/\|\fB.\|.\fP\|/'' are not allowed.
-Files may be written to only if they already exist and are publicly writable.
+Unless option
+.Fl w
+is used,
+files may be written to only if they already exist and are publicly writable.
.Pp
Note that this extends the concept of
.Qq public
@@ -141,6 +145,9 @@
isn't also given, change the gid to that of
.Ar user
as well.
+.Fl w
+Allow unrestricted writing of new files, with no need for
+a prior existance.
.El
.Sh SEE ALSO
.Xr tftp 1 ,
@@ -220,3 +227,9 @@
sort of file-access restrictions in place.
The exact methods are specific to each site and therefore
difficult to document here.
+.Pp
+If unrestricted file upload is enabled via the
+.Fl w
+option, care should be taken that this can be used
+to fill up disk space in an uncontrolled manner
+if this is used in an insecure environment.
From: Takahiro Kambe <taca@back-street.net>
To: gnats-bugs@NetBSD.org, hubert@feyrer.de
Cc:
Subject: Re: bin/43164 (tftpd: file upload broken)
Date: Sat, 17 Apr 2010 12:07:38 +0900 (JST)
In message <20100416204502.81AD163B8BC@www.NetBSD.org>
on Fri, 16 Apr 2010 20:45:02 +0000 (UTC),
Hubert Feyrer <hubert@feyrer.de> wrote:
> Currently, file uploads require files to exist.
> Allow file upload without that restriction if option -w is used.
How about using -W to warn it is danger option?
--
Takahiro Kambe <taca@back-street.net>
From: Hubert Feyrer <hubert@feyrer.de>
To: Takahiro Kambe <taca@back-street.net>
Cc: gnats-bugs@NetBSD.org, Hubert Feyrer <hubert@feyrer.de>
Subject: Re: bin/43164 (tftpd: file upload broken)
Date: Sat, 17 Apr 2010 09:18:39 +0200 (CEST)
Hi,
On Sat, 17 Apr 2010, Takahiro Kambe wrote:
>> Allow file upload without that restriction if option -w is used.
> How about using -W to warn it is danger option?
Thanks for your feedback.
I'm not sure what you mean here:
* rename the -w in my patch to -W, or
* add an additional option, to do the warnings?
- Hubert
From: Takahiro Kambe <taca@back-street.net>
To: hubert@feyrer.de
Cc: gnats-bugs@NetBSD.org
Subject: Re: bin/43164 (tftpd: file upload broken)
Date: Sat, 17 Apr 2010 16:50:44 +0900 (JST)
In message <alpine.DEB.1.10.1004170916530.21020@calanda.fehu.org>
on Sat, 17 Apr 2010 09:18:39 +0200 (CEST),
Hubert Feyrer <hubert@feyrer.de> wrote:
> On Sat, 17 Apr 2010, Takahiro Kambe wrote:
>>> Allow file upload without that restriction if option -w is used.
>> How about using -W to warn it is danger option?
>
> Thanks for your feedback. I'm not sure what you mean here:
> * rename the -w in my patch to -W, or
This one.
This is only an idea.
--
Takahiro Kambe <taca@back-street.net>
State-Changed-From-To: feedback->closed
State-Changed-By: hubertf@NetBSD.org
State-Changed-When: Wed, 28 Apr 2010 22:22:27 +0000
State-Changed-Why:
Patch committed.
From: Hubert Feyrer <hubertf@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/43164 CVS commit: src
Date: Wed, 28 Apr 2010 22:21:51 +0000
Module Name: src
Committed By: hubertf
Date: Wed Apr 28 22:21:51 UTC 2010
Modified Files:
src/doc: CHANGES
src/libexec/tftpd: tftpd.8 tftpd.c
Log Message:
tftpd(8): Add -w so files can be uploaded without requiring them
to be created before the upload. See the section on security
considerations before enabling. [hubertf 20100429]
Addresses PR bin/43164.
To generate a diff of this commit:
cvs rdiff -u -r1.1383 -r1.1384 src/doc/CHANGES
cvs rdiff -u -r1.24 -r1.25 src/libexec/tftpd/tftpd.8
cvs rdiff -u -r1.36 -r1.37 src/libexec/tftpd/tftpd.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.