• P
    ipc/sem.c: avoid overflow of semop undo (semadj) value · 78f5009c
    Petr Mladek 提交于
    When trying to understand semop code, I found a small mistake in the check
    for semadj (undo) value overflow.  The new undo value is not stored
    immediately and next potential checks are done against the old value.
    
    The failing scenario is not much practical.  One semop call has to do more
    operations on the same semaphore.  Also semval and semadj must have
    different values, so there has to be some operations without SEM_UNDO
    flag.  For example:
    
    	struct sembuf depositor_op[1];
    	struct sembuf collector_op[2];
    
    	depositor_op[0].sem_num = 0;
    	depositor_op[0].sem_op = 20000;
    	depositor_op[0].sem_flg = 0;
    
    	collector_op[0].sem_num = 0;
    	collector_op[0].sem_op = -10000;
    	collector_op[0].sem_flg = SEM_UNDO;
    	collector_op[1].sem_num = 0;
    	collector_op[1].sem_op = -10000;
    	collector_op[1].sem_flg = SEM_UNDO;
    
    	if (semop(semid, depositor_op, 1) == -1)
    		{ perror("Failed to do 1st deposit"); return 1; }
    
    	if (semop(semid, collector_op, 2) == -1)
    		{ perror("Failed to do 1st collect"); return 1; }
    
    	if (semop(semid, depositor_op, 1) == -1)
    		{ perror("Failed to do 2nd deposit"); return 1; }
    
    	if (semop(semid, collector_op, 2) == -1)
    		{ perror("Failed to do 2nd collect"); return 1; }
    
    	return 0;
    
    It passes without error now but the semadj value has overflown in the 2nd
    collector operation.
    
    [akpm@linux-foundation.org: restore lessened scope of local `undo']
    [davidlohr@hp.com: correct header comment for perform_atomic_semop]
    Signed-off-by: NPetr Mladek <pmladek@suse.cz>
    Acked-by: NDavidlohr Bueso <davidlohr@hp.com>
    Acked-by: NManfred Spraul <manfred@colorfullife.com>
    Cc: Jiri Kosina <jkosina@suse.cz>
    Signed-off-by: NDavidlohr Bueso <davidlohr@hp.com>
    Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
    78f5009c
sem.c 54.5 KB