mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	ipc/msg.c: consolidate all xxxctl_down() functions
A use of uninitialized memory in msgctl_down() because msqid64 in ksys_msgctl hasn't been initialized. The local | msqid64 | is created in ksys_msgctl() and then passed into msgctl_down(). Along the way msqid64 is never initialized before msgctl_down() checks msqid64->msg_qbytes. KUMSAN(KernelUninitializedMemorySantizer, a new error detection tool) reports: ================================================================== BUG: KUMSAN: use of uninitialized memory in msgctl_down+0x94/0x300 Read of size 8 at addr ffff88806bb97eb8 by task syz-executor707/2022 CPU: 0 PID: 2022 Comm: syz-executor707 Not tainted 5.2.0-rc4+ #63 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 Call Trace: dump_stack+0x75/0xae __kumsan_report+0x17c/0x3e6 kumsan_report+0xe/0x20 msgctl_down+0x94/0x300 ksys_msgctl.constprop.14+0xef/0x260 do_syscall_64+0x7e/0x1f0 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x4400e9 Code: 18 89 d0 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 fb 13 fc ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:00007ffd869e0598 EFLAGS: 00000246 ORIG_RAX: 0000000000000047 RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 00000000004400e9 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 00000000006ca018 R08: 0000000000000000 R09: 0000000000000000 R10: 00000000ffffffff R11: 0000000000000246 R12: 0000000000401970 R13: 0000000000401a00 R14: 0000000000000000 R15: 0000000000000000 The buggy address belongs to the page: page:ffffea0001aee5c0 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 flags: 0x100000000000000() raw: 0100000000000000 0000000000000000 ffffffff01ae0101 0000000000000000 raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kumsan: bad access detected ================================================================== Syzkaller reproducer: msgctl$IPC_RMID(0x0, 0x0) C reproducer: // autogenerated by syzkaller (https://github.com/google/syzkaller) int main(void) { syscall(__NR_mmap, 0x20000000, 0x1000000, 3, 0x32, -1, 0); syscall(__NR_msgctl, 0, 0, 0); return 0; } [natechancellor@gmail.com: adjust indentation in ksys_msgctl] Link: https://github.com/ClangBuiltLinux/linux/issues/829 Link: http://lkml.kernel.org/r/20191218032932.37479-1-natechancellor@gmail.com Link: http://lkml.kernel.org/r/20190613014044.24234-1-shuaibinglu@126.com Signed-off-by: Lu Shuaibing <shuaibinglu@126.com> Signed-off-by: Nathan Chancellor <natechancellor@gmail.com> Suggested-by: Arnd Bergmann <arnd@arndb.de> Cc: Davidlohr Bueso <dave@stgolabs.net> Cc: Manfred Spraul <manfred@colorfullife.com> Cc: NeilBrown <neilb@suse.com> From: Andrew Morton <akpm@linux-foundation.org> Subject: drivers/block/null_blk_main.c: fix layout Each line here overflows 80 cols by exactly one character. Delete one tab per line to fix. Cc: Shaohua Li <shli@fb.com> Cc: Jens Axboe <axboe@kernel.dk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									8116b54e7e
								
							
						
					
					
						commit
						889b331724
					
				
					 1 changed files with 10 additions and 9 deletions
				
			
		
							
								
								
									
										19
									
								
								ipc/msg.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								ipc/msg.c
									
									
									
									
									
								
							| 
						 | 
					@ -394,7 +394,7 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version)
 | 
				
			||||||
 * NOTE: no locks must be held, the rwsem is taken inside this function.
 | 
					 * NOTE: no locks must be held, the rwsem is taken inside this function.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
 | 
					static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
 | 
				
			||||||
			struct msqid64_ds *msqid64)
 | 
								struct ipc64_perm *perm, int msg_qbytes)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct kern_ipc_perm *ipcp;
 | 
						struct kern_ipc_perm *ipcp;
 | 
				
			||||||
	struct msg_queue *msq;
 | 
						struct msg_queue *msq;
 | 
				
			||||||
| 
						 | 
					@ -404,7 +404,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
 | 
				
			||||||
	rcu_read_lock();
 | 
						rcu_read_lock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ipcp = ipcctl_obtain_check(ns, &msg_ids(ns), msqid, cmd,
 | 
						ipcp = ipcctl_obtain_check(ns, &msg_ids(ns), msqid, cmd,
 | 
				
			||||||
				      &msqid64->msg_perm, msqid64->msg_qbytes);
 | 
									      perm, msg_qbytes);
 | 
				
			||||||
	if (IS_ERR(ipcp)) {
 | 
						if (IS_ERR(ipcp)) {
 | 
				
			||||||
		err = PTR_ERR(ipcp);
 | 
							err = PTR_ERR(ipcp);
 | 
				
			||||||
		goto out_unlock1;
 | 
							goto out_unlock1;
 | 
				
			||||||
| 
						 | 
					@ -426,18 +426,18 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		DEFINE_WAKE_Q(wake_q);
 | 
							DEFINE_WAKE_Q(wake_q);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (msqid64->msg_qbytes > ns->msg_ctlmnb &&
 | 
							if (msg_qbytes > ns->msg_ctlmnb &&
 | 
				
			||||||
		    !capable(CAP_SYS_RESOURCE)) {
 | 
							    !capable(CAP_SYS_RESOURCE)) {
 | 
				
			||||||
			err = -EPERM;
 | 
								err = -EPERM;
 | 
				
			||||||
			goto out_unlock1;
 | 
								goto out_unlock1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ipc_lock_object(&msq->q_perm);
 | 
							ipc_lock_object(&msq->q_perm);
 | 
				
			||||||
		err = ipc_update_perm(&msqid64->msg_perm, ipcp);
 | 
							err = ipc_update_perm(perm, ipcp);
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
			goto out_unlock0;
 | 
								goto out_unlock0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		msq->q_qbytes = msqid64->msg_qbytes;
 | 
							msq->q_qbytes = msg_qbytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		msq->q_ctime = ktime_get_real_seconds();
 | 
							msq->q_ctime = ktime_get_real_seconds();
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
| 
						 | 
					@ -618,9 +618,10 @@ static long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf, int ver
 | 
				
			||||||
	case IPC_SET:
 | 
						case IPC_SET:
 | 
				
			||||||
		if (copy_msqid_from_user(&msqid64, buf, version))
 | 
							if (copy_msqid_from_user(&msqid64, buf, version))
 | 
				
			||||||
			return -EFAULT;
 | 
								return -EFAULT;
 | 
				
			||||||
		/* fallthru */
 | 
							return msgctl_down(ns, msqid, cmd, &msqid64.msg_perm,
 | 
				
			||||||
 | 
									   msqid64.msg_qbytes);
 | 
				
			||||||
	case IPC_RMID:
 | 
						case IPC_RMID:
 | 
				
			||||||
		return msgctl_down(ns, msqid, cmd, &msqid64);
 | 
							return msgctl_down(ns, msqid, cmd, NULL, 0);
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return  -EINVAL;
 | 
							return  -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -752,9 +753,9 @@ static long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr, int versio
 | 
				
			||||||
	case IPC_SET:
 | 
						case IPC_SET:
 | 
				
			||||||
		if (copy_compat_msqid_from_user(&msqid64, uptr, version))
 | 
							if (copy_compat_msqid_from_user(&msqid64, uptr, version))
 | 
				
			||||||
			return -EFAULT;
 | 
								return -EFAULT;
 | 
				
			||||||
		/* fallthru */
 | 
							return msgctl_down(ns, msqid, cmd, &msqid64.msg_perm, msqid64.msg_qbytes);
 | 
				
			||||||
	case IPC_RMID:
 | 
						case IPC_RMID:
 | 
				
			||||||
		return msgctl_down(ns, msqid, cmd, &msqid64);
 | 
							return msgctl_down(ns, msqid, cmd, NULL, 0);
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue