lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Sat, 18 Aug 2007 21:39:50 +0400 From: Oleg Nesterov <oleg@...sign.ru> To: Andrew Morton <akpm@...ux-foundation.org> Cc: Roland McGrath <roland@...hat.com>, linux-kernel@...r.kernel.org Subject: [PATCH 3/5] exec: simplify the new ->sighand allocation de_thread() pre-allocates newsighand to make sure that exec() can't fail after killing all sub-threads. Imho, this buys nothing, but complicates the code: - this is (mostly) needed to handle CLONE_SIGHAND without CLONE_THREAD tasks, this is very unlikely (if ever used) case - unless we already have some serious problems, GFP_KERNEL allocation should not fail - ENOMEM still can happen after de_thread(), ->sighand is not the last object we have to allocate Change the code to allocate the new ->sighand on demand. Signed-off-by: Oleg Nesterov <oleg@...sign.ru> --- t/fs/exec.c~3_ALLOC 2007-08-18 18:26:48.000000000 +0400 +++ t/fs/exec.c 2007-08-18 19:10:58.000000000 +0400 @@ -774,7 +774,7 @@ static int exec_mmap(struct mm_struct *m static int de_thread(struct task_struct *tsk) { struct signal_struct *sig = tsk->signal; - struct sighand_struct *newsighand, *oldsighand = tsk->sighand; + struct sighand_struct *oldsighand = tsk->sighand; spinlock_t *lock = &oldsighand->siglock; struct task_struct *leader = NULL; int count; @@ -789,10 +789,6 @@ static int de_thread(struct task_struct return 0; } - newsighand = kmem_cache_alloc(sighand_cachep, GFP_KERNEL); - if (!newsighand) - return -ENOMEM; - if (thread_group_empty(tsk)) goto no_thread_group; @@ -809,7 +805,6 @@ static int de_thread(struct task_struct */ spin_unlock_irq(lock); read_unlock(&tasklist_lock); - kmem_cache_free(sighand_cachep, newsighand); return -EAGAIN; } @@ -928,17 +923,16 @@ no_thread_group: if (leader) release_task(leader); - if (atomic_read(&oldsighand->count) == 1) { - /* - * Now that we nuked the rest of the thread group, - * it turns out we are not sharing sighand any more either. - * So we can just keep it. - */ - kmem_cache_free(sighand_cachep, newsighand); - } else { + if (atomic_read(&oldsighand->count) != 1) { + struct sighand_struct *newsighand; /* - * Move our state over to newsighand and switch it in. + * This ->sighand is shared with the CLONE_SIGHAND + * but not CLONE_THREAD task, switch to the new one. */ + newsighand = kmem_cache_alloc(sighand_cachep, GFP_KERNEL); + if (!newsighand) + return -ENOMEM; + atomic_set(&newsighand->count, 1); memcpy(newsighand->action, oldsighand->action, sizeof(newsighand->action)); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists