diff options
Diffstat (limited to 'man2/modify_ldt.2')
-rw-r--r-- | man2/modify_ldt.2 | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/man2/modify_ldt.2 b/man2/modify_ldt.2 new file mode 100644 index 0000000..0364289 --- /dev/null +++ b/man2/modify_ldt.2 @@ -0,0 +1,196 @@ +.\" Copyright (c) 1995 Michael Chastain (mec@duracef.shout.net), 22 July 1995. +.\" Copyright (c) 2015 Andrew Lutomirski +.\" +.\" SPDX-License-Identifier: GPL-2.0-or-later +.\" +.TH modify_ldt 2 2023-03-30 "Linux man-pages 6.05.01" +.SH NAME +modify_ldt \- get or set a per-process LDT entry +.SH LIBRARY +Standard C library +.RI ( libc ", " \-lc ) +.SH SYNOPSIS +.nf +.BR "#include <asm/ldt.h>" " /* Definition of " "struct user_desc" " */" +.BR "#include <sys/syscall.h>" " /* Definition of " SYS_* " constants */" +.B #include <unistd.h> +.PP +.BI "int syscall(SYS_modify_ldt, int " func ", void " ptr [. bytecount ], +.BI " unsigned long " bytecount ); +.fi +.PP +.IR Note : +glibc provides no wrapper for +.BR modify_ldt (), +necessitating the use of +.BR syscall (2). +.SH DESCRIPTION +.BR modify_ldt () +reads or writes the local descriptor table (LDT) for a process. +The LDT +is an array of segment descriptors that can be referenced by user code. +Linux allows processes to configure a per-process (actually per-mm) LDT. +For more information about the LDT, see the Intel Software Developer's +Manual or the AMD Architecture Programming Manual. +.PP +When +.I func +is 0, +.BR modify_ldt () +reads the LDT into the memory pointed to by +.IR ptr . +The number of bytes read is the smaller of +.I bytecount +and the actual size of the LDT, although the kernel may act as though +the LDT is padded with additional trailing zero bytes. +On success, +.BR modify_ldt () +will return the number of bytes read. +.PP +When +.I func +is 1 or 0x11, +.BR modify_ldt () +modifies the LDT entry indicated by +.IR ptr\->entry_number . +.I ptr +points to a +.I user_desc +structure +and +.I bytecount +must equal the size of this structure. +.PP +The +.I user_desc +structure is defined in \fI<asm/ldt.h>\fP as: +.PP +.in +4n +.EX +struct user_desc { + unsigned int entry_number; + unsigned int base_addr; + unsigned int limit; + unsigned int seg_32bit:1; + unsigned int contents:2; + unsigned int read_exec_only:1; + unsigned int limit_in_pages:1; + unsigned int seg_not_present:1; + unsigned int useable:1; +}; +.EE +.in +.PP +In Linux 2.4 and earlier, this structure was named +.IR modify_ldt_ldt_s . +.PP +The +.I contents +field is the segment type (data, expand-down data, non-conforming code, or +conforming code). +The other fields match their descriptions in the CPU manual, although +.BR modify_ldt () +cannot set the hardware-defined "accessed" bit described in the CPU manual. +.PP +A +.I user_desc +is considered "empty" if +.I read_exec_only +and +.I seg_not_present +are set to 1 and all of the other fields are 0. +An LDT entry can be cleared by setting it to an "empty" +.I user_desc +or, if +.I func +is 1, by setting both +.I base +and +.I limit +to 0. +.PP +A conforming code segment (i.e., one with +.IR contents==3 ) +will be rejected if +.I +func +is 1 or if +.I seg_not_present +is 0. +.PP +When +.I func +is 2, +.BR modify_ldt () +will read zeros. +This appears to be a leftover from Linux 2.4. +.SH RETURN VALUE +On success, +.BR modify_ldt () +returns either the actual number of bytes read (for reading) +or 0 (for writing). +On failure, +.BR modify_ldt () +returns \-1 and sets +.I errno +to indicate the error. +.SH ERRORS +.TP +.B EFAULT +.I ptr +points outside the address space. +.TP +.B EINVAL +.I ptr +is 0, +or +.I func +is 1 and +.I bytecount +is not equal to the size of the structure +.IR user_desc , +or +.I func +is 1 or 0x11 and the new LDT entry has invalid values. +.TP +.B ENOSYS +.I func +is neither 0, 1, 2, nor 0x11. +.SH STANDARDS +Linux. +.SH NOTES +.BR modify_ldt () +should not be used for thread-local storage, as it slows down context +switches and only supports a limited number of threads. +Threading libraries should use +.BR set_thread_area (2) +or +.BR arch_prctl (2) +instead, except on extremely old kernels that do not support those system +calls. +.PP +The normal use for +.BR modify_ldt () +is to run legacy 16-bit or segmented 32-bit code. +Not all kernels allow 16-bit segments to be installed, however. +.PP +Even on 64-bit kernels, +.BR modify_ldt () +cannot be used to create a long mode (i.e., 64-bit) code segment. +The undocumented field "lm" in +.I user_desc +is not useful, and, despite its name, +does not result in a long mode segment. +.SH BUGS +On 64-bit kernels before Linux 3.19, +.\" commit e30ab185c490e9a9381385529e0fd32f0a399495 +setting the "lm" bit in +.I user_desc +prevents the descriptor from being considered empty. +Keep in mind that the +"lm" bit does not exist in the 32-bit headers, but these buggy kernels +will still notice the bit even when set in a 32-bit process. +.SH SEE ALSO +.BR arch_prctl (2), +.BR set_thread_area (2), +.BR vm86 (2) |