bin/176136: cp(1) fails to overwrite a symlnk pointing to a directory
>Number: 176136 >Category: bin >Synopsis: cp(1) fails to overwrite a symlnk pointing to a directory >Confidential: no >Severity: non-critical >Priority: low >Responsible:freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Feb 14 08:00:00 UTC 2013 >Closed-Date: >Last-Modified: >Originator: Akinori MUSHA >Release:9.1-STABLE >Organization: >Environment: FreeBSD 9.1-STABLE/amd64 >Description: Our implementation of cp(1) cannot overwrite a symlink pointing to an existing directory. This is because it always calls stat(2) on a destination file path even if -R (with -P by default) is given, where lstat(2) should be used instead. Dragonfly BSD, OS X and OpenBSD all share the same problem with us. NetBSD cp(1) has once had this problem but fixed it in 2006 (bin/cp.c rev.1.42). GNU cp does not have this problem. Solaris/OpenIndiana's cp(1) (/usr/xpg4/bin/cp) seems to have this problem. As far as I read, SUSv4 is not very clear as to how cp(1) should do about the situation, but there should be no reason a symlink cannot be overwritten. >How-To-Repeat: % ln -s . foo % mkdir bar % ln -s .. bar/foo Now we have and . Let's try copying to . % cp -RP foo bar/ cp: cannot overwrite directory bar/foo with non-directory foo It failed! % ls -l bar total 1 lrwxr-xr-x 1 knu knu 2 Feb 14 16:18 foo -> .. It seems cp(1) decided not to copy the source file just because the destination symlink was resolved to a directory, but it is certainly not what you would expect. >Fix: Index: cp.c === --- cp.c(revision 246770) +++ cp.c(working copy) @@ -262,7 +262,7 @@ copy(char *argv[], enum op type, int fts struct stat to_stat; FTS *ftsp; FTSENT *curr; - int base = 0, dne, badcp, rval; + int base = 0, dne, badcp, rval, sval; size_t nlen; char *p, *target_mid; mode_t mask, mode; @@ -383,8 +383,18 @@ copy(char *argv[], enum op type, int fts continue; } + /* + * lstat(2) should be used if neither -H or -L is + * given, or we will fail to overwrite an existing + * symlink pointing to a directory. + */ + if (fts_options & (FTS_LOGICAL | FTS_COMFOLLOW)) + sval = stat(to.p_path, &to_stat); +else + sval = lstat(to.p_path, &to_stat); + /* Not an error but need to remember it happened */ - if (stat(to.p_path, &to_stat) == -1) + if (sval == -1) dne = 1; else { if (to_stat.st_dev == curr->fts_statp->st_dev && >Release-Note: >Audit-Trail: >Unformatted: ___ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"
Re: bin/176136: cp(1) fails to overwrite a symlnk pointing to a directory
The following reply was made to PR bin/176136; it has been noted by GNATS. From: "Akinori MUSHA" To: freebsd-gnats-sub...@freebsd.org Cc: Subject: Re: bin/176136: cp(1) fails to overwrite a symlnk pointing to a directory Date: Thu, 14 Feb 2013 17:19:41 +0900 Seems I messed up the patch and blew up tabs, so I put it on Gist: https://gist.github.com/knu/4951299 -- Akinori MUSHA / http://akinori.org/ ___ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"
misc/176141: [zfs] sharesmb=on makes errors for sharenfs, and still sets the option
>Number: 176141 >Category: misc >Synopsis: [zfs] sharesmb=on makes errors for sharenfs, and still sets >the option >Confidential: no >Severity: non-critical >Priority: low >Responsible:freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Feb 14 10:50:00 UTC 2013 >Closed-Date: >Last-Modified: >Originator: Nathan Rich >Release:9.1-RELEASE >Organization: Dynasty Systems >Environment: FreeBSD first 9.1-RELEASE FreeBSD 9.1-RELEASE #0 r243826: Tue Dec 4 06:55:39 UTC 2012 r...@obrian.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386 >Description: Once you enable sharesmb on zfs, changing sharenfs to on or off will spit out an error (but still work). Stems from that setting sharesmb doesn't work but actually toggles the setting. >How-To-Repeat: [root@first ~]# zfs get -H sharesmb,sharenfs data datasharesmboff local datasharenfsoff local [root@first ~]# zfs sharesmb=on data Unsupported share protocol: 1. Unsupported share protocol: 1. Unsupported share protocol: 1. Unsupported share protocol: 1. Unsupported share protocol: 1. Unsupported share protocol: 1. Unsupported share protocol: 1. [root@first ~]# zfs get -H sharesmb,sharenfs data datasharesmbon local datasharenfsoff local [root@first ~]# zfs sharenfs=on data Unsupported share protocol: 1. Unsupported share protocol: 1. Unsupported share protocol: 1. Unsupported share protocol: 1. Unsupported share protocol: 1. Unsupported share protocol: 1. Unsupported share protocol: 1. [root@first ~]# zfs get -H sharesmb,sharenfs data datasharesmbon local datasharenfson local [root@first ~]# >Fix: Either: 1. Change sharesmb=on to NOT actually change the flag Or: 2. Change error message to display once and be human friendly: Warning: sharesmb set to 'on' but not supported in FreeBSD! >Release-Note: >Audit-Trail: >Unformatted: ___ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"
Re: kern/176141: [zfs] sharesmb=on makes errors for sharenfs, and still sets the option
Synopsis: [zfs] sharesmb=on makes errors for sharenfs, and still sets the option Responsible-Changed-From-To: freebsd-bugs->freebsd-fs Responsible-Changed-By: linimon Responsible-Changed-When: Thu Feb 14 11:15:44 UTC 2013 Responsible-Changed-Why: Over to maintainer(s). http://www.freebsd.org/cgi/query-pr.cgi?pr=176141 ___ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"
kern/176144: Bug in m_split() when splitting M_EXT mbufs
>Number: 176144 >Category: kern >Synopsis: Bug in m_split() when splitting M_EXT mbufs >Confidential: no >Severity: non-critical >Priority: low >Responsible:freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Feb 14 13:00:00 UTC 2013 >Closed-Date: >Last-Modified: >Originator: Jacques Fourie >Release:10-current >Organization: Netronome Systems >Environment: FreeBSD fbsd10vm 10.0-CURRENT FreeBSD 10.0-CURRENT #7 r+45b4c99-dirty: Mon Jan 7 09:40:08 SAST 2013 root@fbsd10vm:/usr/obj/usr/home/jfourie/freebsd.git/sys/FBSD10VM amd64 >Description: The following text is copied from my original mail to -hackers: Could someone please verify if m_split as in svn rev 245286 is doing the right thing in the scenario where a mbuf chain is split with len0 falling on a mbuf boundary and the mbuf in question being a M_EXT mbuf? Consider the following example where m0 is a mbuf chain consisting of 2 M_EXT mbufs, both 1448 bytes in length. Let len0 be 1448. The 'len0 > m->m_len' check will be false so the for loop will not be entered in this case. We now have len = 1448 and remain = 0 and m still points to the first mbuf in the chain. Also assume that m0 is a pkthdr mbuf. A new pkthdr mbuf n will be allocated and initialized before the following piece of code is executed : extpacket: if (m->m_flags & M_EXT) { n->m_data = m->m_data + len; mb_dupcl(n, m); } else { bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain); } n->m_len = remain; m->m_len = len; n->m_next = m->m_next; m->m_next = NULL; As m is a M_EXT mbuf the code in the if() clause will be executed. The problem is that m still points to the first mbuf so effectively the data pointer for n is assigned to the end of m's data pointer. It should actually point to the start of the data pointer of the next mbuf in the original m0 chain, right? >How-To-Repeat: >Fix: Attached patch fixes the issue for me Patch attached with submission follows: diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index ab6163d..5c397fa 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -1132,6 +1132,23 @@ m_split(struct mbuf *m0, int len0, int wait) return (NULL); remain = m->m_len - len; if (m0->m_flags & M_PKTHDR) { + if (remain == 0) { + if (m->m_next == NULL) + return (NULL); + if (!(m->m_next->m_flags & M_PKTHDR)) { + MGETHDR(n, wait, m0->m_type); + if (n == NULL) + return (NULL); + MH_ALIGN(n, 0); + n->m_next = m->m_next; + } else + n = m->m_next; + m->m_next = NULL; + n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif; + n->m_pkthdr.len = m0->m_pkthdr.len - len0; + m0->m_pkthdr.len = len0; + return (n); + } MGETHDR(n, wait, m0->m_type); if (n == NULL) return (NULL); >Release-Note: >Audit-Trail: >Unformatted: ___ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"
Re: kern/176144: Bug in m_split() when splitting M_EXT mbufs
Synopsis: Bug in m_split() when splitting M_EXT mbufs Responsible-Changed-From-To: freebsd-bugs->glebius Responsible-Changed-By: glebius Responsible-Changed-When: Thu Feb 14 13:03:20 UTC 2013 Responsible-Changed-Why: I promised to look at this. http://www.freebsd.org/cgi/query-pr.cgi?pr=176144 ___ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"