ia64/linux-2.6.18-xen.hg

annotate kernel/sys.c @ 562:66faefe721eb

pvSCSI backend driver

Signed-off-by: Tomonari Horikoshi <t.horikoshi@jp.fujitsu.com>
Signed-off-by: Jun Kamada <kama@jp.fujitsu.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Jun 02 09:58:27 2008 +0100 (2008-06-02)
parents 831230e53067
children
rev   line source
ian@0 1 /*
ian@0 2 * linux/kernel/sys.c
ian@0 3 *
ian@0 4 * Copyright (C) 1991, 1992 Linus Torvalds
ian@0 5 */
ian@0 6
ian@0 7 #include <linux/module.h>
ian@0 8 #include <linux/mm.h>
ian@0 9 #include <linux/utsname.h>
ian@0 10 #include <linux/mman.h>
ian@0 11 #include <linux/smp_lock.h>
ian@0 12 #include <linux/notifier.h>
ian@0 13 #include <linux/reboot.h>
ian@0 14 #include <linux/prctl.h>
ian@0 15 #include <linux/highuid.h>
ian@0 16 #include <linux/fs.h>
ian@0 17 #include <linux/kernel.h>
ian@0 18 #include <linux/kexec.h>
ian@0 19 #include <linux/workqueue.h>
ian@0 20 #include <linux/capability.h>
ian@0 21 #include <linux/device.h>
ian@0 22 #include <linux/key.h>
ian@0 23 #include <linux/times.h>
ian@0 24 #include <linux/posix-timers.h>
ian@0 25 #include <linux/security.h>
ian@0 26 #include <linux/dcookies.h>
ian@0 27 #include <linux/suspend.h>
ian@0 28 #include <linux/tty.h>
ian@0 29 #include <linux/signal.h>
ian@0 30 #include <linux/cn_proc.h>
ian@0 31
ian@0 32 #include <linux/compat.h>
ian@0 33 #include <linux/syscalls.h>
ian@0 34 #include <linux/kprobes.h>
ian@0 35
ian@0 36 #include <asm/uaccess.h>
ian@0 37 #include <asm/io.h>
ian@0 38 #include <asm/unistd.h>
ian@0 39
ian@0 40 #ifndef SET_UNALIGN_CTL
ian@0 41 # define SET_UNALIGN_CTL(a,b) (-EINVAL)
ian@0 42 #endif
ian@0 43 #ifndef GET_UNALIGN_CTL
ian@0 44 # define GET_UNALIGN_CTL(a,b) (-EINVAL)
ian@0 45 #endif
ian@0 46 #ifndef SET_FPEMU_CTL
ian@0 47 # define SET_FPEMU_CTL(a,b) (-EINVAL)
ian@0 48 #endif
ian@0 49 #ifndef GET_FPEMU_CTL
ian@0 50 # define GET_FPEMU_CTL(a,b) (-EINVAL)
ian@0 51 #endif
ian@0 52 #ifndef SET_FPEXC_CTL
ian@0 53 # define SET_FPEXC_CTL(a,b) (-EINVAL)
ian@0 54 #endif
ian@0 55 #ifndef GET_FPEXC_CTL
ian@0 56 # define GET_FPEXC_CTL(a,b) (-EINVAL)
ian@0 57 #endif
ian@0 58 #ifndef GET_ENDIAN
ian@0 59 # define GET_ENDIAN(a,b) (-EINVAL)
ian@0 60 #endif
ian@0 61 #ifndef SET_ENDIAN
ian@0 62 # define SET_ENDIAN(a,b) (-EINVAL)
ian@0 63 #endif
ian@0 64
ian@0 65 /*
ian@0 66 * this is where the system-wide overflow UID and GID are defined, for
ian@0 67 * architectures that now have 32-bit UID/GID but didn't in the past
ian@0 68 */
ian@0 69
ian@0 70 int overflowuid = DEFAULT_OVERFLOWUID;
ian@0 71 int overflowgid = DEFAULT_OVERFLOWGID;
ian@0 72
ian@0 73 #ifdef CONFIG_UID16
ian@0 74 EXPORT_SYMBOL(overflowuid);
ian@0 75 EXPORT_SYMBOL(overflowgid);
ian@0 76 #endif
ian@0 77
ian@0 78 /*
ian@0 79 * the same as above, but for filesystems which can only store a 16-bit
ian@0 80 * UID and GID. as such, this is needed on all architectures
ian@0 81 */
ian@0 82
ian@0 83 int fs_overflowuid = DEFAULT_FS_OVERFLOWUID;
ian@0 84 int fs_overflowgid = DEFAULT_FS_OVERFLOWUID;
ian@0 85
ian@0 86 EXPORT_SYMBOL(fs_overflowuid);
ian@0 87 EXPORT_SYMBOL(fs_overflowgid);
ian@0 88
ian@0 89 /*
ian@0 90 * this indicates whether you can reboot with ctrl-alt-del: the default is yes
ian@0 91 */
ian@0 92
ian@0 93 int C_A_D = 1;
ian@0 94 int cad_pid = 1;
ian@0 95
ian@0 96 /*
ian@0 97 * Notifier list for kernel code which wants to be called
ian@0 98 * at shutdown. This is used to stop any idling DMA operations
ian@0 99 * and the like.
ian@0 100 */
ian@0 101
ian@0 102 static BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
ian@0 103
ian@0 104 /*
ian@0 105 * Notifier chain core routines. The exported routines below
ian@0 106 * are layered on top of these, with appropriate locking added.
ian@0 107 */
ian@0 108
ian@0 109 static int notifier_chain_register(struct notifier_block **nl,
ian@0 110 struct notifier_block *n)
ian@0 111 {
ian@0 112 while ((*nl) != NULL) {
ian@0 113 if (n->priority > (*nl)->priority)
ian@0 114 break;
ian@0 115 nl = &((*nl)->next);
ian@0 116 }
ian@0 117 n->next = *nl;
ian@0 118 rcu_assign_pointer(*nl, n);
ian@0 119 return 0;
ian@0 120 }
ian@0 121
ian@0 122 static int notifier_chain_unregister(struct notifier_block **nl,
ian@0 123 struct notifier_block *n)
ian@0 124 {
ian@0 125 while ((*nl) != NULL) {
ian@0 126 if ((*nl) == n) {
ian@0 127 rcu_assign_pointer(*nl, n->next);
ian@0 128 return 0;
ian@0 129 }
ian@0 130 nl = &((*nl)->next);
ian@0 131 }
ian@0 132 return -ENOENT;
ian@0 133 }
ian@0 134
ian@0 135 static int __kprobes notifier_call_chain(struct notifier_block **nl,
ian@0 136 unsigned long val, void *v)
ian@0 137 {
ian@0 138 int ret = NOTIFY_DONE;
ian@0 139 struct notifier_block *nb, *next_nb;
ian@0 140
ian@0 141 nb = rcu_dereference(*nl);
ian@0 142 while (nb) {
ian@0 143 next_nb = rcu_dereference(nb->next);
ian@0 144 ret = nb->notifier_call(nb, val, v);
ian@0 145 if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK)
ian@0 146 break;
ian@0 147 nb = next_nb;
ian@0 148 }
ian@0 149 return ret;
ian@0 150 }
ian@0 151
ian@0 152 /*
ian@0 153 * Atomic notifier chain routines. Registration and unregistration
ian@0 154 * use a mutex, and call_chain is synchronized by RCU (no locks).
ian@0 155 */
ian@0 156
ian@0 157 /**
ian@0 158 * atomic_notifier_chain_register - Add notifier to an atomic notifier chain
ian@0 159 * @nh: Pointer to head of the atomic notifier chain
ian@0 160 * @n: New entry in notifier chain
ian@0 161 *
ian@0 162 * Adds a notifier to an atomic notifier chain.
ian@0 163 *
ian@0 164 * Currently always returns zero.
ian@0 165 */
ian@0 166
ian@0 167 int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
ian@0 168 struct notifier_block *n)
ian@0 169 {
ian@0 170 unsigned long flags;
ian@0 171 int ret;
ian@0 172
ian@0 173 spin_lock_irqsave(&nh->lock, flags);
ian@0 174 ret = notifier_chain_register(&nh->head, n);
ian@0 175 spin_unlock_irqrestore(&nh->lock, flags);
ian@0 176 return ret;
ian@0 177 }
ian@0 178
ian@0 179 EXPORT_SYMBOL_GPL(atomic_notifier_chain_register);
ian@0 180
ian@0 181 /**
ian@0 182 * atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain
ian@0 183 * @nh: Pointer to head of the atomic notifier chain
ian@0 184 * @n: Entry to remove from notifier chain
ian@0 185 *
ian@0 186 * Removes a notifier from an atomic notifier chain.
ian@0 187 *
ian@0 188 * Returns zero on success or %-ENOENT on failure.
ian@0 189 */
ian@0 190 int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
ian@0 191 struct notifier_block *n)
ian@0 192 {
ian@0 193 unsigned long flags;
ian@0 194 int ret;
ian@0 195
ian@0 196 spin_lock_irqsave(&nh->lock, flags);
ian@0 197 ret = notifier_chain_unregister(&nh->head, n);
ian@0 198 spin_unlock_irqrestore(&nh->lock, flags);
ian@0 199 synchronize_rcu();
ian@0 200 return ret;
ian@0 201 }
ian@0 202
ian@0 203 EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
ian@0 204
ian@0 205 /**
ian@0 206 * atomic_notifier_call_chain - Call functions in an atomic notifier chain
ian@0 207 * @nh: Pointer to head of the atomic notifier chain
ian@0 208 * @val: Value passed unmodified to notifier function
ian@0 209 * @v: Pointer passed unmodified to notifier function
ian@0 210 *
ian@0 211 * Calls each function in a notifier chain in turn. The functions
ian@0 212 * run in an atomic context, so they must not block.
ian@0 213 * This routine uses RCU to synchronize with changes to the chain.
ian@0 214 *
ian@0 215 * If the return value of the notifier can be and'ed
ian@0 216 * with %NOTIFY_STOP_MASK then atomic_notifier_call_chain
ian@0 217 * will return immediately, with the return value of
ian@0 218 * the notifier function which halted execution.
ian@0 219 * Otherwise the return value is the return value
ian@0 220 * of the last notifier function called.
ian@0 221 */
ian@0 222
ian@0 223 int atomic_notifier_call_chain(struct atomic_notifier_head *nh,
ian@0 224 unsigned long val, void *v)
ian@0 225 {
ian@0 226 int ret;
ian@0 227
ian@0 228 rcu_read_lock();
ian@0 229 ret = notifier_call_chain(&nh->head, val, v);
ian@0 230 rcu_read_unlock();
ian@0 231 return ret;
ian@0 232 }
ian@0 233
ian@0 234 EXPORT_SYMBOL_GPL(atomic_notifier_call_chain);
ian@0 235
ian@0 236 /*
ian@0 237 * Blocking notifier chain routines. All access to the chain is
ian@0 238 * synchronized by an rwsem.
ian@0 239 */
ian@0 240
ian@0 241 /**
ian@0 242 * blocking_notifier_chain_register - Add notifier to a blocking notifier chain
ian@0 243 * @nh: Pointer to head of the blocking notifier chain
ian@0 244 * @n: New entry in notifier chain
ian@0 245 *
ian@0 246 * Adds a notifier to a blocking notifier chain.
ian@0 247 * Must be called in process context.
ian@0 248 *
ian@0 249 * Currently always returns zero.
ian@0 250 */
ian@0 251
ian@0 252 int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
ian@0 253 struct notifier_block *n)
ian@0 254 {
ian@0 255 int ret;
ian@0 256
ian@0 257 /*
ian@0 258 * This code gets used during boot-up, when task switching is
ian@0 259 * not yet working and interrupts must remain disabled. At
ian@0 260 * such times we must not call down_write().
ian@0 261 */
ian@0 262 if (unlikely(system_state == SYSTEM_BOOTING))
ian@0 263 return notifier_chain_register(&nh->head, n);
ian@0 264
ian@0 265 down_write(&nh->rwsem);
ian@0 266 ret = notifier_chain_register(&nh->head, n);
ian@0 267 up_write(&nh->rwsem);
ian@0 268 return ret;
ian@0 269 }
ian@0 270
ian@0 271 EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
ian@0 272
ian@0 273 /**
ian@0 274 * blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
ian@0 275 * @nh: Pointer to head of the blocking notifier chain
ian@0 276 * @n: Entry to remove from notifier chain
ian@0 277 *
ian@0 278 * Removes a notifier from a blocking notifier chain.
ian@0 279 * Must be called from process context.
ian@0 280 *
ian@0 281 * Returns zero on success or %-ENOENT on failure.
ian@0 282 */
ian@0 283 int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
ian@0 284 struct notifier_block *n)
ian@0 285 {
ian@0 286 int ret;
ian@0 287
ian@0 288 /*
ian@0 289 * This code gets used during boot-up, when task switching is
ian@0 290 * not yet working and interrupts must remain disabled. At
ian@0 291 * such times we must not call down_write().
ian@0 292 */
ian@0 293 if (unlikely(system_state == SYSTEM_BOOTING))
ian@0 294 return notifier_chain_unregister(&nh->head, n);
ian@0 295
ian@0 296 down_write(&nh->rwsem);
ian@0 297 ret = notifier_chain_unregister(&nh->head, n);
ian@0 298 up_write(&nh->rwsem);
ian@0 299 return ret;
ian@0 300 }
ian@0 301
ian@0 302 EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister);
ian@0 303
ian@0 304 /**
ian@0 305 * blocking_notifier_call_chain - Call functions in a blocking notifier chain
ian@0 306 * @nh: Pointer to head of the blocking notifier chain
ian@0 307 * @val: Value passed unmodified to notifier function
ian@0 308 * @v: Pointer passed unmodified to notifier function
ian@0 309 *
ian@0 310 * Calls each function in a notifier chain in turn. The functions
ian@0 311 * run in a process context, so they are allowed to block.
ian@0 312 *
ian@0 313 * If the return value of the notifier can be and'ed
ian@0 314 * with %NOTIFY_STOP_MASK then blocking_notifier_call_chain
ian@0 315 * will return immediately, with the return value of
ian@0 316 * the notifier function which halted execution.
ian@0 317 * Otherwise the return value is the return value
ian@0 318 * of the last notifier function called.
ian@0 319 */
ian@0 320
ian@0 321 int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
ian@0 322 unsigned long val, void *v)
ian@0 323 {
ian@0 324 int ret;
ian@0 325
ian@0 326 down_read(&nh->rwsem);
ian@0 327 ret = notifier_call_chain(&nh->head, val, v);
ian@0 328 up_read(&nh->rwsem);
ian@0 329 return ret;
ian@0 330 }
ian@0 331
ian@0 332 EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);
ian@0 333
ian@0 334 /*
ian@0 335 * Raw notifier chain routines. There is no protection;
ian@0 336 * the caller must provide it. Use at your own risk!
ian@0 337 */
ian@0 338
ian@0 339 /**
ian@0 340 * raw_notifier_chain_register - Add notifier to a raw notifier chain
ian@0 341 * @nh: Pointer to head of the raw notifier chain
ian@0 342 * @n: New entry in notifier chain
ian@0 343 *
ian@0 344 * Adds a notifier to a raw notifier chain.
ian@0 345 * All locking must be provided by the caller.
ian@0 346 *
ian@0 347 * Currently always returns zero.
ian@0 348 */
ian@0 349
ian@0 350 int raw_notifier_chain_register(struct raw_notifier_head *nh,
ian@0 351 struct notifier_block *n)
ian@0 352 {
ian@0 353 return notifier_chain_register(&nh->head, n);
ian@0 354 }
ian@0 355
ian@0 356 EXPORT_SYMBOL_GPL(raw_notifier_chain_register);
ian@0 357
ian@0 358 /**
ian@0 359 * raw_notifier_chain_unregister - Remove notifier from a raw notifier chain
ian@0 360 * @nh: Pointer to head of the raw notifier chain
ian@0 361 * @n: Entry to remove from notifier chain
ian@0 362 *
ian@0 363 * Removes a notifier from a raw notifier chain.
ian@0 364 * All locking must be provided by the caller.
ian@0 365 *
ian@0 366 * Returns zero on success or %-ENOENT on failure.
ian@0 367 */
ian@0 368 int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
ian@0 369 struct notifier_block *n)
ian@0 370 {
ian@0 371 return notifier_chain_unregister(&nh->head, n);
ian@0 372 }
ian@0 373
ian@0 374 EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister);
ian@0 375
ian@0 376 /**
ian@0 377 * raw_notifier_call_chain - Call functions in a raw notifier chain
ian@0 378 * @nh: Pointer to head of the raw notifier chain
ian@0 379 * @val: Value passed unmodified to notifier function
ian@0 380 * @v: Pointer passed unmodified to notifier function
ian@0 381 *
ian@0 382 * Calls each function in a notifier chain in turn. The functions
ian@0 383 * run in an undefined context.
ian@0 384 * All locking must be provided by the caller.
ian@0 385 *
ian@0 386 * If the return value of the notifier can be and'ed
ian@0 387 * with %NOTIFY_STOP_MASK then raw_notifier_call_chain
ian@0 388 * will return immediately, with the return value of
ian@0 389 * the notifier function which halted execution.
ian@0 390 * Otherwise the return value is the return value
ian@0 391 * of the last notifier function called.
ian@0 392 */
ian@0 393
ian@0 394 int raw_notifier_call_chain(struct raw_notifier_head *nh,
ian@0 395 unsigned long val, void *v)
ian@0 396 {
ian@0 397 return notifier_call_chain(&nh->head, val, v);
ian@0 398 }
ian@0 399
ian@0 400 EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
ian@0 401
ian@0 402 /**
ian@0 403 * register_reboot_notifier - Register function to be called at reboot time
ian@0 404 * @nb: Info about notifier function to be called
ian@0 405 *
ian@0 406 * Registers a function with the list of functions
ian@0 407 * to be called at reboot time.
ian@0 408 *
ian@0 409 * Currently always returns zero, as blocking_notifier_chain_register
ian@0 410 * always returns zero.
ian@0 411 */
ian@0 412
ian@0 413 int register_reboot_notifier(struct notifier_block * nb)
ian@0 414 {
ian@0 415 return blocking_notifier_chain_register(&reboot_notifier_list, nb);
ian@0 416 }
ian@0 417
ian@0 418 EXPORT_SYMBOL(register_reboot_notifier);
ian@0 419
ian@0 420 /**
ian@0 421 * unregister_reboot_notifier - Unregister previously registered reboot notifier
ian@0 422 * @nb: Hook to be unregistered
ian@0 423 *
ian@0 424 * Unregisters a previously registered reboot
ian@0 425 * notifier function.
ian@0 426 *
ian@0 427 * Returns zero on success, or %-ENOENT on failure.
ian@0 428 */
ian@0 429
ian@0 430 int unregister_reboot_notifier(struct notifier_block * nb)
ian@0 431 {
ian@0 432 return blocking_notifier_chain_unregister(&reboot_notifier_list, nb);
ian@0 433 }
ian@0 434
ian@0 435 EXPORT_SYMBOL(unregister_reboot_notifier);
ian@0 436
ian@0 437 static int set_one_prio(struct task_struct *p, int niceval, int error)
ian@0 438 {
ian@0 439 int no_nice;
ian@0 440
ian@0 441 if (p->uid != current->euid &&
ian@0 442 p->euid != current->euid && !capable(CAP_SYS_NICE)) {
ian@0 443 error = -EPERM;
ian@0 444 goto out;
ian@0 445 }
ian@0 446 if (niceval < task_nice(p) && !can_nice(p, niceval)) {
ian@0 447 error = -EACCES;
ian@0 448 goto out;
ian@0 449 }
ian@0 450 no_nice = security_task_setnice(p, niceval);
ian@0 451 if (no_nice) {
ian@0 452 error = no_nice;
ian@0 453 goto out;
ian@0 454 }
ian@0 455 if (error == -ESRCH)
ian@0 456 error = 0;
ian@0 457 set_user_nice(p, niceval);
ian@0 458 out:
ian@0 459 return error;
ian@0 460 }
ian@0 461
ian@0 462 asmlinkage long sys_setpriority(int which, int who, int niceval)
ian@0 463 {
ian@0 464 struct task_struct *g, *p;
ian@0 465 struct user_struct *user;
ian@0 466 int error = -EINVAL;
ian@0 467
ian@0 468 if (which > 2 || which < 0)
ian@0 469 goto out;
ian@0 470
ian@0 471 /* normalize: avoid signed division (rounding problems) */
ian@0 472 error = -ESRCH;
ian@0 473 if (niceval < -20)
ian@0 474 niceval = -20;
ian@0 475 if (niceval > 19)
ian@0 476 niceval = 19;
ian@0 477
ian@0 478 read_lock(&tasklist_lock);
ian@0 479 switch (which) {
ian@0 480 case PRIO_PROCESS:
ian@0 481 if (!who)
ian@0 482 who = current->pid;
ian@0 483 p = find_task_by_pid(who);
ian@0 484 if (p)
ian@0 485 error = set_one_prio(p, niceval, error);
ian@0 486 break;
ian@0 487 case PRIO_PGRP:
ian@0 488 if (!who)
ian@0 489 who = process_group(current);
ian@0 490 do_each_task_pid(who, PIDTYPE_PGID, p) {
ian@0 491 error = set_one_prio(p, niceval, error);
ian@0 492 } while_each_task_pid(who, PIDTYPE_PGID, p);
ian@0 493 break;
ian@0 494 case PRIO_USER:
ian@0 495 user = current->user;
ian@0 496 if (!who)
ian@0 497 who = current->uid;
ian@0 498 else
ian@0 499 if ((who != current->uid) && !(user = find_user(who)))
ian@0 500 goto out_unlock; /* No processes for this user */
ian@0 501
ian@0 502 do_each_thread(g, p)
ian@0 503 if (p->uid == who)
ian@0 504 error = set_one_prio(p, niceval, error);
ian@0 505 while_each_thread(g, p);
ian@0 506 if (who != current->uid)
ian@0 507 free_uid(user); /* For find_user() */
ian@0 508 break;
ian@0 509 }
ian@0 510 out_unlock:
ian@0 511 read_unlock(&tasklist_lock);
ian@0 512 out:
ian@0 513 return error;
ian@0 514 }
ian@0 515
ian@0 516 /*
ian@0 517 * Ugh. To avoid negative return values, "getpriority()" will
ian@0 518 * not return the normal nice-value, but a negated value that
ian@0 519 * has been offset by 20 (ie it returns 40..1 instead of -20..19)
ian@0 520 * to stay compatible.
ian@0 521 */
ian@0 522 asmlinkage long sys_getpriority(int which, int who)
ian@0 523 {
ian@0 524 struct task_struct *g, *p;
ian@0 525 struct user_struct *user;
ian@0 526 long niceval, retval = -ESRCH;
ian@0 527
ian@0 528 if (which > 2 || which < 0)
ian@0 529 return -EINVAL;
ian@0 530
ian@0 531 read_lock(&tasklist_lock);
ian@0 532 switch (which) {
ian@0 533 case PRIO_PROCESS:
ian@0 534 if (!who)
ian@0 535 who = current->pid;
ian@0 536 p = find_task_by_pid(who);
ian@0 537 if (p) {
ian@0 538 niceval = 20 - task_nice(p);
ian@0 539 if (niceval > retval)
ian@0 540 retval = niceval;
ian@0 541 }
ian@0 542 break;
ian@0 543 case PRIO_PGRP:
ian@0 544 if (!who)
ian@0 545 who = process_group(current);
ian@0 546 do_each_task_pid(who, PIDTYPE_PGID, p) {
ian@0 547 niceval = 20 - task_nice(p);
ian@0 548 if (niceval > retval)
ian@0 549 retval = niceval;
ian@0 550 } while_each_task_pid(who, PIDTYPE_PGID, p);
ian@0 551 break;
ian@0 552 case PRIO_USER:
ian@0 553 user = current->user;
ian@0 554 if (!who)
ian@0 555 who = current->uid;
ian@0 556 else
ian@0 557 if ((who != current->uid) && !(user = find_user(who)))
ian@0 558 goto out_unlock; /* No processes for this user */
ian@0 559
ian@0 560 do_each_thread(g, p)
ian@0 561 if (p->uid == who) {
ian@0 562 niceval = 20 - task_nice(p);
ian@0 563 if (niceval > retval)
ian@0 564 retval = niceval;
ian@0 565 }
ian@0 566 while_each_thread(g, p);
ian@0 567 if (who != current->uid)
ian@0 568 free_uid(user); /* for find_user() */
ian@0 569 break;
ian@0 570 }
ian@0 571 out_unlock:
ian@0 572 read_unlock(&tasklist_lock);
ian@0 573
ian@0 574 return retval;
ian@0 575 }
ian@0 576
ian@0 577 /**
ian@0 578 * emergency_restart - reboot the system
ian@0 579 *
ian@0 580 * Without shutting down any hardware or taking any locks
ian@0 581 * reboot the system. This is called when we know we are in
ian@0 582 * trouble so this is our best effort to reboot. This is
ian@0 583 * safe to call in interrupt context.
ian@0 584 */
ian@0 585 void emergency_restart(void)
ian@0 586 {
ian@0 587 machine_emergency_restart();
ian@0 588 }
ian@0 589 EXPORT_SYMBOL_GPL(emergency_restart);
ian@0 590
ian@0 591 static void kernel_restart_prepare(char *cmd)
ian@0 592 {
ian@0 593 blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
ian@0 594 system_state = SYSTEM_RESTART;
ian@0 595 device_shutdown();
ian@0 596 }
ian@0 597
ian@0 598 /**
ian@0 599 * kernel_restart - reboot the system
ian@0 600 * @cmd: pointer to buffer containing command to execute for restart
ian@0 601 * or %NULL
ian@0 602 *
ian@0 603 * Shutdown everything and perform a clean reboot.
ian@0 604 * This is not safe to call in interrupt context.
ian@0 605 */
ian@0 606 void kernel_restart(char *cmd)
ian@0 607 {
ian@0 608 kernel_restart_prepare(cmd);
ian@0 609 if (!cmd) {
ian@0 610 printk(KERN_EMERG "Restarting system.\n");
ian@0 611 } else {
ian@0 612 printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd);
ian@0 613 }
ian@0 614 printk(".\n");
ian@0 615 machine_restart(cmd);
ian@0 616 }
ian@0 617 EXPORT_SYMBOL_GPL(kernel_restart);
ian@0 618
ian@0 619 /**
ian@0 620 * kernel_kexec - reboot the system
ian@0 621 *
ian@0 622 * Move into place and start executing a preloaded standalone
ian@0 623 * executable. If nothing was preloaded return an error.
ian@0 624 */
ian@0 625 static void kernel_kexec(void)
ian@0 626 {
ian@0 627 #ifdef CONFIG_KEXEC
ian@0 628 struct kimage *image;
ian@0 629 image = xchg(&kexec_image, NULL);
ian@0 630 if (!image) {
ian@0 631 return;
ian@0 632 }
ian@0 633 kernel_restart_prepare(NULL);
ian@0 634 printk(KERN_EMERG "Starting new kernel\n");
ian@0 635 machine_shutdown();
ian@0 636 machine_kexec(image);
ian@0 637 #endif
ian@0 638 }
ian@0 639
ian@0 640 void kernel_shutdown_prepare(enum system_states state)
ian@0 641 {
ian@0 642 blocking_notifier_call_chain(&reboot_notifier_list,
ian@0 643 (state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL);
ian@0 644 system_state = state;
ian@0 645 device_shutdown();
ian@0 646 }
ian@0 647 /**
ian@0 648 * kernel_halt - halt the system
ian@0 649 *
ian@0 650 * Shutdown everything and perform a clean system halt.
ian@0 651 */
ian@0 652 void kernel_halt(void)
ian@0 653 {
ian@0 654 kernel_shutdown_prepare(SYSTEM_HALT);
ian@0 655 printk(KERN_EMERG "System halted.\n");
ian@0 656 machine_halt();
ian@0 657 }
ian@0 658
ian@0 659 EXPORT_SYMBOL_GPL(kernel_halt);
ian@0 660
ian@0 661 /**
ian@0 662 * kernel_power_off - power_off the system
ian@0 663 *
ian@0 664 * Shutdown everything and perform a clean system power_off.
ian@0 665 */
ian@0 666 void kernel_power_off(void)
ian@0 667 {
ian@0 668 kernel_shutdown_prepare(SYSTEM_POWER_OFF);
ian@0 669 printk(KERN_EMERG "Power down.\n");
ian@0 670 machine_power_off();
ian@0 671 }
ian@0 672 EXPORT_SYMBOL_GPL(kernel_power_off);
ian@0 673 /*
ian@0 674 * Reboot system call: for obvious reasons only root may call it,
ian@0 675 * and even root needs to set up some magic numbers in the registers
ian@0 676 * so that some mistake won't make this reboot the whole machine.
ian@0 677 * You can also set the meaning of the ctrl-alt-del-key here.
ian@0 678 *
ian@0 679 * reboot doesn't sync: do that yourself before calling this.
ian@0 680 */
ian@0 681 asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user * arg)
ian@0 682 {
ian@0 683 char buffer[256];
ian@0 684
ian@0 685 /* We only trust the superuser with rebooting the system. */
ian@0 686 if (!capable(CAP_SYS_BOOT))
ian@0 687 return -EPERM;
ian@0 688
ian@0 689 /* For safety, we require "magic" arguments. */
ian@0 690 if (magic1 != LINUX_REBOOT_MAGIC1 ||
ian@0 691 (magic2 != LINUX_REBOOT_MAGIC2 &&
ian@0 692 magic2 != LINUX_REBOOT_MAGIC2A &&
ian@0 693 magic2 != LINUX_REBOOT_MAGIC2B &&
ian@0 694 magic2 != LINUX_REBOOT_MAGIC2C))
ian@0 695 return -EINVAL;
ian@0 696
ian@0 697 /* Instead of trying to make the power_off code look like
ian@0 698 * halt when pm_power_off is not set do it the easy way.
ian@0 699 */
ian@0 700 if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
ian@0 701 cmd = LINUX_REBOOT_CMD_HALT;
ian@0 702
ian@0 703 lock_kernel();
ian@0 704 switch (cmd) {
ian@0 705 case LINUX_REBOOT_CMD_RESTART:
ian@0 706 kernel_restart(NULL);
ian@0 707 break;
ian@0 708
ian@0 709 case LINUX_REBOOT_CMD_CAD_ON:
ian@0 710 C_A_D = 1;
ian@0 711 break;
ian@0 712
ian@0 713 case LINUX_REBOOT_CMD_CAD_OFF:
ian@0 714 C_A_D = 0;
ian@0 715 break;
ian@0 716
ian@0 717 case LINUX_REBOOT_CMD_HALT:
ian@0 718 kernel_halt();
ian@0 719 unlock_kernel();
ian@0 720 do_exit(0);
ian@0 721 break;
ian@0 722
ian@0 723 case LINUX_REBOOT_CMD_POWER_OFF:
ian@0 724 kernel_power_off();
ian@0 725 unlock_kernel();
ian@0 726 do_exit(0);
ian@0 727 break;
ian@0 728
ian@0 729 case LINUX_REBOOT_CMD_RESTART2:
ian@0 730 if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
ian@0 731 unlock_kernel();
ian@0 732 return -EFAULT;
ian@0 733 }
ian@0 734 buffer[sizeof(buffer) - 1] = '\0';
ian@0 735
ian@0 736 kernel_restart(buffer);
ian@0 737 break;
ian@0 738
ian@0 739 case LINUX_REBOOT_CMD_KEXEC:
ian@0 740 kernel_kexec();
ian@0 741 unlock_kernel();
ian@0 742 return -EINVAL;
ian@0 743
ian@0 744 #ifdef CONFIG_SOFTWARE_SUSPEND
ian@0 745 case LINUX_REBOOT_CMD_SW_SUSPEND:
ian@0 746 {
ian@0 747 int ret = software_suspend();
ian@0 748 unlock_kernel();
ian@0 749 return ret;
ian@0 750 }
ian@0 751 #endif
ian@0 752
ian@0 753 default:
ian@0 754 unlock_kernel();
ian@0 755 return -EINVAL;
ian@0 756 }
ian@0 757 unlock_kernel();
ian@0 758 return 0;
ian@0 759 }
ian@0 760
ian@0 761 static void deferred_cad(void *dummy)
ian@0 762 {
ian@0 763 kernel_restart(NULL);
ian@0 764 }
ian@0 765
ian@0 766 /*
ian@0 767 * This function gets called by ctrl-alt-del - ie the keyboard interrupt.
ian@0 768 * As it's called within an interrupt, it may NOT sync: the only choice
ian@0 769 * is whether to reboot at once, or just ignore the ctrl-alt-del.
ian@0 770 */
ian@0 771 void ctrl_alt_del(void)
ian@0 772 {
ian@0 773 static DECLARE_WORK(cad_work, deferred_cad, NULL);
ian@0 774
ian@0 775 if (C_A_D)
ian@0 776 schedule_work(&cad_work);
ian@0 777 else
ian@0 778 kill_proc(cad_pid, SIGINT, 1);
ian@0 779 }
ian@0 780
ian@0 781
ian@0 782 /*
ian@0 783 * Unprivileged users may change the real gid to the effective gid
ian@0 784 * or vice versa. (BSD-style)
ian@0 785 *
ian@0 786 * If you set the real gid at all, or set the effective gid to a value not
ian@0 787 * equal to the real gid, then the saved gid is set to the new effective gid.
ian@0 788 *
ian@0 789 * This makes it possible for a setgid program to completely drop its
ian@0 790 * privileges, which is often a useful assertion to make when you are doing
ian@0 791 * a security audit over a program.
ian@0 792 *
ian@0 793 * The general idea is that a program which uses just setregid() will be
ian@0 794 * 100% compatible with BSD. A program which uses just setgid() will be
ian@0 795 * 100% compatible with POSIX with saved IDs.
ian@0 796 *
ian@0 797 * SMP: There are not races, the GIDs are checked only by filesystem
ian@0 798 * operations (as far as semantic preservation is concerned).
ian@0 799 */
ian@0 800 asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
ian@0 801 {
ian@0 802 int old_rgid = current->gid;
ian@0 803 int old_egid = current->egid;
ian@0 804 int new_rgid = old_rgid;
ian@0 805 int new_egid = old_egid;
ian@0 806 int retval;
ian@0 807
ian@0 808 retval = security_task_setgid(rgid, egid, (gid_t)-1, LSM_SETID_RE);
ian@0 809 if (retval)
ian@0 810 return retval;
ian@0 811
ian@0 812 if (rgid != (gid_t) -1) {
ian@0 813 if ((old_rgid == rgid) ||
ian@0 814 (current->egid==rgid) ||
ian@0 815 capable(CAP_SETGID))
ian@0 816 new_rgid = rgid;
ian@0 817 else
ian@0 818 return -EPERM;
ian@0 819 }
ian@0 820 if (egid != (gid_t) -1) {
ian@0 821 if ((old_rgid == egid) ||
ian@0 822 (current->egid == egid) ||
ian@0 823 (current->sgid == egid) ||
ian@0 824 capable(CAP_SETGID))
ian@0 825 new_egid = egid;
ian@0 826 else {
ian@0 827 return -EPERM;
ian@0 828 }
ian@0 829 }
ian@0 830 if (new_egid != old_egid)
ian@0 831 {
ian@0 832 current->mm->dumpable = suid_dumpable;
ian@0 833 smp_wmb();
ian@0 834 }
ian@0 835 if (rgid != (gid_t) -1 ||
ian@0 836 (egid != (gid_t) -1 && egid != old_rgid))
ian@0 837 current->sgid = new_egid;
ian@0 838 current->fsgid = new_egid;
ian@0 839 current->egid = new_egid;
ian@0 840 current->gid = new_rgid;
ian@0 841 key_fsgid_changed(current);
ian@0 842 proc_id_connector(current, PROC_EVENT_GID);
ian@0 843 return 0;
ian@0 844 }
ian@0 845
ian@0 846 /*
ian@0 847 * setgid() is implemented like SysV w/ SAVED_IDS
ian@0 848 *
ian@0 849 * SMP: Same implicit races as above.
ian@0 850 */
ian@0 851 asmlinkage long sys_setgid(gid_t gid)
ian@0 852 {
ian@0 853 int old_egid = current->egid;
ian@0 854 int retval;
ian@0 855
ian@0 856 retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_ID);
ian@0 857 if (retval)
ian@0 858 return retval;
ian@0 859
ian@0 860 if (capable(CAP_SETGID))
ian@0 861 {
ian@0 862 if(old_egid != gid)
ian@0 863 {
ian@0 864 current->mm->dumpable = suid_dumpable;
ian@0 865 smp_wmb();
ian@0 866 }
ian@0 867 current->gid = current->egid = current->sgid = current->fsgid = gid;
ian@0 868 }
ian@0 869 else if ((gid == current->gid) || (gid == current->sgid))
ian@0 870 {
ian@0 871 if(old_egid != gid)
ian@0 872 {
ian@0 873 current->mm->dumpable = suid_dumpable;
ian@0 874 smp_wmb();
ian@0 875 }
ian@0 876 current->egid = current->fsgid = gid;
ian@0 877 }
ian@0 878 else
ian@0 879 return -EPERM;
ian@0 880
ian@0 881 key_fsgid_changed(current);
ian@0 882 proc_id_connector(current, PROC_EVENT_GID);
ian@0 883 return 0;
ian@0 884 }
ian@0 885
ian@0 886 static int set_user(uid_t new_ruid, int dumpclear)
ian@0 887 {
ian@0 888 struct user_struct *new_user;
ian@0 889
ian@0 890 new_user = alloc_uid(new_ruid);
ian@0 891 if (!new_user)
ian@0 892 return -EAGAIN;
ian@0 893
ian@0 894 if (atomic_read(&new_user->processes) >=
ian@0 895 current->signal->rlim[RLIMIT_NPROC].rlim_cur &&
ian@0 896 new_user != &root_user) {
ian@0 897 free_uid(new_user);
ian@0 898 return -EAGAIN;
ian@0 899 }
ian@0 900
ian@0 901 switch_uid(new_user);
ian@0 902
ian@0 903 if(dumpclear)
ian@0 904 {
ian@0 905 current->mm->dumpable = suid_dumpable;
ian@0 906 smp_wmb();
ian@0 907 }
ian@0 908 current->uid = new_ruid;
ian@0 909 return 0;
ian@0 910 }
ian@0 911
ian@0 912 /*
ian@0 913 * Unprivileged users may change the real uid to the effective uid
ian@0 914 * or vice versa. (BSD-style)
ian@0 915 *
ian@0 916 * If you set the real uid at all, or set the effective uid to a value not
ian@0 917 * equal to the real uid, then the saved uid is set to the new effective uid.
ian@0 918 *
ian@0 919 * This makes it possible for a setuid program to completely drop its
ian@0 920 * privileges, which is often a useful assertion to make when you are doing
ian@0 921 * a security audit over a program.
ian@0 922 *
ian@0 923 * The general idea is that a program which uses just setreuid() will be
ian@0 924 * 100% compatible with BSD. A program which uses just setuid() will be
ian@0 925 * 100% compatible with POSIX with saved IDs.
ian@0 926 */
ian@0 927 asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
ian@0 928 {
ian@0 929 int old_ruid, old_euid, old_suid, new_ruid, new_euid;
ian@0 930 int retval;
ian@0 931
ian@0 932 retval = security_task_setuid(ruid, euid, (uid_t)-1, LSM_SETID_RE);
ian@0 933 if (retval)
ian@0 934 return retval;
ian@0 935
ian@0 936 new_ruid = old_ruid = current->uid;
ian@0 937 new_euid = old_euid = current->euid;
ian@0 938 old_suid = current->suid;
ian@0 939
ian@0 940 if (ruid != (uid_t) -1) {
ian@0 941 new_ruid = ruid;
ian@0 942 if ((old_ruid != ruid) &&
ian@0 943 (current->euid != ruid) &&
ian@0 944 !capable(CAP_SETUID))
ian@0 945 return -EPERM;
ian@0 946 }
ian@0 947
ian@0 948 if (euid != (uid_t) -1) {
ian@0 949 new_euid = euid;
ian@0 950 if ((old_ruid != euid) &&
ian@0 951 (current->euid != euid) &&
ian@0 952 (current->suid != euid) &&
ian@0 953 !capable(CAP_SETUID))
ian@0 954 return -EPERM;
ian@0 955 }
ian@0 956
ian@0 957 if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
ian@0 958 return -EAGAIN;
ian@0 959
ian@0 960 if (new_euid != old_euid)
ian@0 961 {
ian@0 962 current->mm->dumpable = suid_dumpable;
ian@0 963 smp_wmb();
ian@0 964 }
ian@0 965 current->fsuid = current->euid = new_euid;
ian@0 966 if (ruid != (uid_t) -1 ||
ian@0 967 (euid != (uid_t) -1 && euid != old_ruid))
ian@0 968 current->suid = current->euid;
ian@0 969 current->fsuid = current->euid;
ian@0 970
ian@0 971 key_fsuid_changed(current);
ian@0 972 proc_id_connector(current, PROC_EVENT_UID);
ian@0 973
ian@0 974 return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RE);
ian@0 975 }
ian@0 976
ian@0 977
ian@0 978
ian@0 979 /*
ian@0 980 * setuid() is implemented like SysV with SAVED_IDS
ian@0 981 *
ian@0 982 * Note that SAVED_ID's is deficient in that a setuid root program
ian@0 983 * like sendmail, for example, cannot set its uid to be a normal
ian@0 984 * user and then switch back, because if you're root, setuid() sets
ian@0 985 * the saved uid too. If you don't like this, blame the bright people
ian@0 986 * in the POSIX committee and/or USG. Note that the BSD-style setreuid()
ian@0 987 * will allow a root program to temporarily drop privileges and be able to
ian@0 988 * regain them by swapping the real and effective uid.
ian@0 989 */
ian@0 990 asmlinkage long sys_setuid(uid_t uid)
ian@0 991 {
ian@0 992 int old_euid = current->euid;
ian@0 993 int old_ruid, old_suid, new_ruid, new_suid;
ian@0 994 int retval;
ian@0 995
ian@0 996 retval = security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_ID);
ian@0 997 if (retval)
ian@0 998 return retval;
ian@0 999
ian@0 1000 old_ruid = new_ruid = current->uid;
ian@0 1001 old_suid = current->suid;
ian@0 1002 new_suid = old_suid;
ian@0 1003
ian@0 1004 if (capable(CAP_SETUID)) {
ian@0 1005 if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
ian@0 1006 return -EAGAIN;
ian@0 1007 new_suid = uid;
ian@0 1008 } else if ((uid != current->uid) && (uid != new_suid))
ian@0 1009 return -EPERM;
ian@0 1010
ian@0 1011 if (old_euid != uid)
ian@0 1012 {
ian@0 1013 current->mm->dumpable = suid_dumpable;
ian@0 1014 smp_wmb();
ian@0 1015 }
ian@0 1016 current->fsuid = current->euid = uid;
ian@0 1017 current->suid = new_suid;
ian@0 1018
ian@0 1019 key_fsuid_changed(current);
ian@0 1020 proc_id_connector(current, PROC_EVENT_UID);
ian@0 1021
ian@0 1022 return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_ID);
ian@0 1023 }
ian@0 1024
ian@0 1025
ian@0 1026 /*
ian@0 1027 * This function implements a generic ability to update ruid, euid,
ian@0 1028 * and suid. This allows you to implement the 4.4 compatible seteuid().
ian@0 1029 */
ian@0 1030 asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
ian@0 1031 {
ian@0 1032 int old_ruid = current->uid;
ian@0 1033 int old_euid = current->euid;
ian@0 1034 int old_suid = current->suid;
ian@0 1035 int retval;
ian@0 1036
ian@0 1037 retval = security_task_setuid(ruid, euid, suid, LSM_SETID_RES);
ian@0 1038 if (retval)
ian@0 1039 return retval;
ian@0 1040
ian@0 1041 if (!capable(CAP_SETUID)) {
ian@0 1042 if ((ruid != (uid_t) -1) && (ruid != current->uid) &&
ian@0 1043 (ruid != current->euid) && (ruid != current->suid))
ian@0 1044 return -EPERM;
ian@0 1045 if ((euid != (uid_t) -1) && (euid != current->uid) &&
ian@0 1046 (euid != current->euid) && (euid != current->suid))
ian@0 1047 return -EPERM;
ian@0 1048 if ((suid != (uid_t) -1) && (suid != current->uid) &&
ian@0 1049 (suid != current->euid) && (suid != current->suid))
ian@0 1050 return -EPERM;
ian@0 1051 }
ian@0 1052 if (ruid != (uid_t) -1) {
ian@0 1053 if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
ian@0 1054 return -EAGAIN;
ian@0 1055 }
ian@0 1056 if (euid != (uid_t) -1) {
ian@0 1057 if (euid != current->euid)
ian@0 1058 {
ian@0 1059 current->mm->dumpable = suid_dumpable;
ian@0 1060 smp_wmb();
ian@0 1061 }
ian@0 1062 current->euid = euid;
ian@0 1063 }
ian@0 1064 current->fsuid = current->euid;
ian@0 1065 if (suid != (uid_t) -1)
ian@0 1066 current->suid = suid;
ian@0 1067
ian@0 1068 key_fsuid_changed(current);
ian@0 1069 proc_id_connector(current, PROC_EVENT_UID);
ian@0 1070
ian@0 1071 return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RES);
ian@0 1072 }
ian@0 1073
ian@0 1074 asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid)
ian@0 1075 {
ian@0 1076 int retval;
ian@0 1077
ian@0 1078 if (!(retval = put_user(current->uid, ruid)) &&
ian@0 1079 !(retval = put_user(current->euid, euid)))
ian@0 1080 retval = put_user(current->suid, suid);
ian@0 1081
ian@0 1082 return retval;
ian@0 1083 }
ian@0 1084
ian@0 1085 /*
ian@0 1086 * Same as above, but for rgid, egid, sgid.
ian@0 1087 */
ian@0 1088 asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
ian@0 1089 {
ian@0 1090 int retval;
ian@0 1091
ian@0 1092 retval = security_task_setgid(rgid, egid, sgid, LSM_SETID_RES);
ian@0 1093 if (retval)
ian@0 1094 return retval;
ian@0 1095
ian@0 1096 if (!capable(CAP_SETGID)) {
ian@0 1097 if ((rgid != (gid_t) -1) && (rgid != current->gid) &&
ian@0 1098 (rgid != current->egid) && (rgid != current->sgid))
ian@0 1099 return -EPERM;
ian@0 1100 if ((egid != (gid_t) -1) && (egid != current->gid) &&
ian@0 1101 (egid != current->egid) && (egid != current->sgid))
ian@0 1102 return -EPERM;
ian@0 1103 if ((sgid != (gid_t) -1) && (sgid != current->gid) &&
ian@0 1104 (sgid != current->egid) && (sgid != current->sgid))
ian@0 1105 return -EPERM;
ian@0 1106 }
ian@0 1107 if (egid != (gid_t) -1) {
ian@0 1108 if (egid != current->egid)
ian@0 1109 {
ian@0 1110 current->mm->dumpable = suid_dumpable;
ian@0 1111 smp_wmb();
ian@0 1112 }
ian@0 1113 current->egid = egid;
ian@0 1114 }
ian@0 1115 current->fsgid = current->egid;
ian@0 1116 if (rgid != (gid_t) -1)
ian@0 1117 current->gid = rgid;
ian@0 1118 if (sgid != (gid_t) -1)
ian@0 1119 current->sgid = sgid;
ian@0 1120
ian@0 1121 key_fsgid_changed(current);
ian@0 1122 proc_id_connector(current, PROC_EVENT_GID);
ian@0 1123 return 0;
ian@0 1124 }
ian@0 1125
ian@0 1126 asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid)
ian@0 1127 {
ian@0 1128 int retval;
ian@0 1129
ian@0 1130 if (!(retval = put_user(current->gid, rgid)) &&
ian@0 1131 !(retval = put_user(current->egid, egid)))
ian@0 1132 retval = put_user(current->sgid, sgid);
ian@0 1133
ian@0 1134 return retval;
ian@0 1135 }
ian@0 1136
ian@0 1137
ian@0 1138 /*
ian@0 1139 * "setfsuid()" sets the fsuid - the uid used for filesystem checks. This
ian@0 1140 * is used for "access()" and for the NFS daemon (letting nfsd stay at
ian@0 1141 * whatever uid it wants to). It normally shadows "euid", except when
ian@0 1142 * explicitly set by setfsuid() or for access..
ian@0 1143 */
ian@0 1144 asmlinkage long sys_setfsuid(uid_t uid)
ian@0 1145 {
ian@0 1146 int old_fsuid;
ian@0 1147
ian@0 1148 old_fsuid = current->fsuid;
ian@0 1149 if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
ian@0 1150 return old_fsuid;
ian@0 1151
ian@0 1152 if (uid == current->uid || uid == current->euid ||
ian@0 1153 uid == current->suid || uid == current->fsuid ||
ian@0 1154 capable(CAP_SETUID))
ian@0 1155 {
ian@0 1156 if (uid != old_fsuid)
ian@0 1157 {
ian@0 1158 current->mm->dumpable = suid_dumpable;
ian@0 1159 smp_wmb();
ian@0 1160 }
ian@0 1161 current->fsuid = uid;
ian@0 1162 }
ian@0 1163
ian@0 1164 key_fsuid_changed(current);
ian@0 1165 proc_id_connector(current, PROC_EVENT_UID);
ian@0 1166
ian@0 1167 security_task_post_setuid(old_fsuid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS);
ian@0 1168
ian@0 1169 return old_fsuid;
ian@0 1170 }
ian@0 1171
ian@0 1172 /*
ian@0 1173 * Samma på svenska..
ian@0 1174 */
ian@0 1175 asmlinkage long sys_setfsgid(gid_t gid)
ian@0 1176 {
ian@0 1177 int old_fsgid;
ian@0 1178
ian@0 1179 old_fsgid = current->fsgid;
ian@0 1180 if (security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS))
ian@0 1181 return old_fsgid;
ian@0 1182
ian@0 1183 if (gid == current->gid || gid == current->egid ||
ian@0 1184 gid == current->sgid || gid == current->fsgid ||
ian@0 1185 capable(CAP_SETGID))
ian@0 1186 {
ian@0 1187 if (gid != old_fsgid)
ian@0 1188 {
ian@0 1189 current->mm->dumpable = suid_dumpable;
ian@0 1190 smp_wmb();
ian@0 1191 }
ian@0 1192 current->fsgid = gid;
ian@0 1193 key_fsgid_changed(current);
ian@0 1194 proc_id_connector(current, PROC_EVENT_GID);
ian@0 1195 }
ian@0 1196 return old_fsgid;
ian@0 1197 }
ian@0 1198
ian@0 1199 asmlinkage long sys_times(struct tms __user * tbuf)
ian@0 1200 {
ian@0 1201 /*
ian@0 1202 * In the SMP world we might just be unlucky and have one of
ian@0 1203 * the times increment as we use it. Since the value is an
ian@0 1204 * atomically safe type this is just fine. Conceptually its
ian@0 1205 * as if the syscall took an instant longer to occur.
ian@0 1206 */
ian@0 1207 if (tbuf) {
ian@0 1208 struct tms tmp;
ian@0 1209 struct task_struct *tsk = current;
ian@0 1210 struct task_struct *t;
ian@0 1211 cputime_t utime, stime, cutime, cstime;
ian@0 1212
ian@0 1213 spin_lock_irq(&tsk->sighand->siglock);
ian@0 1214 utime = tsk->signal->utime;
ian@0 1215 stime = tsk->signal->stime;
ian@0 1216 t = tsk;
ian@0 1217 do {
ian@0 1218 utime = cputime_add(utime, t->utime);
ian@0 1219 stime = cputime_add(stime, t->stime);
ian@0 1220 t = next_thread(t);
ian@0 1221 } while (t != tsk);
ian@0 1222
ian@0 1223 cutime = tsk->signal->cutime;
ian@0 1224 cstime = tsk->signal->cstime;
ian@0 1225 spin_unlock_irq(&tsk->sighand->siglock);
ian@0 1226
ian@0 1227 tmp.tms_utime = cputime_to_clock_t(utime);
ian@0 1228 tmp.tms_stime = cputime_to_clock_t(stime);
ian@0 1229 tmp.tms_cutime = cputime_to_clock_t(cutime);
ian@0 1230 tmp.tms_cstime = cputime_to_clock_t(cstime);
ian@0 1231 if (copy_to_user(tbuf, &tmp, sizeof(struct tms)))
ian@0 1232 return -EFAULT;
ian@0 1233 }
ian@0 1234 return (long) jiffies_64_to_clock_t(get_jiffies_64());
ian@0 1235 }
ian@0 1236
ian@0 1237 /*
ian@0 1238 * This needs some heavy checking ...
ian@0 1239 * I just haven't the stomach for it. I also don't fully
ian@0 1240 * understand sessions/pgrp etc. Let somebody who does explain it.
ian@0 1241 *
ian@0 1242 * OK, I think I have the protection semantics right.... this is really
ian@0 1243 * only important on a multi-user system anyway, to make sure one user
ian@0 1244 * can't send a signal to a process owned by another. -TYT, 12/12/91
ian@0 1245 *
ian@0 1246 * Auch. Had to add the 'did_exec' flag to conform completely to POSIX.
ian@0 1247 * LBT 04.03.94
ian@0 1248 */
ian@0 1249
ian@0 1250 asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
ian@0 1251 {
ian@0 1252 struct task_struct *p;
ian@0 1253 struct task_struct *group_leader = current->group_leader;
ian@0 1254 int err = -EINVAL;
ian@0 1255
ian@0 1256 if (!pid)
ian@0 1257 pid = group_leader->pid;
ian@0 1258 if (!pgid)
ian@0 1259 pgid = pid;
ian@0 1260 if (pgid < 0)
ian@0 1261 return -EINVAL;
ian@0 1262
ian@0 1263 /* From this point forward we keep holding onto the tasklist lock
ian@0 1264 * so that our parent does not change from under us. -DaveM
ian@0 1265 */
ian@0 1266 write_lock_irq(&tasklist_lock);
ian@0 1267
ian@0 1268 err = -ESRCH;
ian@0 1269 p = find_task_by_pid(pid);
ian@0 1270 if (!p)
ian@0 1271 goto out;
ian@0 1272
ian@0 1273 err = -EINVAL;
ian@0 1274 if (!thread_group_leader(p))
ian@0 1275 goto out;
ian@0 1276
ian@0 1277 if (p->real_parent == group_leader) {
ian@0 1278 err = -EPERM;
ian@0 1279 if (p->signal->session != group_leader->signal->session)
ian@0 1280 goto out;
ian@0 1281 err = -EACCES;
ian@0 1282 if (p->did_exec)
ian@0 1283 goto out;
ian@0 1284 } else {
ian@0 1285 err = -ESRCH;
ian@0 1286 if (p != group_leader)
ian@0 1287 goto out;
ian@0 1288 }
ian@0 1289
ian@0 1290 err = -EPERM;
ian@0 1291 if (p->signal->leader)
ian@0 1292 goto out;
ian@0 1293
ian@0 1294 if (pgid != pid) {
ian@0 1295 struct task_struct *p;
ian@0 1296
ian@0 1297 do_each_task_pid(pgid, PIDTYPE_PGID, p) {
ian@0 1298 if (p->signal->session == group_leader->signal->session)
ian@0 1299 goto ok_pgid;
ian@0 1300 } while_each_task_pid(pgid, PIDTYPE_PGID, p);
ian@0 1301 goto out;
ian@0 1302 }
ian@0 1303
ian@0 1304 ok_pgid:
ian@0 1305 err = security_task_setpgid(p, pgid);
ian@0 1306 if (err)
ian@0 1307 goto out;
ian@0 1308
ian@0 1309 if (process_group(p) != pgid) {
ian@0 1310 detach_pid(p, PIDTYPE_PGID);
ian@0 1311 p->signal->pgrp = pgid;
ian@0 1312 attach_pid(p, PIDTYPE_PGID, pgid);
ian@0 1313 }
ian@0 1314
ian@0 1315 err = 0;
ian@0 1316 out:
ian@0 1317 /* All paths lead to here, thus we are safe. -DaveM */
ian@0 1318 write_unlock_irq(&tasklist_lock);
ian@0 1319 return err;
ian@0 1320 }
ian@0 1321
ian@0 1322 asmlinkage long sys_getpgid(pid_t pid)
ian@0 1323 {
ian@0 1324 if (!pid) {
ian@0 1325 return process_group(current);
ian@0 1326 } else {
ian@0 1327 int retval;
ian@0 1328 struct task_struct *p;
ian@0 1329
ian@0 1330 read_lock(&tasklist_lock);
ian@0 1331 p = find_task_by_pid(pid);
ian@0 1332
ian@0 1333 retval = -ESRCH;
ian@0 1334 if (p) {
ian@0 1335 retval = security_task_getpgid(p);
ian@0 1336 if (!retval)
ian@0 1337 retval = process_group(p);
ian@0 1338 }
ian@0 1339 read_unlock(&tasklist_lock);
ian@0 1340 return retval;
ian@0 1341 }
ian@0 1342 }
ian@0 1343
ian@0 1344 #ifdef __ARCH_WANT_SYS_GETPGRP
ian@0 1345
ian@0 1346 asmlinkage long sys_getpgrp(void)
ian@0 1347 {
ian@0 1348 /* SMP - assuming writes are word atomic this is fine */
ian@0 1349 return process_group(current);
ian@0 1350 }
ian@0 1351
ian@0 1352 #endif
ian@0 1353
ian@0 1354 asmlinkage long sys_getsid(pid_t pid)
ian@0 1355 {
ian@0 1356 if (!pid) {
ian@0 1357 return current->signal->session;
ian@0 1358 } else {
ian@0 1359 int retval;
ian@0 1360 struct task_struct *p;
ian@0 1361
ian@0 1362 read_lock(&tasklist_lock);
ian@0 1363 p = find_task_by_pid(pid);
ian@0 1364
ian@0 1365 retval = -ESRCH;
ian@0 1366 if(p) {
ian@0 1367 retval = security_task_getsid(p);
ian@0 1368 if (!retval)
ian@0 1369 retval = p->signal->session;
ian@0 1370 }
ian@0 1371 read_unlock(&tasklist_lock);
ian@0 1372 return retval;
ian@0 1373 }
ian@0 1374 }
ian@0 1375
ian@0 1376 asmlinkage long sys_setsid(void)
ian@0 1377 {
ian@0 1378 struct task_struct *group_leader = current->group_leader;
ian@0 1379 pid_t session;
ian@0 1380 int err = -EPERM;
ian@0 1381
ian@0 1382 mutex_lock(&tty_mutex);
ian@0 1383 write_lock_irq(&tasklist_lock);
ian@0 1384
ian@0 1385 /* Fail if I am already a session leader */
ian@0 1386 if (group_leader->signal->leader)
ian@0 1387 goto out;
ian@0 1388
ian@0 1389 session = group_leader->pid;
ian@0 1390 /* Fail if a process group id already exists that equals the
ian@0 1391 * proposed session id.
ian@0 1392 *
ian@0 1393 * Don't check if session id == 1 because kernel threads use this
ian@0 1394 * session id and so the check will always fail and make it so
ian@0 1395 * init cannot successfully call setsid.
ian@0 1396 */
ian@0 1397 if (session > 1 && find_task_by_pid_type(PIDTYPE_PGID, session))
ian@0 1398 goto out;
ian@0 1399
ian@0 1400 group_leader->signal->leader = 1;
ian@0 1401 __set_special_pids(session, session);
ian@0 1402 group_leader->signal->tty = NULL;
ian@0 1403 group_leader->signal->tty_old_pgrp = 0;
ian@0 1404 err = process_group(group_leader);
ian@0 1405 out:
ian@0 1406 write_unlock_irq(&tasklist_lock);
ian@0 1407 mutex_unlock(&tty_mutex);
ian@0 1408 return err;
ian@0 1409 }
ian@0 1410
ian@0 1411 /*
ian@0 1412 * Supplementary group IDs
ian@0 1413 */
ian@0 1414
ian@0 1415 /* init to 2 - one for init_task, one to ensure it is never freed */
ian@0 1416 struct group_info init_groups = { .usage = ATOMIC_INIT(2) };
ian@0 1417
ian@0 1418 struct group_info *groups_alloc(int gidsetsize)
ian@0 1419 {
ian@0 1420 struct group_info *group_info;
ian@0 1421 int nblocks;
ian@0 1422 int i;
ian@0 1423
ian@0 1424 nblocks = (gidsetsize + NGROUPS_PER_BLOCK - 1) / NGROUPS_PER_BLOCK;
ian@0 1425 /* Make sure we always allocate at least one indirect block pointer */
ian@0 1426 nblocks = nblocks ? : 1;
ian@0 1427 group_info = kmalloc(sizeof(*group_info) + nblocks*sizeof(gid_t *), GFP_USER);
ian@0 1428 if (!group_info)
ian@0 1429 return NULL;
ian@0 1430 group_info->ngroups = gidsetsize;
ian@0 1431 group_info->nblocks = nblocks;
ian@0 1432 atomic_set(&group_info->usage, 1);
ian@0 1433
ian@0 1434 if (gidsetsize <= NGROUPS_SMALL) {
ian@0 1435 group_info->blocks[0] = group_info->small_block;
ian@0 1436 } else {
ian@0 1437 for (i = 0; i < nblocks; i++) {
ian@0 1438 gid_t *b;
ian@0 1439 b = (void *)__get_free_page(GFP_USER);
ian@0 1440 if (!b)
ian@0 1441 goto out_undo_partial_alloc;
ian@0 1442 group_info->blocks[i] = b;
ian@0 1443 }
ian@0 1444 }
ian@0 1445 return group_info;
ian@0 1446
ian@0 1447 out_undo_partial_alloc:
ian@0 1448 while (--i >= 0) {
ian@0 1449 free_page((unsigned long)group_info->blocks[i]);
ian@0 1450 }
ian@0 1451 kfree(group_info);
ian@0 1452 return NULL;
ian@0 1453 }
ian@0 1454
ian@0 1455 EXPORT_SYMBOL(groups_alloc);
ian@0 1456
ian@0 1457 void groups_free(struct group_info *group_info)
ian@0 1458 {
ian@0 1459 if (group_info->blocks[0] != group_info->small_block) {
ian@0 1460 int i;
ian@0 1461 for (i = 0; i < group_info->nblocks; i++)
ian@0 1462 free_page((unsigned long)group_info->blocks[i]);
ian@0 1463 }
ian@0 1464 kfree(group_info);
ian@0 1465 }
ian@0 1466
ian@0 1467 EXPORT_SYMBOL(groups_free);
ian@0 1468
ian@0 1469 /* export the group_info to a user-space array */
ian@0 1470 static int groups_to_user(gid_t __user *grouplist,
ian@0 1471 struct group_info *group_info)
ian@0 1472 {
ian@0 1473 int i;
ian@0 1474 int count = group_info->ngroups;
ian@0 1475
ian@0 1476 for (i = 0; i < group_info->nblocks; i++) {
ian@0 1477 int cp_count = min(NGROUPS_PER_BLOCK, count);
ian@0 1478 int off = i * NGROUPS_PER_BLOCK;
ian@0 1479 int len = cp_count * sizeof(*grouplist);
ian@0 1480
ian@0 1481 if (copy_to_user(grouplist+off, group_info->blocks[i], len))
ian@0 1482 return -EFAULT;
ian@0 1483
ian@0 1484 count -= cp_count;
ian@0 1485 }
ian@0 1486 return 0;
ian@0 1487 }
ian@0 1488
ian@0 1489 /* fill a group_info from a user-space array - it must be allocated already */
ian@0 1490 static int groups_from_user(struct group_info *group_info,
ian@0 1491 gid_t __user *grouplist)
ian@0 1492 {
ian@0 1493 int i;
ian@0 1494 int count = group_info->ngroups;
ian@0 1495
ian@0 1496 for (i = 0; i < group_info->nblocks; i++) {
ian@0 1497 int cp_count = min(NGROUPS_PER_BLOCK, count);
ian@0 1498 int off = i * NGROUPS_PER_BLOCK;
ian@0 1499 int len = cp_count * sizeof(*grouplist);
ian@0 1500
ian@0 1501 if (copy_from_user(group_info->blocks[i], grouplist+off, len))
ian@0 1502 return -EFAULT;
ian@0 1503
ian@0 1504 count -= cp_count;
ian@0 1505 }
ian@0 1506 return 0;
ian@0 1507 }
ian@0 1508
ian@0 1509 /* a simple Shell sort */
ian@0 1510 static void groups_sort(struct group_info *group_info)
ian@0 1511 {
ian@0 1512 int base, max, stride;
ian@0 1513 int gidsetsize = group_info->ngroups;
ian@0 1514
ian@0 1515 for (stride = 1; stride < gidsetsize; stride = 3 * stride + 1)
ian@0 1516 ; /* nothing */
ian@0 1517 stride /= 3;
ian@0 1518
ian@0 1519 while (stride) {
ian@0 1520 max = gidsetsize - stride;
ian@0 1521 for (base = 0; base < max; base++) {
ian@0 1522 int left = base;
ian@0 1523 int right = left + stride;
ian@0 1524 gid_t tmp = GROUP_AT(group_info, right);
ian@0 1525
ian@0 1526 while (left >= 0 && GROUP_AT(group_info, left) > tmp) {
ian@0 1527 GROUP_AT(group_info, right) =
ian@0 1528 GROUP_AT(group_info, left);
ian@0 1529 right = left;
ian@0 1530 left -= stride;
ian@0 1531 }
ian@0 1532 GROUP_AT(group_info, right) = tmp;
ian@0 1533 }
ian@0 1534 stride /= 3;
ian@0 1535 }
ian@0 1536 }
ian@0 1537
ian@0 1538 /* a simple bsearch */
ian@0 1539 int groups_search(struct group_info *group_info, gid_t grp)
ian@0 1540 {
ian@0 1541 unsigned int left, right;
ian@0 1542
ian@0 1543 if (!group_info)
ian@0 1544 return 0;
ian@0 1545
ian@0 1546 left = 0;
ian@0 1547 right = group_info->ngroups;
ian@0 1548 while (left < right) {
ian@0 1549 unsigned int mid = (left+right)/2;
ian@0 1550 int cmp = grp - GROUP_AT(group_info, mid);
ian@0 1551 if (cmp > 0)
ian@0 1552 left = mid + 1;
ian@0 1553 else if (cmp < 0)
ian@0 1554 right = mid;
ian@0 1555 else
ian@0 1556 return 1;
ian@0 1557 }
ian@0 1558 return 0;
ian@0 1559 }
ian@0 1560
ian@0 1561 /* validate and set current->group_info */
ian@0 1562 int set_current_groups(struct group_info *group_info)
ian@0 1563 {
ian@0 1564 int retval;
ian@0 1565 struct group_info *old_info;
ian@0 1566
ian@0 1567 retval = security_task_setgroups(group_info);
ian@0 1568 if (retval)
ian@0 1569 return retval;
ian@0 1570
ian@0 1571 groups_sort(group_info);
ian@0 1572 get_group_info(group_info);
ian@0 1573
ian@0 1574 task_lock(current);
ian@0 1575 old_info = current->group_info;
ian@0 1576 current->group_info = group_info;
ian@0 1577 task_unlock(current);
ian@0 1578
ian@0 1579 put_group_info(old_info);
ian@0 1580
ian@0 1581 return 0;
ian@0 1582 }
ian@0 1583
ian@0 1584 EXPORT_SYMBOL(set_current_groups);
ian@0 1585
ian@0 1586 asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist)
ian@0 1587 {
ian@0 1588 int i = 0;
ian@0 1589
ian@0 1590 /*
ian@0 1591 * SMP: Nobody else can change our grouplist. Thus we are
ian@0 1592 * safe.
ian@0 1593 */
ian@0 1594
ian@0 1595 if (gidsetsize < 0)
ian@0 1596 return -EINVAL;
ian@0 1597
ian@0 1598 /* no need to grab task_lock here; it cannot change */
ian@0 1599 i = current->group_info->ngroups;
ian@0 1600 if (gidsetsize) {
ian@0 1601 if (i > gidsetsize) {
ian@0 1602 i = -EINVAL;
ian@0 1603 goto out;
ian@0 1604 }
ian@0 1605 if (groups_to_user(grouplist, current->group_info)) {
ian@0 1606 i = -EFAULT;
ian@0 1607 goto out;
ian@0 1608 }
ian@0 1609 }
ian@0 1610 out:
ian@0 1611 return i;
ian@0 1612 }
ian@0 1613
ian@0 1614 /*
ian@0 1615 * SMP: Our groups are copy-on-write. We can set them safely
ian@0 1616 * without another task interfering.
ian@0 1617 */
ian@0 1618
ian@0 1619 asmlinkage long sys_setgroups(int gidsetsize, gid_t __user *grouplist)
ian@0 1620 {
ian@0 1621 struct group_info *group_info;
ian@0 1622 int retval;
ian@0 1623
ian@0 1624 if (!capable(CAP_SETGID))
ian@0 1625 return -EPERM;
ian@0 1626 if ((unsigned)gidsetsize > NGROUPS_MAX)
ian@0 1627 return -EINVAL;
ian@0 1628
ian@0 1629 group_info = groups_alloc(gidsetsize);
ian@0 1630 if (!group_info)
ian@0 1631 return -ENOMEM;
ian@0 1632 retval = groups_from_user(group_info, grouplist);
ian@0 1633 if (retval) {
ian@0 1634 put_group_info(group_info);
ian@0 1635 return retval;
ian@0 1636 }
ian@0 1637
ian@0 1638 retval = set_current_groups(group_info);
ian@0 1639 put_group_info(group_info);
ian@0 1640
ian@0 1641 return retval;
ian@0 1642 }
ian@0 1643
ian@0 1644 /*
ian@0 1645 * Check whether we're fsgid/egid or in the supplemental group..
ian@0 1646 */
ian@0 1647 int in_group_p(gid_t grp)
ian@0 1648 {
ian@0 1649 int retval = 1;
ian@0 1650 if (grp != current->fsgid) {
ian@0 1651 retval = groups_search(current->group_info, grp);
ian@0 1652 }
ian@0 1653 return retval;
ian@0 1654 }
ian@0 1655
ian@0 1656 EXPORT_SYMBOL(in_group_p);
ian@0 1657
ian@0 1658 int in_egroup_p(gid_t grp)
ian@0 1659 {
ian@0 1660 int retval = 1;
ian@0 1661 if (grp != current->egid) {
ian@0 1662 retval = groups_search(current->group_info, grp);
ian@0 1663 }
ian@0 1664 return retval;
ian@0 1665 }
ian@0 1666
ian@0 1667 EXPORT_SYMBOL(in_egroup_p);
ian@0 1668
ian@0 1669 DECLARE_RWSEM(uts_sem);
ian@0 1670
ian@0 1671 EXPORT_SYMBOL(uts_sem);
ian@0 1672
ian@0 1673 asmlinkage long sys_newuname(struct new_utsname __user * name)
ian@0 1674 {
ian@0 1675 int errno = 0;
ian@0 1676
ian@0 1677 down_read(&uts_sem);
ian@0 1678 if (copy_to_user(name,&system_utsname,sizeof *name))
ian@0 1679 errno = -EFAULT;
ian@0 1680 up_read(&uts_sem);
ian@0 1681 return errno;
ian@0 1682 }
ian@0 1683
ian@0 1684 asmlinkage long sys_sethostname(char __user *name, int len)
ian@0 1685 {
ian@0 1686 int errno;
ian@0 1687 char tmp[__NEW_UTS_LEN];
ian@0 1688
ian@0 1689 if (!capable(CAP_SYS_ADMIN))
ian@0 1690 return -EPERM;
ian@0 1691 if (len < 0 || len > __NEW_UTS_LEN)
ian@0 1692 return -EINVAL;
ian@0 1693 down_write(&uts_sem);
ian@0 1694 errno = -EFAULT;
ian@0 1695 if (!copy_from_user(tmp, name, len)) {
ian@0 1696 memcpy(system_utsname.nodename, tmp, len);
ian@0 1697 system_utsname.nodename[len] = 0;
ian@0 1698 errno = 0;
ian@0 1699 }
ian@0 1700 up_write(&uts_sem);
ian@0 1701 return errno;
ian@0 1702 }
ian@0 1703
ian@0 1704 #ifdef __ARCH_WANT_SYS_GETHOSTNAME
ian@0 1705
ian@0 1706 asmlinkage long sys_gethostname(char __user *name, int len)
ian@0 1707 {
ian@0 1708 int i, errno;
ian@0 1709
ian@0 1710 if (len < 0)
ian@0 1711 return -EINVAL;
ian@0 1712 down_read(&uts_sem);
ian@0 1713 i = 1 + strlen(system_utsname.nodename);
ian@0 1714 if (i > len)
ian@0 1715 i = len;
ian@0 1716 errno = 0;
ian@0 1717 if (copy_to_user(name, system_utsname.nodename, i))
ian@0 1718 errno = -EFAULT;
ian@0 1719 up_read(&uts_sem);
ian@0 1720 return errno;
ian@0 1721 }
ian@0 1722
ian@0 1723 #endif
ian@0 1724
ian@0 1725 /*
ian@0 1726 * Only setdomainname; getdomainname can be implemented by calling
ian@0 1727 * uname()
ian@0 1728 */
ian@0 1729 asmlinkage long sys_setdomainname(char __user *name, int len)
ian@0 1730 {
ian@0 1731 int errno;
ian@0 1732 char tmp[__NEW_UTS_LEN];
ian@0 1733
ian@0 1734 if (!capable(CAP_SYS_ADMIN))
ian@0 1735 return -EPERM;
ian@0 1736 if (len < 0 || len > __NEW_UTS_LEN)
ian@0 1737 return -EINVAL;
ian@0 1738
ian@0 1739 down_write(&uts_sem);
ian@0 1740 errno = -EFAULT;
ian@0 1741 if (!copy_from_user(tmp, name, len)) {
ian@0 1742 memcpy(system_utsname.domainname, tmp, len);
ian@0 1743 system_utsname.domainname[len] = 0;
ian@0 1744 errno = 0;
ian@0 1745 }
ian@0 1746 up_write(&uts_sem);
ian@0 1747 return errno;
ian@0 1748 }
ian@0 1749
ian@0 1750 asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit __user *rlim)
ian@0 1751 {
ian@0 1752 if (resource >= RLIM_NLIMITS)
ian@0 1753 return -EINVAL;
ian@0 1754 else {
ian@0 1755 struct rlimit value;
ian@0 1756 task_lock(current->group_leader);
ian@0 1757 value = current->signal->rlim[resource];
ian@0 1758 task_unlock(current->group_leader);
ian@0 1759 return copy_to_user(rlim, &value, sizeof(*rlim)) ? -EFAULT : 0;
ian@0 1760 }
ian@0 1761 }
ian@0 1762
ian@0 1763 #ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT
ian@0 1764
ian@0 1765 /*
ian@0 1766 * Back compatibility for getrlimit. Needed for some apps.
ian@0 1767 */
ian@0 1768
ian@0 1769 asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim)
ian@0 1770 {
ian@0 1771 struct rlimit x;
ian@0 1772 if (resource >= RLIM_NLIMITS)
ian@0 1773 return -EINVAL;
ian@0 1774
ian@0 1775 task_lock(current->group_leader);
ian@0 1776 x = current->signal->rlim[resource];
ian@0 1777 task_unlock(current->group_leader);
ian@0 1778 if(x.rlim_cur > 0x7FFFFFFF)
ian@0 1779 x.rlim_cur = 0x7FFFFFFF;
ian@0 1780 if(x.rlim_max > 0x7FFFFFFF)
ian@0 1781 x.rlim_max = 0x7FFFFFFF;
ian@0 1782 return copy_to_user(rlim, &x, sizeof(x))?-EFAULT:0;
ian@0 1783 }
ian@0 1784
ian@0 1785 #endif
ian@0 1786
ian@0 1787 asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
ian@0 1788 {
ian@0 1789 struct rlimit new_rlim, *old_rlim;
ian@0 1790 unsigned long it_prof_secs;
ian@0 1791 int retval;
ian@0 1792
ian@0 1793 if (resource >= RLIM_NLIMITS)
ian@0 1794 return -EINVAL;
ian@0 1795 if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
ian@0 1796 return -EFAULT;
ian@0 1797 if (new_rlim.rlim_cur > new_rlim.rlim_max)
ian@0 1798 return -EINVAL;
ian@0 1799 old_rlim = current->signal->rlim + resource;
ian@0 1800 if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
ian@0 1801 !capable(CAP_SYS_RESOURCE))
ian@0 1802 return -EPERM;
ian@0 1803 if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN)
ian@0 1804 return -EPERM;
ian@0 1805
ian@0 1806 retval = security_task_setrlimit(resource, &new_rlim);
ian@0 1807 if (retval)
ian@0 1808 return retval;
ian@0 1809
ian@0 1810 task_lock(current->group_leader);
ian@0 1811 *old_rlim = new_rlim;
ian@0 1812 task_unlock(current->group_leader);
ian@0 1813
ian@0 1814 if (resource != RLIMIT_CPU)
ian@0 1815 goto out;
ian@0 1816
ian@0 1817 /*
ian@0 1818 * RLIMIT_CPU handling. Note that the kernel fails to return an error
ian@0 1819 * code if it rejected the user's attempt to set RLIMIT_CPU. This is a
ian@0 1820 * very long-standing error, and fixing it now risks breakage of
ian@0 1821 * applications, so we live with it
ian@0 1822 */
ian@0 1823 if (new_rlim.rlim_cur == RLIM_INFINITY)
ian@0 1824 goto out;
ian@0 1825
ian@0 1826 it_prof_secs = cputime_to_secs(current->signal->it_prof_expires);
ian@0 1827 if (it_prof_secs == 0 || new_rlim.rlim_cur <= it_prof_secs) {
ian@0 1828 unsigned long rlim_cur = new_rlim.rlim_cur;
ian@0 1829 cputime_t cputime;
ian@0 1830
ian@0 1831 if (rlim_cur == 0) {
ian@0 1832 /*
ian@0 1833 * The caller is asking for an immediate RLIMIT_CPU
ian@0 1834 * expiry. But we use the zero value to mean "it was
ian@0 1835 * never set". So let's cheat and make it one second
ian@0 1836 * instead
ian@0 1837 */
ian@0 1838 rlim_cur = 1;
ian@0 1839 }
ian@0 1840 cputime = secs_to_cputime(rlim_cur);
ian@0 1841 read_lock(&tasklist_lock);
ian@0 1842 spin_lock_irq(&current->sighand->siglock);
ian@0 1843 set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL);
ian@0 1844 spin_unlock_irq(&current->sighand->siglock);
ian@0 1845 read_unlock(&tasklist_lock);
ian@0 1846 }
ian@0 1847 out:
ian@0 1848 return 0;
ian@0 1849 }
ian@0 1850
ian@0 1851 /*
ian@0 1852 * It would make sense to put struct rusage in the task_struct,
ian@0 1853 * except that would make the task_struct be *really big*. After
ian@0 1854 * task_struct gets moved into malloc'ed memory, it would
ian@0 1855 * make sense to do this. It will make moving the rest of the information
ian@0 1856 * a lot simpler! (Which we're not doing right now because we're not
ian@0 1857 * measuring them yet).
ian@0 1858 *
ian@0 1859 * When sampling multiple threads for RUSAGE_SELF, under SMP we might have
ian@0 1860 * races with threads incrementing their own counters. But since word
ian@0 1861 * reads are atomic, we either get new values or old values and we don't
ian@0 1862 * care which for the sums. We always take the siglock to protect reading
ian@0 1863 * the c* fields from p->signal from races with exit.c updating those
ian@0 1864 * fields when reaping, so a sample either gets all the additions of a
ian@0 1865 * given child after it's reaped, or none so this sample is before reaping.
ian@0 1866 *
ian@0 1867 * Locking:
ian@0 1868 * We need to take the siglock for CHILDEREN, SELF and BOTH
ian@0 1869 * for the cases current multithreaded, non-current single threaded
ian@0 1870 * non-current multithreaded. Thread traversal is now safe with
ian@0 1871 * the siglock held.
ian@0 1872 * Strictly speaking, we donot need to take the siglock if we are current and
ian@0 1873 * single threaded, as no one else can take our signal_struct away, no one
ian@0 1874 * else can reap the children to update signal->c* counters, and no one else
ian@0 1875 * can race with the signal-> fields. If we do not take any lock, the
ian@0 1876 * signal-> fields could be read out of order while another thread was just
ian@0 1877 * exiting. So we should place a read memory barrier when we avoid the lock.
ian@0 1878 * On the writer side, write memory barrier is implied in __exit_signal
ian@0 1879 * as __exit_signal releases the siglock spinlock after updating the signal->
ian@0 1880 * fields. But we don't do this yet to keep things simple.
ian@0 1881 *
ian@0 1882 */
ian@0 1883
ian@0 1884 static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
ian@0 1885 {
ian@0 1886 struct task_struct *t;
ian@0 1887 unsigned long flags;
ian@0 1888 cputime_t utime, stime;
ian@0 1889
ian@0 1890 memset((char *) r, 0, sizeof *r);
ian@0 1891 utime = stime = cputime_zero;
ian@0 1892
ian@0 1893 rcu_read_lock();
ian@0 1894 if (!lock_task_sighand(p, &flags)) {
ian@0 1895 rcu_read_unlock();
ian@0 1896 return;
ian@0 1897 }
ian@0 1898
ian@0 1899 switch (who) {
ian@0 1900 case RUSAGE_BOTH:
ian@0 1901 case RUSAGE_CHILDREN:
ian@0 1902 utime = p->signal->cutime;
ian@0 1903 stime = p->signal->cstime;
ian@0 1904 r->ru_nvcsw = p->signal->cnvcsw;
ian@0 1905 r->ru_nivcsw = p->signal->cnivcsw;
ian@0 1906 r->ru_minflt = p->signal->cmin_flt;
ian@0 1907 r->ru_majflt = p->signal->cmaj_flt;
ian@0 1908
ian@0 1909 if (who == RUSAGE_CHILDREN)
ian@0 1910 break;
ian@0 1911
ian@0 1912 case RUSAGE_SELF:
ian@0 1913 utime = cputime_add(utime, p->signal->utime);
ian@0 1914 stime = cputime_add(stime, p->signal->stime);
ian@0 1915 r->ru_nvcsw += p->signal->nvcsw;
ian@0 1916 r->ru_nivcsw += p->signal->nivcsw;
ian@0 1917 r->ru_minflt += p->signal->min_flt;
ian@0 1918 r->ru_majflt += p->signal->maj_flt;
ian@0 1919 t = p;
ian@0 1920 do {
ian@0 1921 utime = cputime_add(utime, t->utime);
ian@0 1922 stime = cputime_add(stime, t->stime);
ian@0 1923 r->ru_nvcsw += t->nvcsw;
ian@0 1924 r->ru_nivcsw += t->nivcsw;
ian@0 1925 r->ru_minflt += t->min_flt;
ian@0 1926 r->ru_majflt += t->maj_flt;
ian@0 1927 t = next_thread(t);
ian@0 1928 } while (t != p);
ian@0 1929 break;
ian@0 1930
ian@0 1931 default:
ian@0 1932 BUG();
ian@0 1933 }
ian@0 1934
ian@0 1935 unlock_task_sighand(p, &flags);
ian@0 1936 rcu_read_unlock();
ian@0 1937
ian@0 1938 cputime_to_timeval(utime, &r->ru_utime);
ian@0 1939 cputime_to_timeval(stime, &r->ru_stime);
ian@0 1940 }
ian@0 1941
ian@0 1942 int getrusage(struct task_struct *p, int who, struct rusage __user *ru)
ian@0 1943 {
ian@0 1944 struct rusage r;
ian@0 1945 k_getrusage(p, who, &r);
ian@0 1946 return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
ian@0 1947 }
ian@0 1948
ian@0 1949 asmlinkage long sys_getrusage(int who, struct rusage __user *ru)
ian@0 1950 {
ian@0 1951 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
ian@0 1952 return -EINVAL;
ian@0 1953 return getrusage(current, who, ru);
ian@0 1954 }
ian@0 1955
ian@0 1956 asmlinkage long sys_umask(int mask)
ian@0 1957 {
ian@0 1958 mask = xchg(&current->fs->umask, mask & S_IRWXUGO);
ian@0 1959 return mask;
ian@0 1960 }
ian@0 1961
ian@0 1962 asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
ian@0 1963 unsigned long arg4, unsigned long arg5)
ian@0 1964 {
ian@0 1965 long error;
ian@0 1966
ian@0 1967 error = security_task_prctl(option, arg2, arg3, arg4, arg5);
ian@0 1968 if (error)
ian@0 1969 return error;
ian@0 1970
ian@0 1971 switch (option) {
ian@0 1972 case PR_SET_PDEATHSIG:
ian@0 1973 if (!valid_signal(arg2)) {
ian@0 1974 error = -EINVAL;
ian@0 1975 break;
ian@0 1976 }
ian@0 1977 current->pdeath_signal = arg2;
ian@0 1978 break;
ian@0 1979 case PR_GET_PDEATHSIG:
ian@0 1980 error = put_user(current->pdeath_signal, (int __user *)arg2);
ian@0 1981 break;
ian@0 1982 case PR_GET_DUMPABLE:
ian@0 1983 error = current->mm->dumpable;
ian@0 1984 break;
ian@0 1985 case PR_SET_DUMPABLE:
ian@0 1986 if (arg2 < 0 || arg2 > 1) {
ian@0 1987 error = -EINVAL;
ian@0 1988 break;
ian@0 1989 }
ian@0 1990 current->mm->dumpable = arg2;
ian@0 1991 break;
ian@0 1992
ian@0 1993 case PR_SET_UNALIGN:
ian@0 1994 error = SET_UNALIGN_CTL(current, arg2);
ian@0 1995 break;
ian@0 1996 case PR_GET_UNALIGN:
ian@0 1997 error = GET_UNALIGN_CTL(current, arg2);
ian@0 1998 break;
ian@0 1999 case PR_SET_FPEMU:
ian@0 2000 error = SET_FPEMU_CTL(current, arg2);
ian@0 2001 break;
ian@0 2002 case PR_GET_FPEMU:
ian@0 2003 error = GET_FPEMU_CTL(current, arg2);
ian@0 2004 break;
ian@0 2005 case PR_SET_FPEXC:
ian@0 2006 error = SET_FPEXC_CTL(current, arg2);
ian@0 2007 break;
ian@0 2008 case PR_GET_FPEXC:
ian@0 2009 error = GET_FPEXC_CTL(current, arg2);
ian@0 2010 break;
ian@0 2011 case PR_GET_TIMING:
ian@0 2012 error = PR_TIMING_STATISTICAL;
ian@0 2013 break;
ian@0 2014 case PR_SET_TIMING:
ian@0 2015 if (arg2 == PR_TIMING_STATISTICAL)
ian@0 2016 error = 0;
ian@0 2017 else
ian@0 2018 error = -EINVAL;
ian@0 2019 break;
ian@0 2020
ian@0 2021 case PR_GET_KEEPCAPS:
ian@0 2022 if (current->keep_capabilities)
ian@0 2023 error = 1;
ian@0 2024 break;
ian@0 2025 case PR_SET_KEEPCAPS:
ian@0 2026 if (arg2 != 0 && arg2 != 1) {
ian@0 2027 error = -EINVAL;
ian@0 2028 break;
ian@0 2029 }
ian@0 2030 current->keep_capabilities = arg2;
ian@0 2031 break;
ian@0 2032 case PR_SET_NAME: {
ian@0 2033 struct task_struct *me = current;
ian@0 2034 unsigned char ncomm[sizeof(me->comm)];
ian@0 2035
ian@0 2036 ncomm[sizeof(me->comm)-1] = 0;
ian@0 2037 if (strncpy_from_user(ncomm, (char __user *)arg2,
ian@0 2038 sizeof(me->comm)-1) < 0)
ian@0 2039 return -EFAULT;
ian@0 2040 set_task_comm(me, ncomm);
ian@0 2041 return 0;
ian@0 2042 }
ian@0 2043 case PR_GET_NAME: {
ian@0 2044 struct task_struct *me = current;
ian@0 2045 unsigned char tcomm[sizeof(me->comm)];
ian@0 2046
ian@0 2047 get_task_comm(tcomm, me);
ian@0 2048 if (copy_to_user((char __user *)arg2, tcomm, sizeof(tcomm)))
ian@0 2049 return -EFAULT;
ian@0 2050 return 0;
ian@0 2051 }
ian@0 2052 case PR_GET_ENDIAN:
ian@0 2053 error = GET_ENDIAN(current, arg2);
ian@0 2054 break;
ian@0 2055 case PR_SET_ENDIAN:
ian@0 2056 error = SET_ENDIAN(current, arg2);
ian@0 2057 break;
ian@0 2058
ian@0 2059 default:
ian@0 2060 error = -EINVAL;
ian@0 2061 break;
ian@0 2062 }
ian@0 2063 return error;
ian@0 2064 }