{"thread":{"id":"11315","subject":"end of file newline regression","startedAt":"2007-12-16T23:54:13Z","lastAt":"2007-12-17T01:24:27Z","messageCount":2,"participants":["David Miller","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"63363","messageId":"20071216.155413.165709543.davem@davemloft.net","threadId":"11315","inReplyTo":null,"subject":"end of file newline regression","fromName":"David Miller","fromEmail":"davem@davemloft.net","sentAt":"2007-12-16T23:54:13Z","receivedAt":"2007-12-16T23:54:13Z","isPatch":false,"sender":{"key":"davem@davemloft.net","avatar":null},"body":"\nI've stumbled into a problem with current mainline.\n\nI have this changeset that I can't get GIT to properly\ngenerate diffs for.  It always give me:\n\ndiff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c\nindex 4440532..096974b 100644\n--- a/net/ipv6/esp6.c\n+++ b/net/ipv6/esp6.c\n@@ -177,5 +177,4 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)\n \t\t\tBUG();\n \n \t\tif (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {\n-\t\t\tx->stats.integrity_failed++;\n-\t\t\tret = -EINVAL;\n\\ No newline at end of file\n+\t\t\tret = -EBADMSG;\n\\ No newline at end of file\n\nNo matter what I do, 1.5.3.7 doesn't do this.\n\nThe file does have a newline at the end.\n\nHere are files you can hopefully use to reproduce:\n\n1) esp6.c\n2) the patch, one that can be applied properly\n\nYou should be able to put that esp6.c into an empty\ngit repo, apply the patch in #2, then run \"git diff >diff\"\nusing mainline to see the problem.\n\n\n\n/*\n * Copyright (C)2002 USAGI/WIDE Project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n *\n * Authors\n *\n *\tMitsuru KANDA @USAGI       : IPv6 Support\n * \tKazunori MIYAZAWA @USAGI   :\n * \tKunihiro Ishiguro <kunihiro@ipinfusion.com>\n *\n * \tThis file is derived from net/ipv4/esp.c\n */\n\n#include <linux/err.h>\n#include <linux/module.h>\n#include <net/ip.h>\n#include <net/xfrm.h>\n#include <net/esp.h>\n#include <linux/scatterlist.h>\n#include <linux/crypto.h>\n#include <linux/kernel.h>\n#include <linux/pfkeyv2.h>\n#include <linux/random.h>\n#include <linux/spinlock.h>\n#include <net/icmp.h>\n#include <net/ipv6.h>\n#include <net/protocol.h>\n#include <linux/icmpv6.h>\n\nstatic int esp6_output(struct xfrm_state *x, struct sk_buff *skb)\n{\n\tint err;\n\tstruct ip_esp_hdr *esph;\n\tstruct crypto_blkcipher *tfm;\n\tstruct blkcipher_desc desc;\n\tstruct sk_buff *trailer;\n\tint blksize;\n\tint clen;\n\tint alen;\n\tint nfrags;\n\tu8 *tail;\n\tstruct esp_data *esp = x->data;\n\n\t/* skb is pure payload to encrypt */\n\terr = -ENOMEM;\n\n\t/* Round to block size */\n\tclen = skb->len;\n\n\talen = esp->auth.icv_trunc_len;\n\ttfm = esp->conf.tfm;\n\tdesc.tfm = tfm;\n\tdesc.flags = 0;\n\tblksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);\n\tclen = ALIGN(clen + 2, blksize);\n\tif (esp->conf.padlen)\n\t\tclen = ALIGN(clen, esp->conf.padlen);\n\n\tif ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0) {\n\t\tgoto error;\n\t}\n\n\t/* Fill padding... */\n\ttail = skb_tail_pointer(trailer);\n\tdo {\n\t\tint i;\n\t\tfor (i=0; i<clen-skb->len - 2; i++)\n\t\t\ttail[i] = i + 1;\n\t} while (0);\n\ttail[clen-skb->len - 2] = (clen - skb->len) - 2;\n\tpskb_put(skb, trailer, clen - skb->len);\n\n\tskb_push(skb, -skb_network_offset(skb));\n\tesph = ip_esp_hdr(skb);\n\t*(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb);\n\t*skb_mac_header(skb) = IPPROTO_ESP;\n\n\tesph->spi = x->id.spi;\n\tesph->seq_no = htonl(XFRM_SKB_CB(skb)->seq);\n\n\tspin_lock_bh(&x->lock);\n\n\tif (esp->conf.ivlen) {\n\t\tif (unlikely(!esp->conf.ivinitted)) {\n\t\t\tget_random_bytes(esp->conf.ivec, esp->conf.ivlen);\n\t\t\tesp->conf.ivinitted = 1;\n\t\t}\n\t\tcrypto_blkcipher_set_iv(tfm, esp->conf.ivec, esp->conf.ivlen);\n\t}\n\n\tdo {\n\t\tstruct scatterlist *sg = &esp->sgbuf[0];\n\n\t\tif (unlikely(nfrags > ESP_NUM_FAST_SG)) {\n\t\t\tsg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);\n\t\t\tif (!sg)\n\t\t\t\tgoto unlock;\n\t\t}\n\t\tsg_init_table(sg, nfrags);\n\t\tskb_to_sgvec(skb, sg,\n\t\t\t     esph->enc_data +\n\t\t\t     esp->conf.ivlen -\n\t\t\t     skb->data, clen);\n\t\terr = crypto_blkcipher_encrypt(&desc, sg, sg, clen);\n\t\tif (unlikely(sg != &esp->sgbuf[0]))\n\t\t\tkfree(sg);\n\t} while (0);\n\n\tif (unlikely(err))\n\t\tgoto unlock;\n\n\tif (esp->conf.ivlen) {\n\t\tmemcpy(esph->enc_data, esp->conf.ivec, esp->conf.ivlen);\n\t\tcrypto_blkcipher_get_iv(tfm, esp->conf.ivec, esp->conf.ivlen);\n\t}\n\n\tif (esp->auth.icv_full_len) {\n\t\terr = esp_mac_digest(esp, skb, (u8 *)esph - skb->data,\n\t\t\t\t     sizeof(*esph) + esp->conf.ivlen + clen);\n\t\tmemcpy(pskb_put(skb, trailer, alen), esp->auth.work_icv, alen);\n\t}\n\nunlock:\n\tspin_unlock_bh(&x->lock);\n\nerror:\n\treturn err;\n}\n\nstatic int esp6_input(struct xfrm_state *x, struct sk_buff *skb)\n{\n\tstruct ipv6hdr *iph;\n\tstruct ip_esp_hdr *esph;\n\tstruct esp_data *esp = x->data;\n\tstruct crypto_blkcipher *tfm = esp->conf.tfm;\n\tstruct blkcipher_desc desc = { .tfm = tfm };\n\tstruct sk_buff *trailer;\n\tint blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);\n\tint alen = esp->auth.icv_trunc_len;\n\tint elen = skb->len - sizeof(*esph) - esp->conf.ivlen - alen;\n\tint hdr_len = skb_network_header_len(skb);\n\tint nfrags;\n\tint ret = 0;\n\n\tif (!pskb_may_pull(skb, sizeof(*esph))) {\n\t\tret = -EINVAL;\n\t\tgoto out;\n\t}\n\n\tif (elen <= 0 || (elen & (blksize-1))) {\n\t\tret = -EINVAL;\n\t\tgoto out;\n\t}\n\n\t/* If integrity check is required, do this. */\n\tif (esp->auth.icv_full_len) {\n\t\tu8 sum[alen];\n\n\t\tret = esp_mac_digest(esp, skb, 0, skb->len - alen);\n\t\tif (ret)\n\t\t\tgoto out;\n\n\t\tif (skb_copy_bits(skb, skb->len - alen, sum, alen))\n\t\t\tBUG();\n\n\t\tif (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {\n\t\t\tx->stats.integrity_failed++;\n\t\t\tret = -EINVAL;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\tif ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0) {\n\t\tret = -EINVAL;\n\t\tgoto out;\n\t}\n\n\tskb->ip_summed = CHECKSUM_NONE;\n\n\tesph = (struct ip_esp_hdr *)skb->data;\n\tiph = ipv6_hdr(skb);\n\n\t/* Get ivec. This can be wrong, check against another impls. */\n\tif (esp->conf.ivlen)\n\t\tcrypto_blkcipher_set_iv(tfm, esph->enc_data, esp->conf.ivlen);\n\n\t{\n\t\tu8 nexthdr[2];\n\t\tstruct scatterlist *sg = &esp->sgbuf[0];\n\t\tu8 padlen;\n\n\t\tif (unlikely(nfrags > ESP_NUM_FAST_SG)) {\n\t\t\tsg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);\n\t\t\tif (!sg) {\n\t\t\t\tret = -ENOMEM;\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t}\n\t\tsg_init_table(sg, nfrags);\n\t\tskb_to_sgvec(skb, sg,\n\t\t\t     sizeof(*esph) + esp->conf.ivlen,\n\t\t\t     elen);\n\t\tret = crypto_blkcipher_decrypt(&desc, sg, sg, elen);\n\t\tif (unlikely(sg != &esp->sgbuf[0]))\n\t\t\tkfree(sg);\n\t\tif (unlikely(ret))\n\t\t\tgoto out;\n\n\t\tif (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))\n\t\t\tBUG();\n\n\t\tpadlen = nexthdr[0];\n\t\tif (padlen+2 >= elen) {\n\t\t\tLIMIT_NETDEBUG(KERN_WARNING \"ipsec esp packet is garbage padlen=%d, elen=%d\\n\", padlen+2, elen);\n\t\t\tret = -EINVAL;\n\t\t\tgoto out;\n\t\t}\n\t\t/* ... check padding bits here. Silly. :-) */\n\n\t\t/* RFC4303: Drop dummy packets without any error */\n\t\tif (nexthdr[1] == IPPROTO_NONE) {\n\t\t\tret = -EINVAL;\n\t\t\tgoto out;\n\t\t}\n\n\t\tpskb_trim(skb, skb->len - alen - padlen - 2);\n\t\tret = nexthdr[1];\n\t}\n\n\t__skb_pull(skb, sizeof(*esph) + esp->conf.ivlen);\n\tskb_set_transport_header(skb, -hdr_len);\nout:\n\treturn ret;\n}\n\nstatic u32 esp6_get_mtu(struct xfrm_state *x, int mtu)\n{\n\tstruct esp_data *esp = x->data;\n\tu32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);\n\tu32 align = max_t(u32, blksize, esp->conf.padlen);\n\tu32 rem;\n\n\tmtu -= x->props.header_len + esp->auth.icv_trunc_len;\n\trem = mtu & (align - 1);\n\tmtu &= ~(align - 1);\n\n\tif (x->props.mode != XFRM_MODE_TUNNEL) {\n\t\tu32 padsize = ((blksize - 1) & 7) + 1;\n\t\tmtu -= blksize - padsize;\n\t\tmtu += min_t(u32, blksize - padsize, rem);\n\t}\n\n\treturn mtu - 2;\n}\n\nstatic void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,\n\t\t     int type, int code, int offset, __be32 info)\n{\n\tstruct ipv6hdr *iph = (struct ipv6hdr*)skb->data;\n\tstruct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset);\n\tstruct xfrm_state *x;\n\n\tif (type != ICMPV6_DEST_UNREACH &&\n\t    type != ICMPV6_PKT_TOOBIG)\n\t\treturn;\n\n\tx = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6);\n\tif (!x)\n\t\treturn;\n\tprintk(KERN_DEBUG \"pmtu discovery on SA ESP/%08x/\" NIP6_FMT \"\\n\",\n\t\t\tntohl(esph->spi), NIP6(iph->daddr));\n\txfrm_state_put(x);\n}\n\nstatic void esp6_destroy(struct xfrm_state *x)\n{\n\tstruct esp_data *esp = x->data;\n\n\tif (!esp)\n\t\treturn;\n\n\tcrypto_free_blkcipher(esp->conf.tfm);\n\tesp->conf.tfm = NULL;\n\tkfree(esp->conf.ivec);\n\tesp->conf.ivec = NULL;\n\tcrypto_free_hash(esp->auth.tfm);\n\tesp->auth.tfm = NULL;\n\tkfree(esp->auth.work_icv);\n\tesp->auth.work_icv = NULL;\n\tkfree(esp);\n}\n\nstatic int esp6_init_state(struct xfrm_state *x)\n{\n\tstruct esp_data *esp = NULL;\n\tstruct crypto_blkcipher *tfm;\n\n\tif (x->ealg == NULL)\n\t\tgoto error;\n\n\tif (x->encap)\n\t\tgoto error;\n\n\tesp = kzalloc(sizeof(*esp), GFP_KERNEL);\n\tif (esp == NULL)\n\t\treturn -ENOMEM;\n\n\tif (x->aalg) {\n\t\tstruct xfrm_algo_desc *aalg_desc;\n\t\tstruct crypto_hash *hash;\n\n\t\thash = crypto_alloc_hash(x->aalg->alg_name, 0,\n\t\t\t\t\t CRYPTO_ALG_ASYNC);\n\t\tif (IS_ERR(hash))\n\t\t\tgoto error;\n\n\t\tesp->auth.tfm = hash;\n\t\tif (crypto_hash_setkey(hash, x->aalg->alg_key,\n\t\t\t\t       (x->aalg->alg_key_len + 7) / 8))\n\t\t\tgoto error;\n\n\t\taalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);\n\t\tBUG_ON(!aalg_desc);\n\n\t\tif (aalg_desc->uinfo.auth.icv_fullbits/8 !=\n\t\t    crypto_hash_digestsize(hash)) {\n\t\t\tNETDEBUG(KERN_INFO \"ESP: %s digestsize %u != %hu\\n\",\n\t\t\t\t x->aalg->alg_name,\n\t\t\t\t crypto_hash_digestsize(hash),\n\t\t\t\t aalg_desc->uinfo.auth.icv_fullbits/8);\n\t\t\tgoto error;\n\t\t}\n\n\t\tesp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;\n\t\tesp->auth.icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8;\n\n\t\tesp->auth.work_icv = kmalloc(esp->auth.icv_full_len, GFP_KERNEL);\n\t\tif (!esp->auth.work_icv)\n\t\t\tgoto error;\n\t}\n\ttfm = crypto_alloc_blkcipher(x->ealg->alg_name, 0, CRYPTO_ALG_ASYNC);\n\tif (IS_ERR(tfm))\n\t\tgoto error;\n\tesp->conf.tfm = tfm;\n\tesp->conf.ivlen = crypto_blkcipher_ivsize(tfm);\n\tesp->conf.padlen = 0;\n\tif (esp->conf.ivlen) {\n\t\tesp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL);\n\t\tif (unlikely(esp->conf.ivec == NULL))\n\t\t\tgoto error;\n\t\tesp->conf.ivinitted = 0;\n\t}\n\tif (crypto_blkcipher_setkey(tfm, x->ealg->alg_key,\n\t\t\t\t    (x->ealg->alg_key_len + 7) / 8))\n\t\tgoto error;\n\tx->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;\n\tswitch (x->props.mode) {\n\tcase XFRM_MODE_BEET:\n\tcase XFRM_MODE_TRANSPORT:\n\t\tbreak;\n\tcase XFRM_MODE_TUNNEL:\n\t\tx->props.header_len += sizeof(struct ipv6hdr);\n\t\tbreak;\n\tdefault:\n\t\tgoto error;\n\t}\n\tx->data = esp;\n\treturn 0;\n\nerror:\n\tx->data = esp;\n\tesp6_destroy(x);\n\tx->data = NULL;\n\treturn -EINVAL;\n}\n\nstatic struct xfrm_type esp6_type =\n{\n\t.description\t= \"ESP6\",\n\t.owner\t     \t= THIS_MODULE,\n\t.proto\t     \t= IPPROTO_ESP,\n\t.flags\t\t= XFRM_TYPE_REPLAY_PROT,\n\t.init_state\t= esp6_init_state,\n\t.destructor\t= esp6_destroy,\n\t.get_mtu\t= esp6_get_mtu,\n\t.input\t\t= esp6_input,\n\t.output\t\t= esp6_output,\n\t.hdr_offset\t= xfrm6_find_1stfragopt,\n};\n\nstatic struct inet6_protocol esp6_protocol = {\n\t.handler \t=\txfrm6_rcv,\n\t.err_handler\t=\tesp6_err,\n\t.flags\t\t=\tINET6_PROTO_NOPOLICY,\n};\n\nstatic int __init esp6_init(void)\n{\n\tif (xfrm_register_type(&esp6_type, AF_INET6) < 0) {\n\t\tprintk(KERN_INFO \"ipv6 esp init: can't add xfrm type\\n\");\n\t\treturn -EAGAIN;\n\t}\n\tif (inet6_add_protocol(&esp6_protocol, IPPROTO_ESP) < 0) {\n\t\tprintk(KERN_INFO \"ipv6 esp init: can't add protocol\\n\");\n\t\txfrm_unregister_type(&esp6_type, AF_INET6);\n\t\treturn -EAGAIN;\n\t}\n\n\treturn 0;\n}\n\nstatic void __exit esp6_fini(void)\n{\n\tif (inet6_del_protocol(&esp6_protocol, IPPROTO_ESP) < 0)\n\t\tprintk(KERN_INFO \"ipv6 esp close: can't remove protocol\\n\");\n\tif (xfrm_unregister_type(&esp6_type, AF_INET6) < 0)\n\t\tprintk(KERN_INFO \"ipv6 esp close: can't remove xfrm type\\n\");\n}\n\nmodule_init(esp6_init);\nmodule_exit(esp6_fini);\n\nMODULE_LICENSE(\"GPL\");\nMODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_ESP);\n\n\ndiff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c\nindex 4440532..096974b 100644\n--- a/esp6.c\n+++ b/esp6.c\n@@ -177,8 +177,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)\n \t\t\tBUG();\n \n \t\tif (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {\n-\t\t\tx->stats.integrity_failed++;\n-\t\t\tret = -EINVAL;\n+\t\t\tret = -EBADMSG;\n \t\t\tgoto out;\n \t\t}\n \t}\n"},{"id":"63364","messageId":"7vsl22glkk.fsf@gitster.siamese.dyndns.org","threadId":"11315","inReplyTo":"20071216.155413.165709543.davem@davemloft.net","subject":"Re: end of file newline regression","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-12-17T01:24:27Z","receivedAt":"2007-12-17T01:24:27Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"David Miller <davem@davemloft.net> writes:\n\n> I've stumbled into a problem with current mainline.\n>\n> I have this changeset that I can't get GIT to properly\n> generate diffs for.  It always give me:\n>\n> diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c\n> index 4440532..096974b 100644\n> --- a/net/ipv6/esp6.c\n> +++ b/net/ipv6/esp6.c\n> @@ -177,5 +177,4 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)\n>  \t\t\tBUG();\n>  \n>  \t\tif (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {\n> -\t\t\tx->stats.integrity_failed++;\n> -\t\t\tret = -EINVAL;\n> \\ No newline at end of file\n> +\t\t\tret = -EBADMSG;\n> \\ No newline at end of file\n>\n> No matter what I do, 1.5.3.7 doesn't do this.\n\nSorry, there was a recent brown-paper-bag.  Should have been fixed with\nthe patches flew on the list for the past 24 hours or so.  Could you try\nit with the tip of 'master'?\n"}]}