qmemman: prefix variables read from xenstore with "untrusted_"
Additionally move all already existing checks to an already existing is_meminfo_suspicious procedure.
This commit is contained in:
		
							parent
							
								
									d84289f983
								
							
						
					
					
						commit
						18e207cbc5
					
				@ -96,8 +96,8 @@ class SystemState:
 | 
			
		||||
            time.sleep(self.BALOON_DELAY)
 | 
			
		||||
            niter = niter + 1
 | 
			
		||||
            
 | 
			
		||||
    def refresh_meminfo(self, domid, val):
 | 
			
		||||
        qmemman_algo.refresh_meminfo_for_domain(self.domdict[domid], val)
 | 
			
		||||
    def refresh_meminfo(self, domid, untrusted_meminfo_key):
 | 
			
		||||
        qmemman_algo.refresh_meminfo_for_domain(self.domdict[domid], untrusted_meminfo_key)
 | 
			
		||||
        self.do_balance()
 | 
			
		||||
 | 
			
		||||
    def is_balance_req_significant(self, memset_reqs, xenfree):
 | 
			
		||||
 | 
			
		||||
@ -1,45 +1,58 @@
 | 
			
		||||
import string
 | 
			
		||||
 | 
			
		||||
def parse_meminfo(meminfo):
 | 
			
		||||
    dict = {}
 | 
			
		||||
    l1 = string.split(meminfo,"\n")
 | 
			
		||||
    for i in l1:
 | 
			
		||||
        l2 = string.split(i)
 | 
			
		||||
        if len(l2) >= 2:
 | 
			
		||||
            dict[string.rstrip(l2[0], ":")] = l2[1]
 | 
			
		||||
#untrusted meminfo size is taken from xenstore key, thus its size is limited
 | 
			
		||||
#so splits do not require excessive memory
 | 
			
		||||
def parse_meminfo(untrusted_meminfo):
 | 
			
		||||
    untrusted_dict = {}
 | 
			
		||||
#split meminfo contents into lines
 | 
			
		||||
    untrusted_lines = string.split(untrusted_meminfo,"\n")
 | 
			
		||||
    for untrusted_lines_iterator in untrusted_lines:
 | 
			
		||||
#split a single meminfo line into words
 | 
			
		||||
        untrusted_words = string.split(untrusted_lines_iterator)
 | 
			
		||||
        if len(untrusted_words) >= 2:
 | 
			
		||||
            untrusted_dict[string.rstrip(untrusted_words[0], ":")] = untrusted_words[1]
 | 
			
		||||
 | 
			
		||||
    return untrusted_dict
 | 
			
		||||
 | 
			
		||||
def is_meminfo_suspicious(dom, untrusted_meminfo):
 | 
			
		||||
    ret = False
 | 
			
		||||
    
 | 
			
		||||
#check whether the required keys exist and are not negative
 | 
			
		||||
    try:
 | 
			
		||||
        for i in ('MemTotal', 'MemFree', 'Buffers', 'Cached', 'SwapTotal', 'SwapFree'):
 | 
			
		||||
            val = int(dict[i])*1024
 | 
			
		||||
            val = int(untrusted_meminfo[i])*1024
 | 
			
		||||
            if (val < 0):
 | 
			
		||||
                return None
 | 
			
		||||
            dict[i] = val
 | 
			
		||||
                ret = True
 | 
			
		||||
            untrusted_meminfo[i] = val
 | 
			
		||||
    except:
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    if dict['SwapTotal'] < dict['SwapFree']:
 | 
			
		||||
        return None
 | 
			
		||||
    return dict
 | 
			
		||||
 | 
			
		||||
def is_suspicious(dom):
 | 
			
		||||
    ret = False
 | 
			
		||||
    if dom.meminfo['SwapTotal'] < dom.meminfo['SwapFree']:
 | 
			
		||||
        ret = True
 | 
			
		||||
    if dom.meminfo['MemTotal'] < dom.meminfo['MemFree'] + dom.meminfo['Cached'] + dom.meminfo['Buffers']:
 | 
			
		||||
 | 
			
		||||
    if not ret and untrusted_meminfo['SwapTotal'] < untrusted_meminfo['SwapFree']:
 | 
			
		||||
        ret = True
 | 
			
		||||
    if not ret and untrusted_meminfo['MemTotal'] < untrusted_meminfo['MemFree'] + untrusted_meminfo['Cached'] + untrusted_meminfo['Buffers']:
 | 
			
		||||
        ret = True
 | 
			
		||||
#we could also impose some limits on all the above values
 | 
			
		||||
#but it has little purpose - all the domain can gain by passing e.g. 
 | 
			
		||||
#very large SwapTotal is that it will be assigned all free Xen memory
 | 
			
		||||
#it can be achieved with legal values, too, and it will not allow to
 | 
			
		||||
#starve existing domains, by design
 | 
			
		||||
    if ret:
 | 
			
		||||
        print 'suspicious meminfo for domain', dom.id, 'mem actual', dom.memory_actual, dom.meminfo
 | 
			
		||||
        print 'suspicious meminfo for domain', dom.id, 'mem actual', dom.memory_actual, untrusted_meminfo
 | 
			
		||||
    return ret
 | 
			
		||||
 | 
			
		||||
def refresh_meminfo_for_domain(dom, xenstore_key):
 | 
			
		||||
    meminfo = parse_meminfo(xenstore_key)
 | 
			
		||||
    dom.meminfo = meminfo
 | 
			
		||||
    if meminfo is None:
 | 
			
		||||
def refresh_meminfo_for_domain(dom, untrusted_xenstore_key):
 | 
			
		||||
    untrusted_meminfo = parse_meminfo(untrusted_xenstore_key)
 | 
			
		||||
    if untrusted_meminfo is None:
 | 
			
		||||
        dom.meminfo = None
 | 
			
		||||
        return
 | 
			
		||||
    if is_suspicious(dom):
 | 
			
		||||
#sanitize start
 | 
			
		||||
    if is_meminfo_suspicious(dom, untrusted_meminfo):
 | 
			
		||||
#sanitize end
 | 
			
		||||
        dom.meminfo = None
 | 
			
		||||
        dom.mem_used = None
 | 
			
		||||
    else:
 | 
			
		||||
#sanitized, can assign
 | 
			
		||||
        dom.meminfo = untrusted_meminfo
 | 
			
		||||
        dom.mem_used =  dom.meminfo['MemTotal'] - dom.meminfo['MemFree'] - dom.meminfo['Cached'] - dom.meminfo['Buffers'] + dom.meminfo['SwapTotal'] - dom.meminfo['SwapFree']
 | 
			
		||||
                        
 | 
			
		||||
def prefmem(dom):
 | 
			
		||||
 | 
			
		||||
@ -49,11 +49,11 @@ class XS_Watcher:
 | 
			
		||||
        global_lock.release()
 | 
			
		||||
 | 
			
		||||
    def request(self, domain_id):
 | 
			
		||||
        ret = self.handle.read('', get_req_node(domain_id))
 | 
			
		||||
        if ret == None or ret == '':
 | 
			
		||||
        untrusted_meminfo_key = self.handle.read('', get_req_node(domain_id))
 | 
			
		||||
        if untrusted_meminfo_key == None or untrusted_meminfo_key == '':
 | 
			
		||||
            return
 | 
			
		||||
        global_lock.acquire()
 | 
			
		||||
        system_state.refresh_meminfo(domain_id, ret)
 | 
			
		||||
        system_state.refresh_meminfo(domain_id, untrusted_meminfo_key)
 | 
			
		||||
        global_lock.release()
 | 
			
		||||
 | 
			
		||||
    def watch_loop(self):
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user